diff options
author | Chris Lattner <sabre@nondot.org> | 2003-06-26 05:06:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-06-26 05:06:25 +0000 |
commit | 833b8a4181f3a8a9f41fea373c0081aa97efd20b (patch) | |
tree | 44dadde2bb2498820bb8205581d2d2279237e267 | |
parent | b75e1e79d7e73f1744a19527f7e8e8945fe04cd0 (diff) | |
download | external_llvm-833b8a4181f3a8a9f41fea373c0081aa97efd20b.zip external_llvm-833b8a4181f3a8a9f41fea373c0081aa97efd20b.tar.gz external_llvm-833b8a4181f3a8a9f41fea373c0081aa97efd20b.tar.bz2 |
Add support for elimination of load instruction from global constants
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6912 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 696575e..5d04d77 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -22,6 +22,7 @@ #include "llvm/Constants.h" #include "llvm/ConstantHandling.h" #include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" #include "llvm/Support/InstIterator.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Support/CallSite.h" @@ -79,6 +80,7 @@ namespace { Instruction *visitPHINode(PHINode &PN); Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP); Instruction *visitAllocationInst(AllocationInst &AI); + Instruction *visitLoadInst(LoadInst &LI); Instruction *visitBranchInst(BranchInst &BI); // visitInstruction - Specify what to return for unhandled instructions... @@ -1261,6 +1263,52 @@ Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) { return 0; } +/// GetGEPGlobalInitializer - Given a constant, and a getelementptr +/// constantexpr, return the constant value being addressed by the constant +/// expression, or null if something is funny. +/// +static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) { + if (CE->getOperand(1) != Constant::getNullValue(Type::LongTy)) + return 0; // Do not allow stepping over the value! + + // Loop over all of the operands, tracking down which value we are + // addressing... + for (unsigned i = 2, e = CE->getNumOperands(); i != e; ++i) + if (ConstantUInt *CU = dyn_cast<ConstantUInt>(CE->getOperand(i))) { + ConstantStruct *CS = cast<ConstantStruct>(C); + if (CU->getValue() >= CS->getValues().size()) return 0; + C = cast<Constant>(CS->getValues()[CU->getValue()]); + } else if (ConstantSInt *CS = dyn_cast<ConstantSInt>(CE->getOperand(i))) { + ConstantArray *CA = cast<ConstantArray>(C); + if ((uint64_t)CS->getValue() >= CA->getValues().size()) return 0; + C = cast<Constant>(CA->getValues()[CS->getValue()]); + } else + return 0; + return C; +} + +Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { + Value *Op = LI.getOperand(0); + if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Op)) + Op = CPR->getValue(); + + // Instcombine load (constant global) into the value loaded... + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Op)) + if (GV->isConstant()) + return ReplaceInstUsesWith(LI, GV->getInitializer()); + + // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded... + if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Op)) + if (CE->getOpcode() == Instruction::GetElementPtr) + if (ConstantPointerRef *G=dyn_cast<ConstantPointerRef>(CE->getOperand(0))) + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G->getValue())) + if (GV->isConstant()) + if (Constant *V = GetGEPGlobalInitializer(GV->getInitializer(), CE)) + return ReplaceInstUsesWith(LI, V); + return 0; +} + + Instruction *InstCombiner::visitBranchInst(BranchInst &BI) { // Change br (not X), label True, label False to: br X, label False, True if (BI.isConditional() && !isa<Constant>(BI.getCondition())) |