diff --git a/lib/Transforms/IPO/AddReadAttrs.cpp b/lib/Transforms/IPO/AddReadAttrs.cpp index 5460a5bde7b..2835d5e9f36 100644 --- a/lib/Transforms/IPO/AddReadAttrs.cpp +++ b/lib/Transforms/IPO/AddReadAttrs.cpp @@ -17,6 +17,7 @@ #define DEBUG_TYPE "addreadattrs" #include "llvm/Transforms/IPO.h" #include "llvm/CallGraphSCCPass.h" +#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/ADT/SmallPtrSet.h" @@ -40,6 +41,8 @@ namespace { AU.setPreservesCFG(); CallGraphSCCPass::getAnalysisUsage(AU); } + + bool PointsToLocalMemory(Value *V); }; } @@ -50,6 +53,20 @@ X("addreadattrs", "Mark functions readnone/readonly"); Pass *llvm::createAddReadAttrsPass() { return new AddReadAttrs(); } +/// PointsToLocalMemory - Returns whether the given pointer value points to +/// memory that is local to the function. Global constants are considered +/// local to all functions. +bool AddReadAttrs::PointsToLocalMemory(Value *V) { + V = V->getUnderlyingObject(); + // An alloca instruction defines local memory. + if (isa(V)) + return true; + // A global constant counts as local memory for our purposes. + if (GlobalVariable *GV = dyn_cast(V)) + return GV->isConstant(); + return false; +} + bool AddReadAttrs::runOnSCC(const std::vector &SCC) { SmallPtrSet SCCNodes; CallGraph &CG = getAnalysis(); @@ -96,14 +113,12 @@ bool AddReadAttrs::runOnSCC(const std::vector &SCC) { if (SCCNodes.count(CG[CS.getCalledFunction()])) continue; } else if (LoadInst *LI = dyn_cast(I)) { - Value *Target = LI->getPointerOperand()->getUnderlyingObject(); // Ignore loads from local memory. - if (isa(Target)) + if (PointsToLocalMemory(LI->getPointerOperand())) continue; } else if (StoreInst *SI = dyn_cast(I)) { - Value *Target = SI->getPointerOperand()->getUnderlyingObject(); // Ignore stores to local memory. - if (isa(Target)) + if (PointsToLocalMemory(SI->getPointerOperand())) continue; } diff --git a/test/Transforms/AddReadAttrs/2008-12-29-Constant.ll b/test/Transforms/AddReadAttrs/2008-12-29-Constant.ll new file mode 100644 index 00000000000..fe038c1be9a --- /dev/null +++ b/test/Transforms/AddReadAttrs/2008-12-29-Constant.ll @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | opt -addreadattrs | llvm-dis | grep readnone + +@s = external constant i8 ; [#uses=1] + +define i8 @f() { + %tmp = load i8* @s ; [#uses=1] + ret i8 %tmp +}