In addition to arguments passed to it, memcpy (and all other calls) can ModRef pointe...
[oota-llvm.git] / lib / Analysis / BasicAliasAnalysis.cpp
index c6e34da5ac3259d97181ceaded824eeb2134e287..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->getFunctionType()->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,156 +827,5 @@ BasicAliasAnalysis::CheckGEPInstructions(
   return MayAlias;
 }
 
-namespace {
-  struct VISIBILITY_HIDDEN StringCompare {
-    bool operator()(const char *LHS, const char *RHS) {
-      return strcmp(LHS, RHS) < 0;
-    }
-  };
-}
-
-// Note that this list cannot contain libm functions (such as acos and sqrt)
-// that set errno on a domain or other error.
-static const char *DoesntAccessMemoryFns[] = {
-  "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
-  "trunc", "truncf", "truncl", "ldexp",
-
-  "atan", "atanf", "atanl",   "atan2", "atan2f", "atan2l",
-  "cbrt",
-  "cos", "cosf", "cosl",
-  "exp", "expf", "expl",
-  "hypot",
-  "sin", "sinf", "sinl",
-  "tan", "tanf", "tanl",      "tanh", "tanhf", "tanhl",
-  
-  "floor", "floorf", "floorl", "ceil", "ceilf", "ceill",
-
-  // ctype.h
-  "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", "isprint"
-  "ispunct", "isspace", "isupper", "isxdigit", "tolower", "toupper",
-
-  // wctype.h"
-  "iswalnum", "iswalpha", "iswcntrl", "iswdigit", "iswgraph", "iswlower",
-  "iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit",
-
-  "iswctype", "towctrans", "towlower", "towupper",
-
-  "btowc", "wctob",
-
-  "isinf", "isnan", "finite",
-
-  // C99 math functions
-  "copysign", "copysignf", "copysignd",
-  "nexttoward", "nexttowardf", "nexttowardd",
-  "nextafter", "nextafterf", "nextafterd",
-
-  // ISO C99:
-  "__signbit", "__signbitf", "__signbitl",
-};
-
-
-static const char *OnlyReadsMemoryFns[] = {
-  "atoi", "atol", "atof", "atoll", "atoq", "a64l",
-  "bcmp", "memcmp", "memchr", "memrchr", "wmemcmp", "wmemchr",
-
-  // Strings
-  "strcmp", "strcasecmp", "strcoll", "strncmp", "strncasecmp",
-  "strchr", "strcspn", "strlen", "strpbrk", "strrchr", "strspn", "strstr",
-  "index", "rindex",
-
-  // Wide char strings
-  "wcschr", "wcscmp", "wcscoll", "wcscspn", "wcslen", "wcsncmp", "wcspbrk",
-  "wcsrchr", "wcsspn", "wcsstr",
-
-  // glibc
-  "alphasort", "alphasort64", "versionsort", "versionsort64",
-
-  // C99
-  "nan", "nanf", "nand",
-
-  // File I/O
-  "feof", "ferror", "fileno",
-  "feof_unlocked", "ferror_unlocked", "fileno_unlocked"
-};
-
-static ManagedStatic<std::vector<const char*> > NoMemoryTable;
-static ManagedStatic<std::vector<const char*> > OnlyReadsMemoryTable;
-
-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) {
-    NoMemoryTable->insert(NoMemoryTable->end(),
-                          DoesntAccessMemoryFns, 
-                          array_endof(DoesntAccessMemoryFns));
-
-    OnlyReadsMemoryTable->insert(OnlyReadsMemoryTable->end(),
-                                 OnlyReadsMemoryFns, 
-                                 array_endof(OnlyReadsMemoryFns));
-
-    // Sort the table the first time through.
-    std::sort(NoMemoryTable->begin(), NoMemoryTable->end(), StringCompare());
-    std::sort(OnlyReadsMemoryTable->begin(), OnlyReadsMemoryTable->end(),
-              StringCompare());
-    
-    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;
-  }
-  
-  ValueName *Name = F->getValueName();
-  if (!Name)
-    return UnknownModRefBehavior;
-  
-  unsigned NameLen = Name->getKeyLength();
-  const char *NamePtr = Name->getKeyData();
-  
-  // If there is an embedded nul character in the function name, we can never
-  // match it.
-  if (strlen(NamePtr) != NameLen)
-    return UnknownModRefBehavior;
-
-  std::vector<const char*>::iterator Ptr =
-    std::lower_bound(NoMemoryTable->begin(), NoMemoryTable->end(),
-                     NamePtr, StringCompare());
-  if (Ptr != NoMemoryTable->end() && strcmp(*Ptr, NamePtr) == 0)
-    return DoesNotAccessMemory;
-
-  Ptr = std::lower_bound(OnlyReadsMemoryTable->begin(),
-                         OnlyReadsMemoryTable->end(),
-                         NamePtr, StringCompare());
-  if (Ptr != OnlyReadsMemoryTable->end() && strcmp(*Ptr, NamePtr) == 0)
-    return OnlyReadsMemory;
-
-  const ParamAttrsList *Attrs = F->getFunctionType()->getParamAttrs();
-  if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadNone))
-    return DoesNotAccessMemory;
-  if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ReadOnly))
-    return OnlyReadsMemory;
-
-  return UnknownModRefBehavior;
-}
-
 // Make sure that anything that uses AliasAnalysis pulls in this file...
 DEFINING_FILE_FOR(BasicAliasAnalysis)