[llvm-commits] CVS: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Nov 17 23:31:54 PST 2005



Changes in directory llvm/lib/Transforms/Utils:

PromoteMemoryToRegister.cpp updated: 1.81 -> 1.82
---
Log message:

Implement a refinement to the mem2reg algorithm for cases where an alloca
has a single def.  In this case, look for uses that are dominated by the def
and attempt to rewrite them to directly use the stored value.

This speeds up mem2reg on these values and reduces the number of phi nodes
inserted.  This should address PR665: http://llvm.cs.uiuc.edu/PR665 .


---
Diffs of the changes:  (+55 -0)

 PromoteMemoryToRegister.cpp |   55 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+)


Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.81 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.82
--- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.81	Fri Nov 18 01:29:44 2005
+++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp	Fri Nov 18 01:31:42 2005
@@ -161,6 +161,7 @@
     std::vector<BasicBlock*> DefiningBlocks;
     std::vector<BasicBlock*> UsingBlocks;
 
+    StoreInst  *OnlyStore = 0;
     BasicBlock *OnlyBlock = 0;
     bool OnlyUsedInOneBlock = true;
 
@@ -174,6 +175,7 @@
         // Remember the basic blocks which define new values for the alloca
         DefiningBlocks.push_back(SI->getParent());
         AllocaPointerVal = SI->getOperand(0);
+        OnlyStore = SI;
       } else {
         LoadInst *LI = cast<LoadInst>(User);
         // Otherwise it must be a load instruction, keep track of variable reads
@@ -201,6 +203,59 @@
       continue;
     }
 
+    // If there is only a single store to this value, replace any loads of
+    // it that are directly dominated by the definition with the value stored.
+    if (DefiningBlocks.size() == 1) {
+      // Be aware of loads before the store.
+      std::set<BasicBlock*> ProcessedBlocks;
+      for (unsigned i = 0, e = UsingBlocks.size(); i != e; ++i)
+        // If the store dominates the block and if we haven't processed it yet,
+        // do so now.
+        if (dominates(OnlyStore->getParent(), UsingBlocks[i]))
+          if (ProcessedBlocks.insert(UsingBlocks[i]).second) {
+            BasicBlock *UseBlock = UsingBlocks[i];
+            
+            // If the use and store are in the same block, do a quick scan to
+            // verify that there are no uses before the store.
+            if (UseBlock == OnlyStore->getParent()) {
+              BasicBlock::iterator I = UseBlock->begin();
+              for (; &*I != OnlyStore; ++I) { // scan block for store.
+                if (isa<LoadInst>(I) && I->getOperand(0) == AI)
+                  break;
+              }
+              if (&*I != OnlyStore) break;  // Do not handle this case.
+            }
+        
+            // Otherwise, if this is a different block or if all uses happen
+            // after the store, do a simple linear scan to replace loads with
+            // the stored value.
+            for (BasicBlock::iterator I = UseBlock->begin(),E = UseBlock->end();
+                 I != E; ) {
+              if (LoadInst *LI = dyn_cast<LoadInst>(I++)) {
+                if (LI->getOperand(0) == AI) {
+                  LI->replaceAllUsesWith(OnlyStore->getOperand(0));
+                  if (AST && isa<PointerType>(LI->getType()))
+                    AST->deleteValue(LI);
+                  LI->eraseFromParent();
+                }
+              }
+            }
+            
+            // Finally, remove this block from the UsingBlock set.
+            UsingBlocks[i] = UsingBlocks.back();
+            --i; --e;
+          }
+
+      // Finally, after the scan, check to see if the store is all that is left.
+      if (UsingBlocks.empty()) {
+        // The alloca has been processed, move on.
+        Allocas[AllocaNum] = Allocas.back();
+        Allocas.pop_back();
+        --AllocaNum;
+        continue;
+      }
+    }
+    
     
     if (AST)
       PointerAllocaValues[AllocaNum] = AllocaPointerVal;






More information about the llvm-commits mailing list