diff options
author | Eli Bendersky <eliben@chromium.org> | 2013-03-20 15:05:17 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@chromium.org> | 2013-03-20 15:05:17 -0700 |
commit | ac16fba57480ab5529dab0c63f33e65b0003e205 (patch) | |
tree | 7c68e40df882d67ba2f6f533a9638c382319221c /lib/Transforms | |
parent | d41567d2ffd3413600162653c08b2365bd5bcbbf (diff) | |
parent | 3503cf8d938c71581c0439dd1267e171f0ef74b1 (diff) |
Merge remote-tracking branch 'origin/master'
Merge Nacl-LLVM work since the upstream merge branched
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/NaCl/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Transforms/NaCl/ExpandConstantExpr.cpp | 112 |
2 files changed, 113 insertions, 0 deletions
diff --git a/lib/Transforms/NaCl/CMakeLists.txt b/lib/Transforms/NaCl/CMakeLists.txt index 5e24cc7e28..acf7656f64 100644 --- a/lib/Transforms/NaCl/CMakeLists.txt +++ b/lib/Transforms/NaCl/CMakeLists.txt @@ -1,4 +1,5 @@ add_llvm_library(LLVMTransformsNaCl + ExpandConstantExpr.cpp ExpandCtors.cpp ExpandTls.cpp ExpandTlsConstantExpr.cpp diff --git a/lib/Transforms/NaCl/ExpandConstantExpr.cpp b/lib/Transforms/NaCl/ExpandConstantExpr.cpp new file mode 100644 index 0000000000..5ff47cb00c --- /dev/null +++ b/lib/Transforms/NaCl/ExpandConstantExpr.cpp @@ -0,0 +1,112 @@ +//===- ExpandConstantExpr.cpp - Convert ConstantExprs to Instructions------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass expands out ConstantExprs into Instructions. +// +// Note that this only converts ConstantExprs that are referenced by +// Instructions. It does not convert ConstantExprs that are used as +// initializers for global variables. +// +// This simplifies the language so that the PNaCl translator does not +// need to handle ConstantExprs as part of a stable wire format for +// PNaCl. +// +//===----------------------------------------------------------------------===// + +#include <map> + +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/NaCl.h" + +using namespace llvm; + +static bool expandInstruction(Instruction *Inst); + +namespace { + // This is a FunctionPass because our handling of PHI nodes means + // that our modifications may cross BasicBlocks. + struct ExpandConstantExpr : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + ExpandConstantExpr() : FunctionPass(ID) { + initializeExpandConstantExprPass(*PassRegistry::getPassRegistry()); + } + + virtual bool runOnFunction(Function &Func); + }; +} + +char ExpandConstantExpr::ID = 0; +INITIALIZE_PASS(ExpandConstantExpr, "expand-constant-expr", + "Expand out ConstantExprs into Instructions", + false, false) + +static Value *expandConstantExpr(Instruction *InsertPt, ConstantExpr *Expr) { + Instruction *NewInst = Expr->getAsInstruction(); + NewInst->insertBefore(InsertPt); + NewInst->setName("expanded"); + expandInstruction(NewInst); + return NewInst; +} + +static bool expandInstruction(Instruction *Inst) { + // A landingpad can only accept ConstantExprs, so it should remain + // unmodified. + if (isa<LandingPadInst>(Inst)) + return false; + + bool Modified = false; + if (PHINode *PN = dyn_cast<PHINode>(Inst)) { + // PHI nodes require special treatment. A incoming block may be + // listed twice, but its incoming values must match so they must + // be converted only once. + std::map<BasicBlock*,Value*> Converted; + for (unsigned OpNum = 0; OpNum < Inst->getNumOperands(); OpNum++) { + if (ConstantExpr *Expr = + dyn_cast<ConstantExpr>(Inst->getOperand(OpNum))) { + Modified = true; + BasicBlock *Incoming = PN->getIncomingBlock(OpNum); + if (Converted.count(Incoming) == 0) { + Converted[Incoming] = expandConstantExpr(Incoming->getTerminator(), + Expr); + } + Inst->setOperand(OpNum, Converted[Incoming]); + } + } + return Modified; + } + + for (unsigned OpNum = 0; OpNum < Inst->getNumOperands(); OpNum++) { + if (ConstantExpr *Expr = + dyn_cast<ConstantExpr>(Inst->getOperand(OpNum))) { + Modified = true; + Inst->setOperand(OpNum, expandConstantExpr(Inst, Expr)); + } + } + return Modified; +} + +bool ExpandConstantExpr::runOnFunction(Function &Func) { + bool Modified = false; + for (llvm::Function::iterator BB = Func.begin(), E = Func.end(); + BB != E; + ++BB) { + for (BasicBlock::InstListType::iterator Inst = BB->begin(), E = BB->end(); + Inst != E; + ++Inst) { + Modified |= expandInstruction(Inst); + } + } + return Modified; +} + +FunctionPass *llvm::createExpandConstantExprPass() { + return new ExpandConstantExpr(); +} |