diff options
author | Chris Lattner <sabre@nondot.org> | 2009-10-10 09:05:58 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-10-10 09:05:58 +0000 |
commit | 433a0dbb262b16b42d75715a4dad618a475ba91b (patch) | |
tree | 59ee78cd36ffa365da094bf08dd058a7fdc2aae4 /lib | |
parent | 93f3bcf7f323069e40d9abb950da73d437b6f7da (diff) | |
download | external_llvm-433a0dbb262b16b42d75715a4dad618a475ba91b.zip external_llvm-433a0dbb262b16b42d75715a4dad618a475ba91b.tar.gz external_llvm-433a0dbb262b16b42d75715a4dad618a475ba91b.tar.bz2 |
Change jump threading to use the new SSAUpdater class instead of
DemoteRegToStack. This makes it more efficient (because it isn't
creating a ton of load/stores that are eventually removed by a later
mem2reg), and more slightly more effective (because those load/stores
don't get in the way of threading).
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@83706 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/Scalar/JumpThreading.cpp | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index 21b6ceb..b9fda96 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -19,6 +19,7 @@ #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/SSAUpdater.h" #include "llvm/Target/TargetData.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Statistic.h" @@ -27,7 +28,6 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/ValueHandle.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -472,7 +472,6 @@ bool JumpThreading::ProcessSwitchOnDuplicateCond(BasicBlock *PredBB, if (PredBB == DestBB) return false; - SwitchInst *PredSI = cast<SwitchInst>(PredBB->getTerminator()); SwitchInst *DestSI = cast<SwitchInst>(DestBB->getTerminator()); @@ -905,18 +904,6 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, << ", across block:\n " << *BB << "\n"); - // Jump Threading can not update SSA properties correctly if the values - // defined in the duplicated block are used outside of the block itself. For - // this reason, we spill all values that are used outside of BB to the stack. - for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { - if (!I->isUsedOutsideOfBlock(BB)) - continue; - - // We found a use of I outside of BB. Create a new stack slot to - // break this inter-block usage pattern. - DemoteRegToStack(*I); - } - // We are going to have to map operands from the original BB block to the new // copy of the block 'NewBB'. If there are PHI nodes in BB, evaluate them to // account for entry from PredBB. @@ -954,8 +941,8 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, // Check to see if SuccBB has PHI nodes. If so, we need to add entries to the // PHI nodes for NewBB now. - for (BasicBlock::iterator PNI = SuccBB->begin(); isa<PHINode>(PNI); ++PNI) { - PHINode *PN = cast<PHINode>(PNI); + for (BasicBlock::iterator PNI = SuccBB->begin(); + PHINode *PN = dyn_cast<PHINode>(PNI); ++PNI) { // Ok, we have a PHI node. Figure out what the incoming value was for the // DestBlock. Value *IV = PN->getIncomingValueForBlock(BB); @@ -969,6 +956,46 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB, PN->addIncoming(IV, NewBB); } + // If there were values defined in BB that are used outside the block, then we + // now have to update all uses of the value to use either the original value, + // the cloned value, or some PHI derived value. This can require arbitrary + // PHI insertion, of which we are prepared to do, clean these up now. + SSAUpdater SSAUpdate; + SmallVector<Use*, 16> UsesToRename; + for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) { + // Scan all uses of this instruction to see if it is used outside of its + // block, and if so, record them in UsesToRename. + for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E; + ++UI) { + Instruction *User = cast<Instruction>(*UI); + if (PHINode *UserPN = dyn_cast<PHINode>(User)) { + if (UserPN->getIncomingBlock(UI) == BB) + continue; + } else if (User->getParent() == BB) + continue; + + UsesToRename.push_back(&UI.getUse()); + } + + // If there are no uses outside the block, we're done with this instruction. + if (UsesToRename.empty()) + continue; + + DEBUG(errs() << "JT: Renaming non-local uses of: " << *I << "\n"); + + // We found a use of I outside of BB. Rename all uses of I that are outside + // its block to be uses of the appropriate PHI node etc. See ValuesInBlocks + // with the two values we know. + SSAUpdate.Initialize(I); + SSAUpdate.AddAvailableValue(BB, I); + SSAUpdate.AddAvailableValue(NewBB, ValueMapping[I]); + + while (!UsesToRename.empty()) + SSAUpdate.RewriteUse(*UsesToRename.pop_back_val()); + DEBUG(errs() << "\n"); + } + + // Ok, NewBB is good to go. Update the terminator of PredBB to jump to // NewBB instead of BB. This eliminates predecessors from BB, which requires // us to simplify any PHI nodes in BB. |