[llvm-commits] [llvm] r118723 - /llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp

Dan Gohman gohman at apple.com
Wed Nov 10 13:51:35 PST 2010


Author: djg
Date: Wed Nov 10 15:51:35 2010
New Revision: 118723

URL: http://llvm.org/viewvc/llvm-project?rev=118723&view=rev
Log:
Factor out the code for computing an AliasAnalysis::Location
for a given instruction into a helper function.

Modified:
    llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp

Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=118723&r1=118722&r2=118723&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Wed Nov 10 15:51:35 2010
@@ -102,6 +102,81 @@
     ReverseMap.erase(InstIt);
 }
 
+/// GetLocation - If the given instruction references a specific memory
+/// location, fill in Loc with the details, otherwise set Loc.Ptr to null.
+/// Return a ModRefInfo value describing the general behavior of the
+/// instruction.
+static
+AliasAnalysis::ModRefResult GetLocation(const Instruction *Inst,
+                                        AliasAnalysis::Location &Loc,
+                                        AliasAnalysis *AA) {
+  if (const LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
+    if (LI->isVolatile()) {
+      Loc = AliasAnalysis::Location();
+      return AliasAnalysis::ModRef;
+    }
+    Loc = AliasAnalysis::Location(LI->getPointerOperand(),
+                                  AA->getTypeStoreSize(LI->getType()),
+                                  LI->getMetadata(LLVMContext::MD_tbaa));
+    return AliasAnalysis::Ref;
+  }
+
+  if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
+    if (SI->isVolatile()) {
+      Loc = AliasAnalysis::Location();
+      return AliasAnalysis::ModRef;
+    }
+    Loc = AliasAnalysis::Location(SI->getPointerOperand(),
+                                  AA->getTypeStoreSize(SI->getValueOperand()
+                                                         ->getType()),
+                                  SI->getMetadata(LLVMContext::MD_tbaa));
+    return AliasAnalysis::Mod;
+  }
+
+  if (const VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
+    Loc = AliasAnalysis::Location(V->getPointerOperand(),
+                                  AA->getTypeStoreSize(V->getType()),
+                                  V->getMetadata(LLVMContext::MD_tbaa));
+    return AliasAnalysis::ModRef;
+  }
+
+  if (const CallInst *CI = isFreeCall(Inst)) {
+    // calls to free() deallocate the entire structure
+    Loc = AliasAnalysis::Location(CI->getArgOperand(0));
+    return AliasAnalysis::Mod;
+  }
+
+  if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst))
+    switch (II->getIntrinsicID()) {
+    case Intrinsic::lifetime_start:
+    case Intrinsic::lifetime_end:
+    case Intrinsic::invariant_start:
+      Loc = AliasAnalysis::Location(II->getArgOperand(1),
+                                    cast<ConstantInt>(II->getArgOperand(0))
+                                      ->getZExtValue(),
+                                    II->getMetadata(LLVMContext::MD_tbaa));
+      // These intrinsics don't really modify the memory, but returning Mod
+      // will allow them to be handled conservatively.
+      return AliasAnalysis::Mod;
+    case Intrinsic::invariant_end:
+      Loc = AliasAnalysis::Location(II->getArgOperand(2),
+                                    cast<ConstantInt>(II->getArgOperand(1))
+                                      ->getZExtValue(),
+                                    II->getMetadata(LLVMContext::MD_tbaa));
+      // These intrinsics don't really modify the memory, but returning Mod
+      // will allow them to be handled conservatively.
+      return AliasAnalysis::Mod;
+    default:
+      break;
+    }
+
+  // Otherwise, just do the coarse-grained thing that always works.
+  if (Inst->mayWriteToMemory())
+    return AliasAnalysis::ModRef;
+  if (Inst->mayReadFromMemory())
+    return AliasAnalysis::Ref;
+  return AliasAnalysis::NoModRef;
+}
 
 /// getCallSiteDependencyFrom - Private helper for finding the local
 /// dependencies of a call site.
@@ -114,19 +189,15 @@
     
     // If this inst is a memory op, get the pointer it accessed
     AliasAnalysis::Location Loc;
-    if (StoreInst *S = dyn_cast<StoreInst>(Inst)) {
-      Loc = AliasAnalysis::Location(S->getPointerOperand(),
-                                    AA->getTypeStoreSize(S->getValueOperand()
-                                                           ->getType()),
-                                    S->getMetadata(LLVMContext::MD_tbaa));
-    } else if (VAArgInst *V = dyn_cast<VAArgInst>(Inst)) {
-      Loc = AliasAnalysis::Location(V->getPointerOperand(),
-                                    AA->getTypeStoreSize(V->getType()),
-                                    V->getMetadata(LLVMContext::MD_tbaa));
-    } else if (const CallInst *CI = isFreeCall(Inst)) {
-      // calls to free() erase the entire structure
-      Loc = AliasAnalysis::Location(CI->getArgOperand(0));
-    } else if (CallSite InstCS = cast<Value>(Inst)) {
+    AliasAnalysis::ModRefResult MR = GetLocation(Inst, Loc, AA);
+    if (Loc.Ptr) {
+      // A simple instruction.
+      if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef)
+        return MemDepResult::getClobber(Inst);
+      continue;
+    }
+
+    if (CallSite InstCS = cast<Value>(Inst)) {
       // Debug intrinsics don't cause dependences.
       if (isa<DbgInfoIntrinsic>(Inst)) continue;
       // If these two calls do not interfere, look past it.
@@ -134,23 +205,17 @@
       case AliasAnalysis::NoModRef:
         // If the two calls are the same, return InstCS as a Def, so that
         // CS can be found redundant and eliminated.
-        if (isReadOnlyCall && InstCS.onlyReadsMemory() &&
+        if (isReadOnlyCall && !(MR & AliasAnalysis::Mod) &&
             CS.getInstruction()->isIdenticalToWhenDefined(Inst))
           return MemDepResult::getDef(Inst);
 
         // Otherwise if the two calls don't interact (e.g. InstCS is readnone)
         // keep scanning.
-        continue;
+        break;
       default:
         return MemDepResult::getClobber(Inst);
       }
-    } else {
-      // Non-memory instruction.
-      continue;
     }
