From 5638dc618acd725d1128e77cd28a6e0ed66185c4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Nov 2009 06:06:14 +0000 Subject: [PATCH] Use the libanalysis 'ConstantFoldLoadFromConstPtr' function instead of reinventing SCCP-specific logic. This gives us new powers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85789 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SCCP.cpp | 29 +++++++++++------------------ test/Transforms/SCCP/loadtest.ll | 11 +++++++++-- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index dd95ed8fa43..dd9f7651a5d 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -28,6 +28,7 @@ #include "llvm/Analysis/MemoryBuiltins.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Target/TargetData.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -154,6 +155,7 @@ namespace { /// Constant Propagation. /// class SCCPSolver : public InstVisitor { + const TargetData *TD; DenseSet BBExecutable;// The basic blocks that are executable DenseMap ValueState; // The state each value is in. @@ -194,6 +196,7 @@ class SCCPSolver : public InstVisitor { typedef std::pair Edge; DenseSet KnownFeasibleEdges; public: + SCCPSolver(const TargetData *td) : TD(td) {} /// MarkBlockExecutable - This method can be used by clients to mark all of /// the blocks that are known to be intrinsically live in the processed unit. @@ -1109,16 +1112,15 @@ void SCCPSolver::visitStoreInst(StoreInst &SI) { // global, we can replace the load with the loaded constant value! void SCCPSolver::visitLoadInst(LoadInst &I) { LatticeVal PtrVal = getValueState(I.getOperand(0)); + if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! LatticeVal &IV = ValueState[&I]; if (IV.isOverdefined()) return; - if (PtrVal.isUndefined()) return; // The pointer is not resolved yet! - if (!PtrVal.isConstant() || I.isVolatile()) return markOverdefined(IV, &I); - Value *Ptr = PtrVal.getConstant(); + Constant *Ptr = PtrVal.getConstant(); // load null -> null if (isa(Ptr) && I.getPointerAddressSpace() == 0) @@ -1126,11 +1128,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) { // Transform load (constant global) into the value loaded. if (GlobalVariable *GV = dyn_cast(Ptr)) { - if (GV->isConstant()) { - if (GV->hasDefinitiveInitializer()) - return markConstant(IV, &I, GV->getInitializer()); - - } else if (!TrackedGlobals.empty()) { + if (!TrackedGlobals.empty()) { // If we are tracking this global, merge in the known value for it. DenseMap::iterator It = TrackedGlobals.find(GV); @@ -1141,14 +1139,9 @@ void SCCPSolver::visitLoadInst(LoadInst &I) { } } - // Transform load (constantexpr_GEP global, 0, ...) into the value loaded. - if (ConstantExpr *CE = dyn_cast(Ptr)) - if (CE->getOpcode() == Instruction::GetElementPtr) - if (GlobalVariable *GV = dyn_cast(CE->getOperand(0))) - if (GV->isConstant() && GV->hasDefinitiveInitializer()) - if (Constant *V = - ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE)) - return markConstant(IV, &I, V); + // Transform load from a constant into a constant if possible. + if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, TD)) + return markConstant(IV, &I, C); // Otherwise we cannot say for certain what value this load will produce. // Bail out. @@ -1530,7 +1523,7 @@ static void DeleteInstructionInBlock(BasicBlock *BB) { // bool SCCP::runOnFunction(Function &F) { DEBUG(errs() << "SCCP on function '" << F.getName() << "'\n"); - SCCPSolver Solver; + SCCPSolver Solver(getAnalysisIfAvailable()); // Mark the first block of the function as being executable. Solver.MarkBlockExecutable(F.begin()); @@ -1640,7 +1633,7 @@ static bool AddressIsTaken(GlobalValue *GV) { } bool IPSCCP::runOnModule(Module &M) { - SCCPSolver Solver; + SCCPSolver Solver(getAnalysisIfAvailable()); // Loop over all functions, marking arguments to those with their addresses // taken or that are external as overdefined. diff --git a/test/Transforms/SCCP/loadtest.ll b/test/Transforms/SCCP/loadtest.ll index fd82aef821f..add2af483f5 100644 --- a/test/Transforms/SCCP/loadtest.ll +++ b/test/Transforms/SCCP/loadtest.ll @@ -1,5 +1,6 @@ ; This test makes sure that these instructions are properly constant propagated. -; + +target datalayout = "e-p:32:32" ; RUN: opt < %s -sccp -S | not grep load @@ -20,7 +21,13 @@ define float @test2() { define i32 @test3() { %A = getelementptr [2 x { i32, float }]* @Y, i64 0, i64 0, i32 0 ; [#uses=1] - %B = load i32* %A ; [#uses=1] + %B = load i32* %A ret i32 %B } +define i8 @test4() { + %A = bitcast i32* @X to i8* + %B = load i8* %A + ret i8 %B +} +