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

Chris Lattner lattner at cs.uiuc.edu
Thu Apr 8 15:00:34 PDT 2004


Changes in directory llvm/lib/Transforms/Utils:

PromoteMemoryToRegister.cpp updated: 1.61 -> 1.62

---
Log message:

Implement ScalarRepl/select_promote.ll


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

Index: llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
diff -u llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.61 llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.62
--- llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp:1.61	Tue Feb  3 16:34:12 2004
+++ llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp	Thu Apr  8 14:59:34 2004
@@ -71,11 +71,42 @@
       if (!isa<LoadInst>(UI) || cast<LoadInst>(UI)->isVolatile()) return false;
       
       // Scan looking for memory accesses.
+      // FIXME: this should REALLY use alias analysis.
       for (--UI; !isa<PHINode>(UI); --UI)
         if (isa<LoadInst>(UI) || isa<StoreInst>(UI) || isa<CallInst>(UI))
           return false;
 
       // If we got this far, we can promote the PHI use.
+    } else if (const SelectInst *SI = dyn_cast<SelectInst>(*UI)) {
+      // We only support selects in a few simple cases.  The select is only
+      // allowed to have one use, which must be a load instruction, and can only
+      // use alloca instructions (no random pointers).  Also, there cannot be
+      // any accesses to AI between the PHI node and the use of the PHI.
+      if (!SI->hasOneUse()) return false;
+
+      // Our transformation causes the unconditional loading of all pointer
+      // operands of the select.  Because this could cause a fault if there is a
+      // critical edge in the CFG and if one of the pointers is illegal, we
+      // refuse to promote the select unless it is obviously safe.  For now,
+      // obviously safe means that all of the operands are allocas.
+      //
+      if (!isa<AllocaInst>(SI->getOperand(1)) ||
+          !isa<AllocaInst>(SI->getOperand(2)))
+        return false;
+      
+      // Now make sure the one user instruction is in the same basic block as
+      // the PHI, and that there are no loads or stores between the PHI node and
+      // the access.
+      BasicBlock::const_iterator UI = cast<Instruction>(SI->use_back());
+      if (!isa<LoadInst>(UI) || cast<LoadInst>(UI)->isVolatile()) return false;
+      
+      // Scan looking for memory accesses.
+      // FIXME: this should REALLY use alias analysis.
+      for (--UI; &*UI != SI; --UI)
+        if (isa<LoadInst>(UI) || isa<StoreInst>(UI) || isa<CallInst>(UI))
+          return false;
+
+      // If we got this far, we can promote the select use.
     } else {
       return false;   // Not a load, store, or promotable PHI?
     }
@@ -170,6 +201,28 @@
       } else if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
         // Otherwise it must be a load instruction, keep track of variable reads
         UsingBlocks.push_back(LI->getParent());
+      } else if (SelectInst *SI = dyn_cast<SelectInst>(User)) {
+        // Because of the restrictions we placed on Select instruction uses
+        // above things are very simple.  Transform the PHI of addresses into a
+        // select of loaded values.
+        LoadInst *Load = cast<LoadInst>(SI->use_back());
+        std::string LoadName = Load->getName(); Load->setName("");
+
+        Value *TrueVal = new LoadInst(SI->getOperand(1), 
+                                      SI->getOperand(1)->getName()+".val", SI);
+        Value *FalseVal = new LoadInst(SI->getOperand(2), 
+                                       SI->getOperand(2)->getName()+".val", SI);
+
+        Value *NewSI = new SelectInst(SI->getOperand(0), TrueVal,
+                                      FalseVal, Load->getName(), SI);
+        Load->replaceAllUsesWith(NewSI);
+        Load->getParent()->getInstList().erase(Load);
+        SI->getParent()->getInstList().erase(SI);
+
+        // Restart our scan of uses...
+        DefiningBlocks.clear();
+        UsingBlocks.clear();
+        goto RestartUseScan;
       } else {
         // Because of the restrictions we placed on PHI node uses above, the PHI
         // node reads the block in any using predecessors.  Transform the PHI of





More information about the llvm-commits mailing list