From: Chris Lattner Date: Thu, 26 Jun 2003 05:06:25 +0000 (+0000) Subject: Add support for elimination of load instruction from global constants X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=833b8a4181f3a8a9f41fea373c0081aa97efd20b;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 696575e3d6b..5d04d7737ff 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(CE->getOperand(i))) { + ConstantStruct *CS = cast(C); + if (CU->getValue() >= CS->getValues().size()) return 0; + C = cast(CS->getValues()[CU->getValue()]); + } else if (ConstantSInt *CS = dyn_cast(CE->getOperand(i))) { + ConstantArray *CA = cast(C); + if ((uint64_t)CS->getValue() >= CA->getValues().size()) return 0; + C = cast(CA->getValues()[CS->getValue()]); + } else + return 0; + return C; +} + +Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { + Value *Op = LI.getOperand(0); + if (ConstantPointerRef *CPR = dyn_cast(Op)) + Op = CPR->getValue(); + + // Instcombine load (constant global) into the value loaded... + if (GlobalVariable *GV = dyn_cast(Op)) + if (GV->isConstant()) + return ReplaceInstUsesWith(LI, GV->getInitializer()); + + // Instcombine load (constantexpr_GEP global, 0, ...) into the value loaded... + if (ConstantExpr *CE = dyn_cast(Op)) + if (CE->getOpcode() == Instruction::GetElementPtr) + if (ConstantPointerRef *G=dyn_cast(CE->getOperand(0))) + if (GlobalVariable *GV = dyn_cast(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(BI.getCondition()))