don't repeat function names in comments; NFC
[oota-llvm.git] / lib / Analysis / GlobalsModRef.cpp
index 3b808e371dbcce268c5100f3bc0e231021252633..ab2263ae374e6e7a9e835842533db79946deba22 100644 (file)
@@ -353,12 +353,12 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
     } else if (auto CS = CallSite(I)) {
       // Make sure that this is just the function being called, not that it is
       // passing into the function.
-      if (!CS.isCallee(&U)) {
+      if (CS.isDataOperand(&U)) {
         // Detect calls to free.
-        if (isFreeCall(I, &TLI)) {
+        if (CS.isArgOperand(&U) && isFreeCall(I, &TLI)) {
           if (Writers)
             Writers->insert(CS->getParent()->getParent());
-        } else if (CS.doesNotCapture(CS.getArgumentNo(&U))) {
+        } else if (CS.doesNotCapture(CS.getDataOperandNo(&U))) {
           Function *ParentF = CS->getParent()->getParent();
           // A nocapture argument may be read from or written to, but does not
           // escape unless the call can somehow recurse.
@@ -376,6 +376,15 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
         } else {
           return true; // Argument of an unknown call.
         }
+        // If the Callee is not ReadNone, it may read the global,
+        // and if it is not ReadOnly, it may also write to it.
+        Function *CalleeF = CS.getCalledFunction();
+        if (!CalleeF->doesNotAccessMemory()) {
+          if (Readers)
+            Readers->insert(CalleeF);
+          if (Writers && !CalleeF->onlyReadsMemory())
+            Writers->insert(CalleeF);
+        }
       }
     } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(I)) {
       if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
@@ -395,11 +404,16 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
 /// Further, all loads out of GV must directly use the memory, not store the
 /// pointer somewhere.  If this is true, we consider the memory pointed to by
 /// GV to be owned by GV and can disambiguate other pointers from it.
-bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
+bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {
   // Keep track of values related to the allocation of the memory, f.e. the
   // value produced by the malloc call and any casts.
   std::vector<Value *> AllocRelatedValues;
 
+  // If the initializer is a valid pointer, bail.
+  if (Constant *C = GV->getInitializer())
+    if (!C->isNullValue())
+      return false;
+    
   // Walk the user list of the global.  If we find anything other than a direct
   // load or store, bail out.
   for (User *U : GV->users()) {
@@ -502,7 +516,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
 
       if (F->isDeclaration()) {
         // Try to get mod/ref behaviour from function attributes.
-        if (F->doesNotAccessMemory()) {
+        if (F->doesNotAccessMemory() || F->onlyAccessesInaccessibleMemory()) {
           // Can't do better than that!
         } else if (F->onlyReadsMemory()) {
           FI.addModRefInfo(MRI_Ref);
@@ -510,6 +524,12 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
             // This function might call back into the module and read a global -
             // consider every global as possibly being read by this function.
             FI.setMayReadAnyGlobal();
+        } else if (F->onlyAccessesArgMemory() || 
+                   F->onlyAccessesInaccessibleMemOrArgMem()) {
+          // This function may only access (read/write) memory pointed to by its
+          // arguments. If this pointer is to a global, this escaping use of the
+          // pointer is captured in AnalyzeUsesOfPointer().
+          FI.addModRefInfo(MRI_ModRef);
         } else {
           FI.addModRefInfo(MRI_ModRef);
           // Can't say anything useful unless it's an intrinsic - they don't
@@ -873,9 +893,7 @@ ModRefInfo GlobalsAAResult::getModRefInfoForArgument(ImmutableCallSite CS,
     GetUnderlyingObjects(A, Objects, DL);
     
     // All objects must be identified.
-    if (!std::all_of(Objects.begin(), Objects.end(), [&GV](const Value *V) {
-          return isIdentifiedObject(V);
-        }))
+    if (!std::all_of(Objects.begin(), Objects.end(), isIdentifiedObject))
       return ConservativeResult;
 
     if (std::find(Objects.begin(), Objects.end(), GV) != Objects.end())