In addition to arguments passed to it, memcpy (and all other calls) can ModRef pointe...
[oota-llvm.git] / lib / Analysis / BasicAliasAnalysis.cpp
index 5ec9afaec98797d47b4d09a27b2073cdb3598b9a..200779f0e7aef7e760221c33da42fdd7eafc6f69 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/ParameterAttributes.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Instructions.h"
-#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
 #include "llvm/Pass.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
@@ -116,9 +114,6 @@ namespace {
     /// global) or not.
     bool pointsToConstantMemory(const Value *P);
 
-    virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
-                                          std::vector<PointerAccessInfo> *Info);
-
   private:
     // CheckGEPInstructions - Check two GEP instructions with known
     // must-aliasing base pointers.  This checks to see if the index expressions
@@ -143,9 +138,10 @@ ImmutablePass *llvm::createBasicAliasAnalysisPass() {
   return new BasicAliasAnalysis();
 }
 
-// getUnderlyingObject - This traverses the use chain to figure out what object
-// the specified value points to.  If the value points to, or is derived from, a
-// unique object or an argument, return it.
+/// getUnderlyingObject - This traverses the use chain to figure out what object
+/// the specified value points to.  If the value points to, or is derived from,
+/// a unique object or an argument, return it.  This returns:
+///    Arguments, GlobalVariables, Functions, Allocas, Mallocs.
 static const Value *getUnderlyingObject(const Value *V) {
   if (!isa<PointerType>(V->getType())) return 0;
 
@@ -223,8 +219,6 @@ static bool AddressMightEscape(const Value *V) {
         return true;
       break; // next use.
     case Instruction::BitCast:
-      if (!isa<PointerType>(I->getType()))
-        return true;
       if (AddressMightEscape(I))
         return true;
       break; // next use
@@ -232,6 +226,12 @@ static bool AddressMightEscape(const Value *V) {
       // If returned, the address will escape to calling functions, but no
       // callees could modify it.
       break; // next use
+    case Instruction::Call:
+      // If the call is to a few known safe intrinsics, we know that it does
+      // not escape
+      if (!isa<MemIntrinsic>(I))
+        return true;
+      break;  // next use
     default:
       return true;
     }
@@ -246,41 +246,45 @@ static bool AddressMightEscape(const Value *V) {
 //
 AliasAnalysis::ModRefResult
 BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
-  if (!isa<Constant>(P))
-    if (const AllocationInst *AI =
-                  dyn_cast_or_null<AllocationInst>(getUnderlyingObject(P))) {
-      // Okay, the pointer is to a stack allocated object.  If we can prove that
-      // the pointer never "escapes", then we know the call cannot clobber it,
-      // because it simply can't get its address.
-      if (!AddressMightEscape(AI))
-        return NoModRef;
+  if (!isa<Constant>(P)) {
+    const Value *Object = getUnderlyingObject(P);
+    // Allocations and byval arguments are "new" objects.
+    if (Object &&
+        (isa<AllocationInst>(Object) || isa<Argument>(Object))) {
+      // Okay, the pointer is to a stack allocated (or effectively so, for 
+      // for noalias parameters) object.  If the address of this object doesn't
+      // escape from this function body to a callee, then we know that no
+      // callees can mod/ref it unless they are actually passed it.
+      if (isa<AllocationInst>(Object) ||
+          cast<Argument>(Object)->hasByValAttr() ||
+          cast<Argument>(Object)->hasNoAliasAttr())
+        if (!AddressMightEscape(Object)) {
+          bool passedAsArg = false;
+          for (CallSite::arg_iterator CI = CS.arg_begin(), CE = CS.arg_end();
+              CI != CE; ++CI)
+            if (isa<PointerType>((*CI)->getType()) &&
+                ( getUnderlyingObject(*CI) == P ||
+                  alias(cast<Value>(CI), ~0ULL, P, ~0ULL) != NoAlias) )
+              passedAsArg = true;
+          
+          if (!passedAsArg)
+            return NoModRef;
+        }
 
       // If this is a tail call and P points to a stack location, we know that
       // the tail call cannot access or modify the local stack.
-      if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
-        if (CI->isTailCall() && isa<AllocaInst>(AI))
-          return NoModRef;
+      if (isa<AllocaInst>(Object) ||
+          (isa<Argument>(Object) && cast<Argument>(Object)->hasByValAttr()))
+        if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
+          if (CI->isTailCall())
+            return NoModRef;
     }
+  }
 
   // The AliasAnalysis base class has some smarts, lets use them.
   return AliasAnalysis::getModRefInfo(CS, P, Size);
 }
 
-static bool isNoAliasArgument(const Argument *Arg) {
-  const Function *Func = Arg->getParent();
-  const ParamAttrsList *Attr = Func->getParamAttrs();
-  if (Attr) {
-    unsigned Idx = 1;
-    for (Function::const_arg_iterator I = Func->arg_begin(), 
-          E = Func->arg_end(); I != E; ++I, ++Idx) {
-      if (&(*I) == Arg && 
-           Attr->paramHasAttr(Idx, ParamAttr::NoAlias))
-        return true;
-    }
-  }
-  return false;
-}
-
 // 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.  :)
@@ -322,9 +326,12 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
         
         // If they are two different objects, and one is a noalias argument
         // then they do not alias.
-        if (O1 != O2 && isNoAliasArgument(O1Arg))
+        if (O1 != O2 && O1Arg->hasNoAliasAttr())
           return NoAlias;
-          
+
+        // Byval arguments can't alias globals or other arguments.
+        if (O1 != O2 && O1Arg->hasByValAttr()) return NoAlias;
+        
         // Otherwise, nothing is known...
       } 
       
@@ -334,16 +341,18 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
         
         // If they are two different objects, and one is a noalias argument
         // then they do not alias.
-        if (O1 != O2 && isNoAliasArgument(O2Arg))
+        if (O1 != O2 && O2Arg->hasNoAliasAttr())
           return NoAlias;
           
+        // Byval arguments can't alias globals or other arguments.
+        if (O1 != O2 && O2Arg->hasByValAttr()) return NoAlias;
+        
         // Otherwise, nothing is known...
       
-      } else if (O1 != O2) {
-        if (!isa<Argument>(O1))
-          // If they are two different objects, and neither is an argument,
-          // we know that we have no alias...
-          return NoAlias;
+      } else if (O1 != O2 && !isa<Argument>(O1)) {
+        // If they are two different objects, and neither is an argument,
+        // we know that we have no alias.
+        return NoAlias;
       }
 
       // If they are the same object, they we can look at the indexes.  If they
@@ -352,9 +361,15 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
       // can't tell anything.
     }
 
