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

Chris Lattner sabre at nondot.org
Sat Dec 6 18:15:48 PST 2008


Author: lattner
Date: Sat Dec  6 20:15:47 2008
New Revision: 60649

URL: http://llvm.org/viewvc/llvm-project?rev=60649&view=rev
Log:
Introduce a new MemDep::getNonLocalPointerDependency
method.  This will eventually take over load/store dep
queries from getNonLocalDependency.  For now it works
fine, but is incredibly slow because it does no caching.
Lets not switch GVN to use it until that is fixed :)

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=60649&r1=60648&r2=60649&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/MemoryDependenceAnalysis.h Sat Dec  6 20:15:47 2008
@@ -214,6 +214,18 @@
     /// that.
     const NonLocalDepInfo &getNonLocalDependency(Instruction *QueryInst);
     
+    
+    /// getNonLocalPointerDependency - Perform a full dependency query for an
+    /// access to the specified (non-volatile) memory location, returning the
+    /// set of instructions that either define or clobber the value.
+    ///
+    /// This method assumes the pointer has a "NonLocal" dependency within BB
+    /// and assumes that Result is empty when you call it.
+    ///
+    void getNonLocalPointerDependency(Value *Pointer, bool isLoad,
+                                      BasicBlock *BB,
+                                     SmallVectorImpl<NonLocalDepEntry> &Result);
+    
     /// removeInstruction - Remove an instruction from the dependence analysis,
     /// updating the dependence of instructions that previously depended on it.
     void removeInstruction(Instruction *InstToRemove);

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

==============================================================================
--- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Sat Dec  6 20:15:47 2008
@@ -101,8 +101,11 @@
       return MemDepResult::getClobber(Inst);
   }
   
-  // No dependence found.
-  return MemDepResult::getNonLocal();
+  // No dependence found.  If this is the entry block of the function, it is a
+  // clobber, otherwise it is non-local.
+  if (BB != &BB->getParent()->getEntryBlock())
+    return MemDepResult::getNonLocal();
+  return MemDepResult::getClobber(ScanIt);
 }
 
 /// getPointerDependencyFrom - Return the instruction on which a memory
@@ -111,10 +114,7 @@
 MemDepResult MemoryDependenceAnalysis::
 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();
-  
+
   // Walk backwards through the basic block, looking for dependencies
   while (ScanIt != BB->begin()) {
     Instruction *Inst = --ScanIt;
@@ -174,8 +174,11 @@
     return MemDepResult::getClobber(Inst);
   }
   
-  // If we found nothing, return the non-local flag.
-  return MemDepResult::getNonLocal();
+  // No dependence found.  If this is the entry block of the function, it is a
+  // clobber, otherwise it is non-local.
+  if (BB != &BB->getParent()->getEntryBlock())
+    return MemDepResult::getNonLocal();
+  return MemDepResult::getClobber(ScanIt);
 }
 
 /// getDependency - Return the instruction on which a memory operation
@@ -209,8 +212,12 @@
   
   // Do the scan.
   if (BasicBlock::iterator(QueryInst) == QueryParent->begin()) {
-    // First instruction in the block -> non local.
-    LocalCache = MemDepResult::getNonLocal();
+    // No dependence found.  If this is the entry block of the function, it is a
+    // clobber, otherwise it is non-local.
+    if (QueryParent != &QueryParent->getParent()->getEntryBlock())
+      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.
@@ -264,6 +271,7 @@
 ///
 const MemoryDependenceAnalysis::NonLocalDepInfo &
 MemoryDependenceAnalysis::getNonLocalDependency(Instruction *QueryInst) {
+  // FIXME: Make this only be for callsites in the future.
   assert(isa<CallInst>(QueryInst) || isa<InvokeInst>(QueryInst) ||
          isa<LoadInst>(QueryInst) || isa<StoreInst>(QueryInst));
   assert(getDependency(QueryInst).isNonLocal() &&
@@ -359,9 +367,13 @@
     Value *MemPtr = 0;
     uint64_t MemSize = 0;
 
-    if (BasicBlock::iterator(QueryInst) == DirtyBB->begin()) {
-      // First instruction in the block -> non local.
-      Dep = MemDepResult::getNonLocal();
+    if (ScanPos == DirtyBB->begin()) {
+      // No dependence found.  If this is the entry block of the function, it is a
+      // clobber, otherwise it is non-local.
+      if (DirtyBB != &DirtyBB->getParent()->getEntryBlock())
+        Dep = MemDepResult::getNonLocal();
+      else
+        Dep = MemDepResult::getClobber(ScanPos);
     } 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.
@@ -415,6 +427,63 @@
   return Cache;
 }
 
+/// getNonLocalPointerDependency - Perform a full dependency query for an
+/// access to the specified (non-volatile) memory location, returning the
+/// set of instructions that either define or clobber the value.
+///
+/// This method assumes the pointer has a "NonLocal" dependency within its
+/// own block.
+///
+void MemoryDependenceAnalysis::
+getNonLocalPointerDependency(Value *Pointer, bool isLoad, BasicBlock *FromBB,
+                             SmallVectorImpl<NonLocalDepEntry> &Result) {
+  // We know that the pointer value is live into FromBB find the def/clobbers
+  // from presecessors.
+  SmallVector<std::pair<BasicBlock*, Value*>, 32> Worklist;
+  
+  for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E;
+       ++PI)
+    // TODO: PHI TRANSLATE.
+    Worklist.push_back(std::make_pair(*PI, Pointer));
+
+  const Type *EltTy = cast<PointerType>(Pointer->getType())->getElementType();
+  uint64_t PointeeSize = TD->getTypeStoreSize(EltTy);
+  
+  // While we have blocks to analyze, get their values.
+  SmallPtrSet<BasicBlock*, 64> Visited;
+  while (!Worklist.empty()) {
+    FromBB = Worklist.back().first;
+    Pointer = Worklist.back().second;
+    Worklist.pop_back();
+    
+    // Analyze the dependency of *Pointer in FromBB.  See if we already have
+    // been here.
+    if (!Visited.insert(FromBB))
+      continue;
+    
+    // FIXME: CACHE!
+    
+    MemDepResult Dep =
+      getPointerDependencyFrom(Pointer, PointeeSize, isLoad,
+                               FromBB->end(), FromBB);
+    
+    // If we got a Def or Clobber, add this to the list of results.
+    if (!Dep.isNonLocal()) {
+      Result.push_back(NonLocalDepEntry(FromBB, Dep));
+      continue;
+    }
+    
+    // Otherwise, we have to process all the predecessors of this block to scan
+    // them as well.
+    for (pred_iterator PI = pred_begin(FromBB), E = pred_end(FromBB); PI != E;
+         ++PI)
+      // TODO: PHI TRANSLATE.
+      Worklist.push_back(std::make_pair(*PI, Pointer));
+  }
+}
+
+
+
 /// 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