Implement AccessesArguments checking in the two-callsite form
authorDan Gohman <gohman@apple.com>
Thu, 5 Aug 2010 23:34:50 +0000 (23:34 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 5 Aug 2010 23:34:50 +0000 (23:34 +0000)
of BasicAA::getModRefInfo. This allows BasicAA to say that two
memset calls to non-aliasing memory locations don't interfere.

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

lib/Analysis/BasicAliasAnalysis.cpp
test/Analysis/BasicAA/getmodrefinfo-cs-cs.ll

index 11cba991a951b4790a0c9ac4bbfca39153173d6c..33c04c1d07fe7e3659f539b501a783b17136e1dd 100644 (file)
@@ -429,13 +429,43 @@ BasicAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
   if (CS1B == OnlyReadsMemory && CS2B == OnlyReadsMemory)
     return NoModRef;
 
+  AliasAnalysis::ModRefResult Mask = ModRef;
+
   // If CS1 only reads memory, the only dependence on CS2 can be
   // from CS1 reading memory written by CS2.
   if (CS1B == OnlyReadsMemory)
-    return Ref;
+    Mask = ModRefResult(Mask & Ref);
   
+  // If CS2 only access memory through arguments, accumulate the mod/ref
+  // information from CS1's references to the memory referenced by
+  // CS2's arguments.
+  if (CS2B == AccessesArguments) {
+    AliasAnalysis::ModRefResult R = NoModRef;
+    for (ImmutableCallSite::arg_iterator
+         I = CS2.arg_begin(), E = CS2.arg_end(); I != E; ++I) {
+      R = ModRefResult((R | getModRefInfo(CS1, *I, UnknownSize)) & Mask);
+      if (R == Mask)
+        break;
+    }
+    return R;
+  }
+
+  // If CS1 only accesses memory through arguments, check if CS2 references
+  // any of the memory referenced by CS1's arguments. If not, return NoModRef.
+  if (CS1B == AccessesArguments) {
+    AliasAnalysis::ModRefResult R = NoModRef;
+    for (ImmutableCallSite::arg_iterator
+         I = CS1.arg_begin(), E = CS1.arg_end(); I != E; ++I)
+      if (getModRefInfo(CS2, *I, UnknownSize) != NoModRef) {
+        R = Mask;
+        break;
+      }
+    if (R == NoModRef)
+      return R;
+  }
+
   // Otherwise, fall back to NoAA (mod+ref).
-  return NoAA::getModRefInfo(CS1, CS2);
+  return ModRefResult(NoAA::getModRefInfo(CS1, CS2) & Mask);
 }
 
 /// GetIndexDifference - Dest and Src are the variable indices from two
index f655913f3d129c7a5c4b60d81b60410b9178923d..12b088b1f6518adfe0c24854d44789f263171731 100644 (file)
@@ -1,12 +1,26 @@
 ; RUN: opt < %s -aa-eval -print-all-alias-modref-info -disable-output |& FileCheck %s
 
+
 ; CHECK: Just Ref: call void @ro() <-> call void @f0()
 
 declare void @f0()
 declare void @ro() readonly
 
-define void @test() {
+define void @test0() {
   call void @f0()
   call void @ro()
   ret void
 }
+
+; CHECK: NoModRef:   call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i32 1, i1 false) <->   call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i32 1, i1 false)
+; CHECK: NoModRef:   call void @llvm.memset.p0i8.i64(i8* @B, i8 0, i64 1, i32 1, i1 false) <->   call void @llvm.memset.p0i8.i64(i8* @A, i8 0, i64 1, i32 1, i1 false)
+
+declare void @llvm.memset.i64(i8*, i8, i64, i32)
+
+@A = external global i8
+@B = external global i8
+define void @test1() {
+  call void @llvm.memset.i64(i8* @A, i8 0, i64 1, i32 1)
+  call void @llvm.memset.i64(i8* @B, i8 0, i64 1, i32 1)
+  ret void
+}