[llvm-commits] [llvm] r60648 - in /llvm/trunk: include/llvm/Analysis/MemoryDependenceAnalysis.h lib/Analysis/MemoryDependenceAnalysis.cpp

Chris Lattner sabre at nondot.org
Sat Dec 6 17:50:17 PST 2008


Author: lattner
Date: Sat Dec  6 19:50:16 2008
New Revision: 60648

URL: http://llvm.org/viewvc/llvm-project?rev=60648&view=rev
Log:
push the "pointer case" up the analysis stack a bit.  This causes 
duplication of logic (in 2 places) to determine what pointer a 
load/store touches.  This will be addressed in a future commit.

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

Modified: llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h?rev=60648&r1=60647&r2=60648&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec  6 19:50:16 2008
@@ -220,11 +220,13 @@
     
   private:
     
-    /// getDependencyFrom - Return the instruction on which the memory operation
-    /// 'QueryInst' depends.  This starts scanning from the instruction before
+    /// getDependencyFrom - Return the instruction on which the memory location
+    /// '*Pointer' depends.  This starts scanning from the instruction before
     /// the position indicated by ScanIt.
-    MemDepResult getDependencyFrom(Instruction *QueryInst,
-                                   BasicBlock::iterator ScanIt, BasicBlock *BB);
+    MemDepResult getPointerDependencyFrom(Value *Pointer, uint64_t MemSize,
+                                          bool isLoad, 
+                                          BasicBlock::iterator ScanIt,
+                                          BasicBlock *BB);
     MemDepResult getCallSiteDependencyFrom(CallSite C,
                                            BasicBlock::iterator ScanIt,
                                            BasicBlock *BB);

Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=60648&r1=60647&r2=60648&view=diff

==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec  6 19:50:16 2008
@@ -105,48 +105,16 @@
   return MemDepResult::getNonLocal();
 }
 
-/// getDependencyFrom - Return the instruction on which a memory operation
-/// depends.
+/// getPointerDependencyFrom - Return the instruction on which a memory
+/// location depends.  If isLoad is true, this routine ignore may-aliases with
+/// read-only operations.
 MemDepResult MemoryDependenceAnalysis::
-getDependencyFrom(Instruction *QueryInst, BasicBlock::iterator ScanIt, 
-                  BasicBlock *BB) {
+getPointerDependencyFrom(Value *MemPtr, uint64_t MemSize, bool isLoad,
+                         BasicBlock::iterator ScanIt, BasicBlock *BB) {
   // The first instruction in a block is always non-local.
   if (ScanIt == BB->begin())
     return MemDepResult::getNonLocal();
   
-  // Get the pointer value for which dependence will be determined
-  Value *MemPtr = 0;
-  uint64_t MemSize = 0;
-  
-  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())
-      return MemDepResult::getClobber(--ScanIt);
-
-    MemPtr = SI->getPointerOperand();
-    MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
-  } 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())
-      return MemDepResult::getClobber(--ScanIt);
-    
-    MemPtr = LI->getPointerOperand();
-    MemSize = TD->getTypeStoreSize(LI->getType());
-  } else if (FreeInst *FI = dyn_cast<FreeInst>(QueryInst)) {
-    MemPtr = FI->getPointerOperand();
-    // FreeInsts erase the entire structure, not just a field.
-    MemSize = ~0UL;
-  } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
-    assert(0 && "Should use getCallSiteDependencyFrom!");
-    return getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanIt, BB);
-  } else {
-    // Otherwise, this is a vaarg or non-memory instruction, just return a
-    // clobber dependency on the previous inst.
-    return MemDepResult::getClobber(--ScanIt);
-  }
-  
   // Walk backwards through the basic block, looking for dependencies
   while (ScanIt != BB->begin()) {
     Instruction *Inst = --ScanIt;
@@ -164,7 +132,7 @@
         continue;
       
       // May-alias loads don't depend on each other without a dependence.
-      if (isa<LoadInst>(QueryInst) && R == AliasAnalysis::MayAlias)
+      if (isLoad && R == AliasAnalysis::MayAlias)
         continue;
       return MemDepResult::getDef(Inst);
     }
@@ -198,6 +166,7 @@
     }
     
     // See if this instruction (e.g. a call or vaarg) mod/ref's the pointer.
