diff options
-rw-r--r-- | lib/Transforms/IPO/AddReadAttrs.cpp | 23 | ||||
-rw-r--r-- | test/Transforms/AddReadAttrs/2008-12-29-Constant.ll | 8 |
2 files changed, 27 insertions, 4 deletions
diff --git a/lib/Transforms/IPO/AddReadAttrs.cpp b/lib/Transforms/IPO/AddReadAttrs.cpp index 5460a5bde7..2835d5e9f3 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<AllocaInst>(V)) + return true; + // A global constant counts as local memory for our purposes. + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) + return GV->isConstant(); + return false; +} + bool AddReadAttrs::runOnSCC(const std::vector<CallGraphNode *> &SCC) { SmallPtrSet<CallGraphNode *, 8> SCCNodes; CallGraph &CG = getAnalysis<CallGraph>(); @@ -96,14 +113,12 @@ bool AddReadAttrs::runOnSCC(const std::vector<CallGraphNode *> &SCC) { if (SCCNodes.count(CG[CS.getCalledFunction()])) continue; } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) { - Value *Target = LI->getPointerOperand()->getUnderlyingObject(); // Ignore loads from local memory. - if (isa<AllocaInst>(Target)) + if (PointsToLocalMemory(LI->getPointerOperand())) continue; } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) { - Value *Target = SI->getPointerOperand()->getUnderlyingObject(); // Ignore stores to local memory. - if (isa<AllocaInst>(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 0000000000..fe038c1be9 --- /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 ; <i8*> [#uses=1] + +define i8 @f() { + %tmp = load i8* @s ; <i8> [#uses=1] + ret i8 %tmp +} |