-
-    if (!isa<Argument>(O1) && isa<ConstantPointerNull>(V2))
-      return NoAlias;                    // Unique values don't alias null
+    // Unique values don't alias null, except non-byval arguments.
+    if (isa<ConstantPointerNull>(V2)) {
+      if (const Argument *O1Arg = dyn_cast<Argument>(O1)) {
+        if (O1Arg->hasByValAttr()) 
+          return NoAlias;
+      } else {
+        return NoAlias;                    
+      }
+    }
 
     if (isa<GlobalVariable>(O1) ||
         (isa<AllocationInst>(O1) &&
@@ -396,17 +411,19 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
   if (isGEP(V1) && isGEP(V2)) {
     // Drill down into the first non-gep value, to test for must-aliasing of
     // the base pointers.
-    const Value *BasePtr1 = V1, *BasePtr2 = V2;
-    do {
-      BasePtr1 = cast<User>(BasePtr1)->getOperand(0);
-    } while (isGEP(BasePtr1) &&
-             cast<User>(BasePtr1)->getOperand(1) ==
-       Constant::getNullValue(cast<User>(BasePtr1)->getOperand(1)->getType()));
-    do {
-      BasePtr2 = cast<User>(BasePtr2)->getOperand(0);
-    } while (isGEP(BasePtr2) &&
-             cast<User>(BasePtr2)->getOperand(1) ==
-       Constant::getNullValue(cast<User>(BasePtr2)->getOperand(1)->getType()));
+    const User *G = cast<User>(V1);
+    while (isGEP(G->getOperand(0)) &&
+           G->getOperand(1) ==
+           Constant::getNullValue(G->getOperand(1)->getType()))
+      G = cast<User>(G->getOperand(0));
+    const Value *BasePtr1 = G->getOperand(0);
+
+    G = cast<User>(V2);
+    while (isGEP(G->getOperand(0)) &&
+           G->getOperand(1) ==
+           Constant::getNullValue(G->getOperand(1)->getType()))
+      G = cast<User>(G->getOperand(0));
+    const Value *BasePtr2 = G->getOperand(0);
 
     // Do the base pointers alias?
     AliasResult BaseAlias = alias(BasePtr1, ~0U, BasePtr2, ~0U);
@@ -735,8 +752,8 @@ BasicAliasAnalysis::CheckGEPInstructions(
           if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
             if (Op1C->getZExtValue() >= AT->getNumElements())
               return MayAlias;  // Be conservative with out-of-range accesses
-          } else if (const VectorType *PT = dyn_cast<VectorType>(BasePtr1Ty)) {
-            if (Op1C->getZExtValue() >= PT->getNumElements())
+          } else if (const VectorType *VT = dyn_cast<VectorType>(BasePtr1Ty)) {
+            if (Op1C->getZExtValue() >= VT->getNumElements())
               return MayAlias;  // Be conservative with out-of-range accesses
           }
           
@@ -761,10 +778,10 @@ BasicAliasAnalysis::CheckGEPInstructions(
       if (Op2) {
         if (const ConstantInt *Op2C = dyn_cast<ConstantInt>(Op2)) {
           // If this is an array index, make sure the array element is in range.
-          if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
+          if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr2Ty)) {
             if (Op2C->getZExtValue() >= AT->getNumElements())
               return MayAlias;  // Be conservative with out-of-range accesses
-          } else if (const VectorType *VT = dyn_cast<VectorType>(BasePtr1Ty)) {
+          } else if (const VectorType *VT = dyn_cast<VectorType>(BasePtr2Ty)) {
             if (Op2C->getZExtValue() >= VT->getNumElements())
               return MayAlias;  // Be conservative with out-of-range accesses
           }
@@ -810,37 +827,5 @@ BasicAliasAnalysis::CheckGEPInstructions(
   return MayAlias;
 }
 
-static ManagedStatic<BitVector> NoMemoryIntrinsics;
-static ManagedStatic<BitVector> OnlyReadsMemoryIntrinsics;
-
-AliasAnalysis::ModRefBehavior
-BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
-                                      std::vector<PointerAccessInfo> *Info) {
-  if (!F->isDeclaration()) return UnknownModRefBehavior;
-
-  static bool Initialized = false;
-  if (!Initialized) {
-    NoMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
-    OnlyReadsMemoryIntrinsics->resize(Intrinsic::num_intrinsics);
-#define GET_MODREF_BEHAVIOR
-#include "llvm/Intrinsics.gen"
-#undef GET_MODREF_BEHAVIOR
-    
-    Initialized = true;
-  }
-
-  // If this is an intrinsic, we can use lookup tables
-  if (unsigned id = F->getIntrinsicID()) {
-    if (NoMemoryIntrinsics->test(id))
-      return DoesNotAccessMemory;
-    if (OnlyReadsMemoryIntrinsics->test(id))
-      return OnlyReadsMemory;
-
-    return UnknownModRefBehavior;
-  }
-
-  return UnknownModRefBehavior;
-}
-
 // Make sure that anything that uses AliasAnalysis pulls in this file...
 DEFINING_FILE_FOR(BasicAliasAnalysis)