Allow readnone functions to read (and write!) global
authorDuncan Sands <baldrick@free.fr>
Mon, 29 Dec 2008 11:34:09 +0000 (11:34 +0000)
committerDuncan Sands <baldrick@free.fr>
Mon, 29 Dec 2008 11:34:09 +0000 (11:34 +0000)
constants, since doing so is irrelevant for aliasing
purposes.  While this doesn't increase the total number
of functions marked readonly or readnone in MultiSource/
Applications (3089), it does result in 12 functions being
marked readnone rather than readonly.
Before:
  readnone: 820
  readonly: 2269
After:
  readnone: 832
  readonly: 2257

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61469 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/AddReadAttrs.cpp
test/Transforms/AddReadAttrs/2008-12-29-Constant.ll [new file with mode: 0644]

index 5460a5bde7b1507bb0b7488a3328c0c56c1b9eeb..2835d5e9f3617c0b8e41221f42987d32882a443c 100644 (file)
@@ -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 (file)
index 0000000..fe038c1
--- /dev/null
@@ -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
+}