Modified Deserializer::ReadCStr to allow C-strings to be read into a
[oota-llvm.git] / lib / Analysis / BasicAliasAnalysis.cpp
index ffe7411b778e12a449e5ed2c74521f4493f92932..7ce9d1651f73c25a422f8ec31e8e7cb5792428e4 100644 (file)
 #include "llvm/ParameterAttributes.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
 #include "llvm/Pass.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/ManagedStatic.h"
@@ -112,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
@@ -217,6 +216,7 @@ static bool AddressMightEscape(const Value *V) {
     case Instruction::GetElementPtr:
       if (AddressMightEscape(I))
         return true;
+      break; // next use.
     case Instruction::BitCast:
       if (!isa<PointerType>(I->getType()))
         return true;
@@ -261,6 +261,21 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
   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.  :)
@@ -295,50 +310,37 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
 
   // Pointing at a discernible object?
   if (O1) {
-    // Check for noalias attribute
-    if (isa<Argument>(O1)) {
-      const Argument *Arg = cast<Argument>(O1);
-      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 NoAlias;
-        }
-      }
-    }
     if (O2) {
-      if (isa<Argument>(O1)) {
+      if (const Argument *O1Arg = dyn_cast<Argument>(O1)) {
         // Incoming argument cannot alias locally allocated object!
         if (isa<AllocationInst>(O2)) return NoAlias;
+        
+        // If they are two different objects, and one is a noalias argument
+        // then they do not alias.
+        if (O1 != O2 && isNoAliasArgument(O1Arg))
+          return NoAlias;
+          
         // Otherwise, nothing is known...
-      } else if (isa<Argument>(O2)) {
+      } 
+      
+      if (const Argument *O2Arg = dyn_cast<Argument>(O2)) {
         // Incoming argument cannot alias locally allocated object!
         if (isa<AllocationInst>(O1)) return NoAlias;
+        
+        // If they are two different objects, and one is a noalias argument
+        // then they do not alias.
+        if (O1 != O2 && isNoAliasArgument(O2Arg))
+          return NoAlias;
+          
         // Otherwise, nothing is known...
-      } else if (O1 != O2) {
-        // If they are two different objects, we know that we have no alias...
-        return NoAlias;
-      }
       
-      // Check for noalias atrribute independently from above logic
-      if (isa<Argument>(O2)) {
-        const Argument *Arg = cast<Argument>(O2);
-        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 NoAlias;
-          }
-        }
+      } 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;
       }
+
       // If they are the same object, they we can look at the indexes.  If they
       // index off of the object is the same for both pointers, they must alias.
       // If they are provably different, they must not alias.  Otherwise, we
@@ -357,7 +359,7 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
         // global/alloca/malloc, it cannot be accessing the global (it's
         // undefined to load or store bytes before or after an object).
         const Type *ElTy = cast<PointerType>(O1->getType())->getElementType();
-        unsigned GlobalSize = getTargetData().getTypeSize(ElTy);
+        unsigned GlobalSize = getTargetData().getABITypeSize(ElTy);
         if (GlobalSize < V2Size && V2Size != ~0U)
           return NoAlias;
       }
@@ -375,7 +377,7 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
         // global/alloca/malloc, it cannot be accessing the object (it's
         // undefined to load or store bytes before or after an object).
         const Type *ElTy = cast<PointerType>(O2->getType())->getElementType();
-        unsigned GlobalSize = getTargetData().getTypeSize(ElTy);
+        unsigned GlobalSize = getTargetData().getABITypeSize(ElTy);
         if (GlobalSize < V1Size && V1Size != ~0U)
           return NoAlias;
       }
@@ -389,17 +391,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);
@@ -728,8 +732,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
           }
           
@@ -746,20 +750,19 @@ BasicAliasAnalysis::CheckGEPInstructions(
           //
           if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty))
             GEP1Ops[i] = ConstantInt::get(Type::Int64Ty,AT->getNumElements()-1);
-          else if (const VectorType *PT = dyn_cast<VectorType>(BasePtr1Ty))
-            GEP1Ops[i] = ConstantInt::get(Type::Int64Ty,PT->getNumElements()-1);
-
+          else if (const VectorType *VT = dyn_cast<VectorType>(BasePtr1Ty))
+            GEP1Ops[i] = ConstantInt::get(Type::Int64Ty,VT->getNumElements()-1);
         }
       }
 
       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 *PT = dyn_cast<VectorType>(BasePtr1Ty)) {
-            if (Op2C->getZExtValue() >= PT->getNumElements())
+          } else if (const VectorType *VT = dyn_cast<VectorType>(BasePtr2Ty)) {
+            if (Op2C->getZExtValue() >= VT->getNumElements())
               return MayAlias;  // Be conservative with out-of-range accesses
           }
         } else {  // Conservatively assume the minimum value for this index
@@ -788,8 +791,13 @@ BasicAliasAnalysis::CheckGEPInstructions(
       getTargetData().getIndexedOffset(GEPPointerTy, GEP1Ops, NumGEP1Ops);
     int64_t Offset2 = 
       getTargetData().getIndexedOffset(GEPPointerTy, GEP2Ops, NumGEP2Ops);
-    assert(Offset1<Offset2 && "There is at least one different constant here!");
-
+    assert(Offset1 != Offset2 &&
+           "There is at least one different constant here!");
+    
+    // Make sure we compare the absolute difference.
+    if (Offset1 > Offset2)
+      std::swap(Offset1, Offset2);
+    
     if ((uint64_t)(Offset2-Offset1) >= SizeMax) {
       //cerr << "Determined that these two GEP's don't alias ["
       //     << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
@@ -799,123 +807,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;
-
-
-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, 
-                          DoesntAccessMemoryFns+
-                sizeof(DoesntAccessMemoryFns)/sizeof(DoesntAccessMemoryFns[0]));
-
-    OnlyReadsMemoryTable->insert(OnlyReadsMemoryTable->end(),
-                                OnlyReadsMemoryFns, 
-                                OnlyReadsMemoryFns+
-                      sizeof(OnlyReadsMemoryFns)/sizeof(OnlyReadsMemoryFns[0]));
-#define GET_MODREF_BEHAVIOR
-#include "llvm/Intrinsics.gen"
-#undef GET_MODREF_BEHAVIOR
-    
-    // Sort the table the first time through.
-    std::sort(NoMemoryTable->begin(), NoMemoryTable->end(), StringCompare());
-    std::sort(OnlyReadsMemoryTable->begin(), OnlyReadsMemoryTable->end(),
-              StringCompare());
-    Initialized = true;
-  }
-
-  std::vector<const char*>::iterator Ptr =
-    std::lower_bound(NoMemoryTable->begin(), NoMemoryTable->end(),
-                     F->getName().c_str(), StringCompare());
-  if (Ptr != NoMemoryTable->end() && *Ptr == F->getName())
-    return DoesNotAccessMemory;
-
-  Ptr = std::lower_bound(OnlyReadsMemoryTable->begin(),
-                         OnlyReadsMemoryTable->end(),
-                         F->getName().c_str(), StringCompare());
-  if (Ptr != OnlyReadsMemoryTable->end() && *Ptr == F->getName())
-    return OnlyReadsMemory;
-
-  return UnknownModRefBehavior;
-}
-
 // Make sure that anything that uses AliasAnalysis pulls in this file...
 DEFINING_FILE_FOR(BasicAliasAnalysis)