[llvm-commits] [llvm] r92829 - in /llvm/trunk: include/llvm/Analysis/AliasAnalysis.h lib/Analysis/AliasAnalysis.cpp lib/Target/README.txt lib/Transforms/IPO/FunctionAttrs.cpp test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll utils/TableGen/IntrinsicEmitter.cpp

Duncan Sands baldrick at free.fr
Wed Jan 6 00:45:53 PST 2010


Author: baldrick
Date: Wed Jan  6 02:45:52 2010
New Revision: 92829

URL: http://llvm.org/viewvc/llvm-project?rev=92829&view=rev
Log:
Partially address a README by having functionattrs consider calls to
memcpy, memset and other intrinsics that only access their arguments
to be readnone if the intrinsic's arguments all point to local memory.
This improves the testcase in the README to readonly, but it could in
theory be made readnone, however this would involve more sophisticated
analysis that looks through the memcpy.

Modified:
    llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
    llvm/trunk/lib/Analysis/AliasAnalysis.cpp
    llvm/trunk/lib/Target/README.txt
    llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
    llvm/trunk/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll
    llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp

Modified: llvm/trunk/include/llvm/Analysis/AliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/AliasAnalysis.h?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/AliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/AliasAnalysis.h Wed Jan  6 02:45:52 2010
@@ -197,6 +197,10 @@
   virtual ModRefBehavior getModRefBehavior(Function *F,
                                    std::vector<PointerAccessInfo> *Info = 0);
 
+  /// getModRefBehavior - Return the modref behavior of the intrinsic with the
+  /// given id.
+  static ModRefBehavior getModRefBehavior(unsigned iid);
+
   /// doesNotAccessMemory - If the specified call is known to never read or
   /// write memory, return true.  If the call only reads from known-constant
   /// memory, it is also legal to return true.  Calls that unwind the stack

Modified: llvm/trunk/lib/Analysis/AliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/AliasAnalysis.cpp?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/AliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/AliasAnalysis.cpp Wed Jan  6 02:45:52 2010
@@ -116,13 +116,16 @@
       return DoesNotAccessMemory;
     if (F->onlyReadsMemory())
       return OnlyReadsMemory;
-    if (unsigned id = F->getIntrinsicID()) {
+    if (unsigned id = F->getIntrinsicID())
+      return getModRefBehavior(id);
+  }
+  return UnknownModRefBehavior;
+}
+
+AliasAnalysis::ModRefBehavior AliasAnalysis::getModRefBehavior(unsigned iid) {
 #define GET_INTRINSIC_MODREF_BEHAVIOR
 #include "llvm/Intrinsics.gen"
 #undef GET_INTRINSIC_MODREF_BEHAVIOR
-    }
-  }
-  return UnknownModRefBehavior;
 }
 
 AliasAnalysis::ModRefResult

Modified: llvm/trunk/lib/Target/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/README.txt?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/lib/Target/README.txt (original)
+++ llvm/trunk/lib/Target/README.txt Wed Jan  6 02:45:52 2010
@@ -1678,8 +1678,8 @@
 memory.
 
 Also, functionattrs doesn't know about memcpy/memset.  This function should be
-marked readnone, since it only twiddles local memory, but functionattrs doesn't
-handle memset/memcpy/memmove aggressively:
+marked readnone rather than readonly, since it only twiddles local memory, but
+functionattrs doesn't handle memset/memcpy/memmove aggressively:
 
 struct X { int *p; int *q; };
 int foo() {

Modified: llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/FunctionAttrs.cpp Wed Jan  6 02:45:52 2010
@@ -136,6 +136,21 @@
         // Ignore calls to functions in the same SCC.
         if (SCCNodes.count(CS.getCalledFunction()))
           continue;
+        // Ignore intrinsics that only access local memory.
+        if (unsigned id = CS.getCalledFunction()->getIntrinsicID())
+          if (AliasAnalysis::getModRefBehavior(id) ==
+              AliasAnalysis::AccessesArguments) {
+            // Check that all pointer arguments point to local memory.
+            for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
+                 CI != CE; ++CI) {
+              Value *Arg = *CI;
+              if (isa<PointerType>(Arg->getType()) && !PointsToLocalMemory(Arg))
+                // Writes memory.  Just give up.
+                return false;
+            }
+            // Only reads and writes local memory.
+            continue;
+          }
       } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
         // Ignore loads from local memory.
         if (PointsToLocalMemory(LI->getPointerOperand()))

Modified: llvm/trunk/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll (original)
+++ llvm/trunk/test/Transforms/FunctionAttrs/2008-10-04-LocalMemory.ll Wed Jan  6 02:45:52 2010
@@ -1,6 +1,8 @@
-; RUN: opt < %s -functionattrs -S | grep readnone | count 2
+; RUN: opt < %s -functionattrs -S | grep readonly | count 3
 
-declare i32 @g(i32*) readnone
+%struct.X = type { i32*, i32* }
+
+declare i32 @g(i32*) readonly
 
 define i32 @f() {
 	%x = alloca i32		; <i32*> [#uses=2]
@@ -8,3 +10,30 @@
 	%y = call i32 @g(i32* %x)		; <i32> [#uses=1]
 	ret i32 %y
 }
+
+define i32 @foo() nounwind {
+entry:
+  %y = alloca %struct.X                           ; <%struct.X*> [#uses=2]
+  %x = alloca %struct.X                           ; <%struct.X*> [#uses=2]
+  %j = alloca i32                                 ; <i32*> [#uses=2]
+  %i = alloca i32                                 ; <i32*> [#uses=2]
+  %"alloca point" = bitcast i32 0 to i32          ; <i32> [#uses=0]
+  store i32 0, i32* %i, align 4
+  store i32 1, i32* %j, align 4
+  %0 = getelementptr inbounds %struct.X* %y, i32 0, i32 0 ; <i32**> [#uses=1]
+  store i32* %i, i32** %0, align 8
+  %1 = getelementptr inbounds %struct.X* %x, i32 0, i32 1 ; <i32**> [#uses=1]
+  store i32* %j, i32** %1, align 8
+  %x1 = bitcast %struct.X* %x to i8*              ; <i8*> [#uses=2]
+  %y2 = bitcast %struct.X* %y to i8*              ; <i8*> [#uses=1]
+  call void @llvm.memcpy.i64(i8* %x1, i8* %y2, i64 8, i32 1)
+  %2 = bitcast i8* %x1 to i32**                   ; <i32**> [#uses=1]
+  %3 = load i32** %2, align 8                     ; <i32*> [#uses=1]
+  %4 = load i32* %3, align 4                      ; <i32> [#uses=1]
+  br label %return
+
+return:                                           ; preds = %entry
+  ret i32 %4
+}
+
+declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind

Modified: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp?rev=92829&r1=92828&r2=92829&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp Wed Jan  6 02:45:52 2010
@@ -522,7 +522,7 @@
 EmitModRefBehavior(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS){
   OS << "// Determine intrinsic alias analysis mod/ref behavior.\n";
   OS << "#ifdef GET_INTRINSIC_MODREF_BEHAVIOR\n";
-  OS << "switch (id) {\n";
+  OS << "switch (iid) {\n";
   OS << "default:\n    return UnknownModRefBehavior;\n";
   for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
     if (Ints[i].ModRef == CodeGenIntrinsic::WriteMem)





More information about the llvm-commits mailing list