-    
-    if (AA->getModRefInfo(CS, Loc) != AliasAnalysis::NoModRef)
-      return MemDepResult::getClobber(Inst);
   }
   
   // No dependence found.  If this is the entry block of the function, it is a
@@ -344,8 +409,6 @@
   
   BasicBlock *QueryParent = QueryInst->getParent();
   
-  AliasAnalysis::Location MemLoc;
-  
   // Do the scan.
   if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
     // No dependence found.  If this is the entry block of the function, it is a
@@ -354,69 +417,25 @@
       LocalCache = MemDepResult::getNonLocal();
     else
       LocalCache = MemDepResult::getClobber(QueryInst);
-  } else if (StoreInst *SI = dyn_cast<StoreInst>(QueryInst)) {
-    // If this is a volatile store, don't mess around with it.  Just return the
-    // previous instruction as a clobber.
-    if (SI->isVolatile())
-      LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
-    else
-      MemLoc = AliasAnalysis::Location(SI->getPointerOperand(),
-                                       AA->getTypeStoreSize(SI->getOperand(0)
-                                                              ->getType()),
-                                       SI->getMetadata(LLVMContext::MD_tbaa));
-  } else if (LoadInst *LI = dyn_cast<LoadInst>(QueryInst)) {
-    // If this is a volatile load, don't mess around with it.  Just return the
-    // previous instruction as a clobber.
-    if (LI->isVolatile())
-      LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
-    else
-      MemLoc = AliasAnalysis::Location(LI->getPointerOperand(),
-                                       AA->getTypeStoreSize(LI->getType()),
-                                       LI->getMetadata(LLVMContext::MD_tbaa));
-  } else if (const CallInst *CI = isFreeCall(QueryInst)) {
-    // calls to free() erase the entire structure, not just a field.
-    MemLoc = AliasAnalysis::Location(CI->getArgOperand(0));
-  } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
-    int IntrinsicID = 0;  // Intrinsic IDs start at 1.
-    IntrinsicInst *II = dyn_cast<IntrinsicInst>(QueryInst);
-    if (II)
-      IntrinsicID = II->getIntrinsicID();
-
-    switch (IntrinsicID) {
-    case Intrinsic::lifetime_start:
-    case Intrinsic::lifetime_end:
-    case Intrinsic::invariant_start:
-      MemLoc = AliasAnalysis::Location(II->getArgOperand(1),
-                                       cast<ConstantInt>(II->getArgOperand(0))
-                                         ->getZExtValue(),
-                                       II->getMetadata(LLVMContext::MD_tbaa));
-      break;
-    case Intrinsic::invariant_end:
-      MemLoc = AliasAnalysis::Location(II->getArgOperand(2),
-                                       cast<ConstantInt>(II->getArgOperand(1))
-                                         ->getZExtValue(),
-                                       II->getMetadata(LLVMContext::MD_tbaa));
-      break;
-    default:
+  } else {
+    AliasAnalysis::Location MemLoc;
+    AliasAnalysis::ModRefResult MR = GetLocation(QueryInst, MemLoc, AA);
+    if (MemLoc.Ptr) {
+      // If we can do a pointer scan, make it happen.
+      bool isLoad = !(MR & AliasAnalysis::Mod);
+      if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
+        isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
+      }
+      LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
+                                            QueryParent);
+    } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
       CallSite QueryCS(QueryInst);
       bool isReadOnly = AA->onlyReadsMemory(QueryCS);
       LocalCache = getCallSiteDependencyFrom(QueryCS, isReadOnly, ScanPos,
                                              QueryParent);
-      break;
-    }
-  } else {
-    // Non-memory instruction.
-    LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
-  }
-  
-  // If we need to do a pointer scan, make it happen.
-  if (MemLoc.Ptr) {
-    bool isLoad = !QueryInst->mayWriteToMemory();
-    if (IntrinsicInst *II = dyn_cast<MemoryUseIntrinsic>(QueryInst)) {
-      isLoad |= II->getIntrinsicID() == Intrinsic::lifetime_end;
-    }
-    LocalCache = getPointerDependencyFrom(MemLoc, isLoad, ScanPos,
-                                          QueryParent);
+    } else
+      // Non-memory instruction.
+      LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
   }
   
   // Remember the result!





More information about the llvm-commits mailing list