+    // FIXME: If this is a load, we should ignore readonly calls!
     if (AA->getModRefInfo(Inst, MemPtr, MemSize) == AliasAnalysis::NoModRef)
       continue;
     
@@ -233,12 +202,50 @@
       ReverseLocalDeps.erase(Inst);
   }
   
+  BasicBlock *QueryParent = QueryInst->getParent();
+  
+  Value *MemPtr = 0;
+  uint64_t MemSize = 0;
+  
   // Do the scan.
-  if (!isa<CallInst>(QueryInst) && !isa<InvokeInst>(QueryInst))
-    LocalCache = getDependencyFrom(QueryInst, ScanPos, QueryInst->getParent());
-  else 
+  if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
+    // First instruction in the block -> non local.
+    LocalCache = MemDepResult::getNonLocal();
+  } 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 {
+      MemPtr = SI->getPointerOperand();
+      MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
+    }
+  } 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 {
+      MemPtr = LI->getPointerOperand();
+      MemSize = TD->getTypeStoreSize(LI->getType());
+    }
+  } else if (isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst)) {
     LocalCache = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos,
-                                           QueryInst->getParent());
+                                           QueryParent);
+  } else if (FreeInst *FI = dyn_cast<FreeInst>(QueryInst)) {
+    MemPtr = FI->getPointerOperand();
+    // FreeInsts erase the entire structure, not just a field.
+    MemSize = ~0UL;
+  } else {
+    // Non-memory instruction.
+    LocalCache = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
+  }
+  
+  // If we need to do a pointer scan, make it happen.
+  if (MemPtr)
+    LocalCache = getPointerDependencyFrom(MemPtr, MemSize, 
+                                          isa<LoadInst>(QueryInst),
+                                          ScanPos, QueryParent);
   
   // Remember the result!
   if (Instruction *I = LocalCache.getInst())
@@ -257,10 +264,11 @@
 ///
 const MemoryDependenceAnalysis::NonLocalDepInfo &
 MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) {
+  assert(isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst) ||
+         isa<LoadInst>(QueryInst) || isa<StoreInst>(QueryInst));
   assert(getDependency(QueryInst).isNonLocal() &&
      "getNonLocalDependency should only be used on insts with non-local deps!");
   PerInstNLInfo &CacheP = NonLocalDeps[QueryInst];
-  
   NonLocalDepInfo &Cache = CacheP.first;
 
   /// DirtyBlocks - This is the set of blocks that need to be recomputed.  In
@@ -347,11 +355,40 @@
     
     // Find out if this block has a local dependency for QueryInst.
     MemDepResult Dep;
-    if (!isa<CallInst>(QueryInst) && !isa<InvokeInst>(QueryInst))
-      Dep = getDependencyFrom(QueryInst, ScanPos, DirtyBB);
-    else 
+    
+    Value *MemPtr = 0;
+    uint64_t MemSize = 0;
+
+    if (BasicBlock::iterator(QueryInst) == DirtyBB->begin()) {
+      // First instruction in the block -> non local.
+      Dep = MemDepResult::getNonLocal();
+    } 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())
+        Dep = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
+      else {
+        MemPtr = SI->getPointerOperand();
+        MemSize = TD->getTypeStoreSize(SI->getOperand(0)->getType());
+      }
+    } 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())
+        Dep = MemDepResult::getClobber(--BasicBlock::iterator(ScanPos));
+      else {
+        MemPtr = LI->getPointerOperand();
+        MemSize = TD->getTypeStoreSize(LI->getType());
+      }
+    } else {
+      assert(isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst));
       Dep = getCallSiteDependencyFrom(CallSite::get(QueryInst), ScanPos,
                                       DirtyBB);
+    }
+    
+    if (MemPtr)
+      Dep = getPointerDependencyFrom(MemPtr, MemSize, isa<LoadInst>(QueryInst),
+                                     ScanPos, DirtyBB);
     
     // If we had a dirty entry for the block, update it.  Otherwise, just add
     // a new entry.
@@ -378,7 +415,6 @@
   return Cache;
 }
 
-
 /// removeInstruction - Remove an instruction from the dependence analysis,
 /// updating the dependence of instructions that previously depended on it.
 /// This method attempts to keep the cache coherent using the reverse map.





More information about the llvm-commits mailing list