[llvm-commits] CVS: llvm/lib/Analysis/LoadValueNumbering.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Jan 28 23:04:25 PST 2005



Changes in directory llvm/lib/Analysis:

LoadValueNumbering.cpp updated: 1.29 -> 1.30
---
Log message:

Due to previous simplifications, we can simplify the data structures being
used here.


---
Diffs of the changes:  (+36 -35)

 LoadValueNumbering.cpp |   71 ++++++++++++++++++++++++-------------------------
 1 files changed, 36 insertions(+), 35 deletions(-)


Index: llvm/lib/Analysis/LoadValueNumbering.cpp
diff -u llvm/lib/Analysis/LoadValueNumbering.cpp:1.29 llvm/lib/Analysis/LoadValueNumbering.cpp:1.30
--- llvm/lib/Analysis/LoadValueNumbering.cpp:1.29	Sat Jan 29 00:42:34 2005
+++ llvm/lib/Analysis/LoadValueNumbering.cpp	Sat Jan 29 01:04:10 2005
@@ -316,7 +316,7 @@
       if (LI->getOperand(0) == LoadPtr && !LI->isVolatile())
         RetVals.push_back(I);
     }
-    
+
     if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
       // If the invalidating instruction is a store, and its in our candidate
       // set, then we can do store-load forwarding: the load has the same value
@@ -352,12 +352,12 @@
   if (LoadInvalidatedInBBBefore && LoadInvalidatedInBBAfter)
     return;
   
-  // Now that we know the set of equivalent source pointers for the load
-  // instruction, look to see if there are any load or store candidates that are
-  // identical.
+  // Now that we know the value is not neccesarily killed on entry or exit to
+  // the BB, find out how many load and store instructions (to this location)
+  // live in each BB in the function.
   //
-  std::map<BasicBlock*, std::vector<LoadInst*> >  CandidateLoads;
-  std::map<BasicBlock*, std::vector<StoreInst*> > CandidateStores;
+  std::map<BasicBlock*, unsigned>  CandidateLoads;
+  std::set<BasicBlock*> CandidateStores;
     
   for (Value::use_iterator UI = LoadPtr->use_begin(), UE = LoadPtr->use_end();
        UI != UE; ++UI)
@@ -365,19 +365,16 @@
       if (Cand->getParent()->getParent() == F &&   // In the same function?
           // Not in LI's block?
           Cand->getParent() != LoadBB && !Cand->isVolatile())
-        CandidateLoads[Cand->getParent()].push_back(Cand);     // Got one...
+        ++CandidateLoads[Cand->getParent()];       // Got one.
     } else if (StoreInst *Cand = dyn_cast<StoreInst>(*UI)) {
       if (Cand->getParent()->getParent() == F && !Cand->isVolatile() &&
-          Cand->getParent() != LoadBB &&
           Cand->getOperand(1) == LoadPtr) // It's a store THROUGH the ptr.
-        CandidateStores[Cand->getParent()].push_back(Cand);
+        CandidateStores.insert(Cand->getParent());
     }
-  
+
   // Get dominators.
   DominatorSet &DomSetInfo = getAnalysis<DominatorSet>();
 
-  std::set<Instruction*> Instrs;
-
   // TransparentBlocks - For each basic block the load/store is alive across,
   // figure out if the pointer is invalidated or not.  If it is invalidated, the
   // boolean is set to false, if it's not it is set to true.  If we don't know
@@ -388,7 +385,7 @@
   // is live across the CFG from the source to destination blocks, and if the
   // value is not invalidated in either the source or destination blocks, add it
   // to the equivalence sets.
