From 00ea74c27e8fbd78f5564d4efd185431c13a92e7 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 29 May 2006 01:00:00 +0000 Subject: [PATCH] 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 --- lib/Transforms/Utils/LCSSA.cpp | 37 ++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index 31e480321cd..3232dd8a938 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 ExitPhis; for (std::set::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(*UI); + + // Don't need to update uses within the loop body + if (!std::binary_search(LoopBlocks.begin(), LoopBlocks.end(), + use->getParent())) { + + for (std::map::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::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. }