diff options
| author | Mark Seaborn <mseaborn@chromium.org> | 2013-03-15 13:44:43 -0700 |
|---|---|---|
| committer | Mark Seaborn <mseaborn@chromium.org> | 2013-03-15 13:44:43 -0700 |
| commit | bd7c1e1fa62acc37cf1bed3c1272703bbffd7242 (patch) | |
| tree | b7c1dd9e10beb99f701868d98a67f4287005c769 /lib/Transforms | |
| parent | 5d4b7153b9eaa695f036357a7a7a24ff3be2b35e (diff) | |
PNaCl: Add ExpandConstantExpr pass for converting ConstantExprs to Instructions
Once this pass is enabled, it will simplify the language to reduce the
set of constructs that a PNaCl translator needs to handle as part of a
stable wire format for PNaCl.
BUG=https://code.google.com/p/nativeclient/issues/detail?id=3337
TEST=test/Transforms/NaCl/expand-constantexpr.ll
Review URL: https://codereview.chromium.org/12792011
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(); +} |
