1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

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).

llvm-svn: 83706
This commit is contained in:
Chris Lattner 2009-10-10 09:05:58 +00:00
parent 9c5aa00411
commit 75e5de9243

View File

@ -19,6 +19,7 @@
#include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/SSAUpdater.h"
#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetData.h"
#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
@ -27,7 +28,6 @@
#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallSet.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ValueHandle.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
using namespace llvm; using namespace llvm;
@ -472,7 +472,6 @@ bool JumpThreading::ProcessSwitchOnDuplicateCond(BasicBlock *PredBB,
if (PredBB == DestBB) if (PredBB == DestBB)
return false; return false;
SwitchInst *PredSI = cast<SwitchInst>(PredBB->getTerminator()); SwitchInst *PredSI = cast<SwitchInst>(PredBB->getTerminator());
SwitchInst *DestSI = cast<SwitchInst>(DestBB->getTerminator()); SwitchInst *DestSI = cast<SwitchInst>(DestBB->getTerminator());
@ -905,18 +904,6 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB,
<< ", across block:\n " << ", across block:\n "
<< *BB << "\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 // 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 // copy of the block 'NewBB'. If there are PHI nodes in BB, evaluate them to
// account for entry from PredBB. // 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 // Check to see if SuccBB has PHI nodes. If so, we need to add entries to the
// PHI nodes for NewBB now. // PHI nodes for NewBB now.
for (BasicBlock::iterator PNI = SuccBB->begin(); isa<PHINode>(PNI); ++PNI) { for (BasicBlock::iterator PNI = SuccBB->begin();
PHINode *PN = cast<PHINode>(PNI); PHINode *PN = dyn_cast<PHINode>(PNI); ++PNI) {
// Ok, we have a PHI node. Figure out what the incoming value was for the // Ok, we have a PHI node. Figure out what the incoming value was for the
// DestBlock. // DestBlock.
Value *IV = PN->getIncomingValueForBlock(BB); Value *IV = PN->getIncomingValueForBlock(BB);
@ -969,6 +956,46 @@ bool JumpThreading::ThreadEdge(BasicBlock *BB, BasicBlock *PredBB,
PN->addIncoming(IV, NewBB); 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 // 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 // NewBB instead of BB. This eliminates predecessors from BB, which requires
// us to simplify any PHI nodes in BB. // us to simplify any PHI nodes in BB.