-  for (std::map<BasicBlock*, std::vector<LoadInst*> >::iterator
+  for (std::map<BasicBlock*, unsigned>::iterator
          I = CandidateLoads.begin(), E = CandidateLoads.end(); I != E; ++I) {
     bool CantEqual = false;
 
@@ -430,18 +427,19 @@
     // For any loads that are not invalidated, add them to the equivalence
     // set!
     if (!CantEqual) {
-      Instrs.insert(I->second.begin(), I->second.end());
+      unsigned NumLoads = I->second;
       if (BB1 == LoadBB) {
         // If LI dominates the block in question, check to see if any of the
         // loads in this block are invalidated before they are reached.
         for (BasicBlock::iterator BBI = I->first->begin(); ; ++BBI) {
-          if (isa<LoadInst>(BBI) && Instrs.count(BBI)) {
-            // The load is in the set!
-            RetVals.push_back(BBI);
-            Instrs.erase(BBI);
-            if (Instrs.empty()) break;
+          if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+            if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) {
+              // The load is in the set!
+              RetVals.push_back(BBI);
+              if (--NumLoads == 0) break;  // Found last load to check.
+            }
           } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize)
-                             & AliasAnalysis::Mod) {
+                                & AliasAnalysis::Mod) {
             // If there is a modifying instruction, nothing below it will value
             // # the same.
             break;
@@ -453,11 +451,12 @@
         BasicBlock::iterator BBI = I->first->end();
         while (1) {
           --BBI;
-          if (isa<LoadInst>(BBI) && Instrs.count(BBI)) {
-            // The load is in the set!
-            RetVals.push_back(BBI);
-            Instrs.erase(BBI);
-            if (Instrs.empty()) break;
+          if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+            if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) {
+              // The load is the same as this load!
+              RetVals.push_back(BBI);
+              if (--NumLoads == 0) break;  // Found all of the laods.
+            }
           } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize)
                              & AliasAnalysis::Mod) {
             // If there is a modifying instruction, nothing above it will value
@@ -466,8 +465,6 @@
           }
         }
       }
-
-      Instrs.clear();
     }
   }
 
@@ -477,16 +474,21 @@
   if (LoadInvalidatedInBBBefore)
     return;
 
-  for (std::map<BasicBlock*, std::vector<StoreInst*> >::iterator
-         I = CandidateStores.begin(), E = CandidateStores.end(); I != E; ++I)
-    if (DomSetInfo.dominates(I->first, LoadBB)) {
+  // Stores in the load-bb are handled above.
+  CandidateStores.erase(LoadBB);
+  
+  for (std::set<BasicBlock*>::iterator I = CandidateStores.begin(),
+         E = CandidateStores.end(); I != E; ++I)
+    if (DomSetInfo.dominates(*I, LoadBB)) {
+      BasicBlock *StoreBB = *I;
+
       // Check to see if the path from the store to the load is transparent
       // w.r.t. the memory location.
       bool CantEqual = false;
       std::set<BasicBlock*> Visited;
       for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
            PI != E; ++PI)
-        if (!isPathTransparentTo(*PI, I->first, LoadPtr, LoadSize, AA,
+        if (!isPathTransparentTo(*PI, StoreBB, LoadPtr, LoadSize, AA,
                                  Visited, TransparentBlocks)) {
           // None of these stores can VN the same.
           CantEqual = true;
@@ -499,9 +501,9 @@
         // of the load block to the load itself.  Now we just scan the store
         // block.
 
-        BasicBlock::iterator BBI = I->first->end();
+        BasicBlock::iterator BBI = StoreBB->end();
         while (1) {
-          assert(BBI != I->first->begin() &&
+          assert(BBI != StoreBB->begin() &&
                  "There is a store in this block of the pointer, but the store"
                  " doesn't mod the address being stored to??  Must be a bug in"
                  " the alias analysis implementation!");
@@ -510,8 +512,7 @@
             // If the invalidating instruction is one of the candidates,
             // then it provides the value the load loads.
             if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
-              if (std::find(I->second.begin(), I->second.end(), SI) !=
-                  I->second.end())
+              if (SI->getOperand(1) == LoadPtr)
                 RetVals.push_back(SI->getOperand(0));
             break;
           }






More information about the llvm-commits mailing list