Teach BasicAA::getModRefInfo(CallSite, CallSite) some
[oota-llvm.git] / lib / Analysis / BasicAliasAnalysis.cpp
index e9c6490ebb75d6c25c058523b1b916fb8a491b77..944d0e0d375669b205f0d67fc56b24bda1ef9fe8 100644 (file)
@@ -164,19 +164,24 @@ static bool isNonEscapingLocalObject(const Value *V) {
 /// by V is smaller than Size.
 static bool isObjectSmallerThan(const Value *V, unsigned Size,
                                 const TargetData &TD) {
-  const Type *AccessTy = 0;
-  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+  const Type *AccessTy;
+  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
     AccessTy = GV->getType()->getElementType();
-  
-  if (const AllocationInst *AI = dyn_cast<AllocationInst>(V))
+  } else if (const AllocationInst *AI = dyn_cast<AllocationInst>(V)) {
     if (!AI->isArrayAllocation())
       AccessTy = AI->getType()->getElementType();
-
-  if (const Argument *A = dyn_cast<Argument>(V))
+    else
+      return false;
+  } else if (const Argument *A = dyn_cast<Argument>(V)) {
     if (A->hasByValAttr())
       AccessTy = cast<PointerType>(A->getType())->getElementType();
+    else
+      return false;
+  } else {
+    return false;
+  }
   
-  if (AccessTy && AccessTy->isSized())
+  if (AccessTy->isSized())
     return TD.getABITypeSize(AccessTy) < Size;
   return false;
 }
@@ -259,10 +264,8 @@ namespace {
                       const Value *V2, unsigned V2Size);
 
     ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
-    ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
-      return NoAA::getModRefInfo(CS1,CS2);
-    }
-
+    ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
+    
     /// hasNoModRefInfoForCalls - We can provide mod/ref information against
     /// non-escaping allocations.
     virtual bool hasNoModRefInfoForCalls() const { return false; }
@@ -347,6 +350,24 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
 }
 
 
+AliasAnalysis::ModRefResult 
+BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
+  // If CS1 or CS2 are readnone, they don't interact.
+  ModRefBehavior CS1B = AliasAnalysis::getModRefBehavior(CS1);
+  if (CS1B == DoesNotAccessMemory) return NoModRef;
+  
+  ModRefBehavior CS2B = AliasAnalysis::getModRefBehavior(CS2);
+  if (CS2B == DoesNotAccessMemory) return NoModRef;
+  
+  // If they both only read from memory, just return ref.
+  if (CS1B == OnlyReadsMemory && CS2B == OnlyReadsMemory)
+    return Ref;
+  
+  // Otherwise, fall back to NoAA (mod+ref).
+  return NoAA::getModRefInfo(CS1, CS2);
+}
+
+
 // alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
 // as array references.  Note that this function is heavily tail recursive.
 // Hopefully we have a smart C++ compiler.  :)
@@ -383,9 +404,9 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
     if (isIdentifiedObject(O1) && isIdentifiedObject(O2))
       return NoAlias;
   
-    // Local allocations can't alias with arguments or noalias functions.
-    if ((isa<AllocationInst>(O1) && (isa<Argument>(O2) || isNoAliasCall(O2))) ||
-        (isa<AllocationInst>(O2) && (isa<Argument>(O1) || isNoAliasCall(O1))))
+    // Arguments can't alias with local allocations or noalias calls.
+    if ((isa<Argument>(O1) && (isa<AllocationInst>(O2) || isNoAliasCall(O2))) ||
+        (isa<Argument>(O2) && (isa<AllocationInst>(O1) || isNoAliasCall(O1))))
       return NoAlias;
 
     // Most objects can't alias null.
@@ -525,7 +546,7 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
   return MayAlias;
 }
 
-// This function is used to determin if the indices of two GEP instructions are
+// This function is used to determine if the indices of two GEP instructions are
 // equal. V1 and V2 are the indices.
 static bool IndexOperandsEqual(Value *V1, Value *V2) {
   if (V1->getType() == V2->getType())