OLD | NEW |
(Empty) | |
| 1 //===- ExpandConstantExpr.cpp - Convert ConstantExprs to Instructions------===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 //===----------------------------------------------------------------------===// |
| 9 // |
| 10 // This pass expands out ConstantExprs into Instructions. |
| 11 // |
| 12 // Note that this only converts ConstantExprs that are referenced by |
| 13 // Instructions. It does not convert ConstantExprs that are used as |
| 14 // initializers for global variables. |
| 15 // |
| 16 // This simplifies the language so that the PNaCl translator does not |
| 17 // need to handle ConstantExprs as part of a stable wire format for |
| 18 // PNaCl. |
| 19 // |
| 20 //===----------------------------------------------------------------------===// |
| 21 |
| 22 #include <map> |
| 23 |
| 24 #include "llvm/IR/Function.h" |
| 25 #include "llvm/IR/Instructions.h" |
| 26 #include "llvm/Pass.h" |
| 27 #include "llvm/Transforms/NaCl.h" |
| 28 |
| 29 using namespace llvm; |
| 30 |
| 31 static bool expandInstruction(Instruction *Inst); |
| 32 |
| 33 namespace { |
| 34 // This is a FunctionPass because our handling of PHI nodes means |
| 35 // that our modifications may cross BasicBlocks. |
| 36 struct ExpandConstantExpr : public FunctionPass { |
| 37 static char ID; // Pass identification, replacement for typeid |
| 38 ExpandConstantExpr() : FunctionPass(ID) { |
| 39 initializeExpandConstantExprPass(*PassRegistry::getPassRegistry()); |
| 40 } |
| 41 |
| 42 virtual bool runOnFunction(Function &Func); |
| 43 }; |
| 44 } |
| 45 |
| 46 char ExpandConstantExpr::ID = 0; |
| 47 INITIALIZE_PASS(ExpandConstantExpr, "expand-constant-expr", |
| 48 "Expand out ConstantExprs into Instructions", |
| 49 false, false) |
| 50 |
| 51 static Value *expandConstantExpr(Instruction *InsertPt, ConstantExpr *Expr) { |
| 52 Instruction *NewInst = Expr->getAsInstruction(); |
| 53 NewInst->insertBefore(InsertPt); |
| 54 NewInst->setName("expanded"); |
| 55 expandInstruction(NewInst); |
| 56 return NewInst; |
| 57 } |
| 58 |
| 59 static bool expandInstruction(Instruction *Inst) { |
| 60 // A landingpad can only accept ConstantExprs, so it should remain |
| 61 // unmodified. |
| 62 if (isa<LandingPadInst>(Inst)) |
| 63 return false; |
| 64 |
| 65 bool Modified = false; |
| 66 if (PHINode *PN = dyn_cast<PHINode>(Inst)) { |
| 67 // PHI nodes require special treatment. A incoming block may be |
| 68 // listed twice, but its incoming values must match so they must |
| 69 // be converted only once. |
| 70 std::map<BasicBlock*,Value*> Converted; |
| 71 for (unsigned OpNum = 0; OpNum < Inst->getNumOperands(); OpNum++) { |
| 72 if (ConstantExpr *Expr = |
| 73 dyn_cast<ConstantExpr>(Inst->getOperand(OpNum))) { |
| 74 Modified = true; |
| 75 BasicBlock *Incoming = PN->getIncomingBlock(OpNum); |
| 76 if (Converted.count(Incoming) == 0) { |
| 77 Converted[Incoming] = expandConstantExpr(Incoming->getTerminator(), |
| 78 Expr); |
| 79 } |
| 80 Inst->setOperand(OpNum, Converted[Incoming]); |
| 81 } |
| 82 } |
| 83 return Modified; |
| 84 } |
| 85 |
| 86 for (unsigned OpNum = 0; OpNum < Inst->getNumOperands(); OpNum++) { |
| 87 if (ConstantExpr *Expr = |
| 88 dyn_cast<ConstantExpr>(Inst->getOperand(OpNum))) { |
| 89 Modified = true; |
| 90 Inst->setOperand(OpNum, expandConstantExpr(Inst, Expr)); |
| 91 } |
| 92 } |
| 93 return Modified; |
| 94 } |
| 95 |
| 96 bool ExpandConstantExpr::runOnFunction(Function &Func) { |
| 97 bool Modified = false; |
| 98 for (llvm::Function::iterator BB = Func.begin(), E = Func.end(); |
| 99 BB != E; |
| 100 ++BB) { |
| 101 for (BasicBlock::InstListType::iterator Inst = BB->begin(), E = BB->end(); |
| 102 Inst != E; |
| 103 ++Inst) { |
| 104 Modified |= expandInstruction(Inst); |
| 105 } |
| 106 } |
| 107 return Modified; |
| 108 } |
| 109 |
| 110 FunctionPass *llvm::createExpandConstantExprPass() { |
| 111 return new ExpandConstantExpr(); |
| 112 } |
OLD | NEW |