summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2006-05-29 01:00:00 +0000
committerOwen Anderson <resistor@mac.com>2006-05-29 01:00:00 +0000
commit00ea74c27e8fbd78f5564d4efd185431c13a92e7 (patch)
treec83366159a8ce8e95908b421bc9efdca17506f6d /lib
parentfb0c0dc9604ffba751bdaf272a7ba8cbd29f5860 (diff)
downloadllvm-00ea74c27e8fbd78f5564d4efd185431c13a92e7.tar.gz
llvm-00ea74c27e8fbd78f5564d4efd185431c13a92e7.tar.bz2
llvm-00ea74c27e8fbd78f5564d4efd185431c13a92e7.tar.xz
Add Use replacement. Assuming there is nothing horribly wrong with this, LCSSA
is now theoretically feature-complete. It has not, however, been thoroughly test, and is still considered experimental. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28529 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Transforms/Utils/LCSSA.cpp37
1 files changed, 35 insertions, 2 deletions
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp
index 31e480321c..3232dd8a93 100644
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -111,6 +111,7 @@ bool LCSSA::visitSubloop(Loop* L) {
// Iterate over all affected values for this loop and insert Phi nodes
// for them in the appropriate exit blocks
+ std::map<BasicBlock*, PHINode*> ExitPhis;
for (std::set<Instruction*>::iterator I = AffectedValues.begin(),
E = AffectedValues.end(); I != E; ++I) {
++NumLCSSA; // We are applying the transformation
@@ -119,6 +120,7 @@ bool LCSSA::visitSubloop(Loop* L) {
PHINode *phi = new PHINode((*I)->getType(), "lcssa");
(*BBI)->getInstList().insert((*BBI)->front(), phi);
workList.push_back(phi);
+ ExitPhis[*BBI] = phi;
// Since LoopSimplify has been run, we know that all of these predecessors
// are in the loop, so just hook them up in the obvious manner.
@@ -166,9 +168,40 @@ bool LCSSA::visitSubloop(Loop* L) {
break;
}
}
-
- // FIXME: Should update all uses.
+
+
+
+ // Find all uses of the affected value, and replace them with the
+ // appropriate Phi.
+ for (Instruction::use_iterator UI = (*I)->use_begin(), UE=(*I)->use_end();
+ UI != UE; ++UI) {
+ Instruction* use = cast<Instruction>(*UI);
+
+ // Don't need to update uses within the loop body
+ if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(),
+ use->getParent())) {
+
+ for (std::map<BasicBlock*, PHINode*>::iterator DI = ExitPhis.begin(),
+ DE = ExitPhis.end(); DI != DE; ++DI) {
+ if (DT->getNode((*DI).first)->dominates( \
+ DT->getNode(use->getParent())) && use != (*DI).second) {
+ use->replaceUsesOfWith(*I, (*DI).second);
+ break;
+ }
+ }
+
+ for (std::map<BasicBlock*, PHINode*>::iterator DI = DFPhis.begin(),
+ DE = DFPhis.end(); DI != DE; ++DI) {
+ if (DT->getNode((*DI).first)->dominates( \
+ DT->getNode(use->getParent()))) {
+ use->replaceUsesOfWith(*I, (*DI).second);
+ break;
+ }
+ }
+ }
+ }
}
+
return true; // FIXME: Should be more intelligent in our return value.
}