mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Teach early dup how to duplicate basic blocks with one successor and only phi instructions
into more complex blocks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133415 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b065b06c12
commit
275c1f9f93
@ -96,6 +96,12 @@ namespace {
|
||||
bool TailDuplicateBlocks(MachineFunction &MF);
|
||||
bool shouldTailDuplicate(const MachineFunction &MF,
|
||||
MachineBasicBlock &TailBB);
|
||||
bool isSimpleBB(MachineBasicBlock *TailBB);
|
||||
bool canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB);
|
||||
bool duplicateSimpleBB(MachineBasicBlock *TailBB,
|
||||
SmallVector<MachineBasicBlock*, 8> &TDBBs,
|
||||
const DenseSet<unsigned> &RegsUsedByPhi,
|
||||
SmallVector<MachineInstr*, 16> &Copies);
|
||||
bool TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
|
||||
SmallVector<MachineBasicBlock*, 8> &TDBBs,
|
||||
SmallVector<MachineInstr*, 16> &Copies);
|
||||
@ -557,6 +563,136 @@ TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF,
|
||||
return true;
|
||||
}
|
||||
|
||||
/// isSimpleBB - True if this BB has only one unconditional jump.
|
||||
bool
|
||||
TailDuplicatePass::isSimpleBB(MachineBasicBlock *TailBB) {
|
||||
if (TailBB->succ_size() != 1)
|
||||
return false;
|
||||
MachineBasicBlock::iterator I = TailBB->getFirstNonPHI();
|
||||
MachineBasicBlock::iterator E = TailBB->end();
|
||||
while (I->isDebugValue() && I != E)
|
||||
++I;
|
||||
if (I == E)
|
||||
return true;
|
||||
return I->getDesc().isUnconditionalBranch();
|
||||
}
|
||||
|
||||
static bool
|
||||
bothUsedInPHI(const MachineBasicBlock &A,
|
||||
SmallPtrSet<MachineBasicBlock*, 8> SuccsB) {
|
||||
for (MachineBasicBlock::const_succ_iterator SI = A.succ_begin(),
|
||||
SE = A.succ_end(); SI != SE; ++SI) {
|
||||
MachineBasicBlock *BB = *SI;
|
||||
if (SuccsB.count(BB) && !BB->empty() && BB->begin()->isPHI())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
TailDuplicatePass::canCompletelyDuplicateSimpleBB(MachineBasicBlock &BB) {
|
||||
SmallPtrSet<MachineBasicBlock*, 8> Succs(BB.succ_begin(), BB.succ_end());
|
||||
|
||||
for (MachineBasicBlock::pred_iterator PI = BB.pred_begin(),
|
||||
PE = BB.pred_end(); PI != PE; ++PI) {
|
||||
MachineBasicBlock *PredBB = *PI;
|
||||
if (PredBB->getLandingPadSuccessor())
|
||||
return false;
|
||||
if (bothUsedInPHI(*PredBB, Succs))
|
||||
return false;
|
||||
MachineBasicBlock *PredTBB = NULL, *PredFBB = NULL;
|
||||
SmallVector<MachineOperand, 4> PredCond;
|
||||
if (TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TailDuplicatePass::duplicateSimpleBB(MachineBasicBlock *TailBB,
|
||||
SmallVector<MachineBasicBlock*, 8> &TDBBs,
|
||||
const DenseSet<unsigned> &UsedByPhi,
|
||||
SmallVector<MachineInstr*, 16> &Copies) {
|
||||
if (!canCompletelyDuplicateSimpleBB(*TailBB))
|
||||
return false;
|
||||
|
||||
bool Changed = false;
|
||||
SmallVector<MachineBasicBlock*, 8> Preds(TailBB->pred_begin(),
|
||||
TailBB->pred_end());
|
||||
for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(),
|
||||
PE = Preds.end(); PI != PE; ++PI) {
|
||||
MachineBasicBlock *PredBB = *PI;
|
||||
|
||||
MachineBasicBlock *PredTBB = NULL, *PredFBB = NULL;
|
||||
SmallVector<MachineOperand, 4> PredCond;
|
||||
bool NotAnalyzable =
|
||||
TII->AnalyzeBranch(*PredBB, PredTBB, PredFBB, PredCond, true);
|
||||
(void)NotAnalyzable;
|
||||
assert(!NotAnalyzable && "Cannot duplicate this!");
|
||||
|
||||
DEBUG(dbgs() << "\nTail-duplicating into PredBB: " << *PredBB
|
||||
<< "From simple Succ: " << *TailBB);
|
||||
|
||||
MachineBasicBlock *NewTarget = *TailBB->succ_begin();
|
||||
MachineBasicBlock *NextBB = next(MachineFunction::iterator(PredBB));
|
||||
|
||||
DenseMap<unsigned, unsigned> LocalVRMap;
|
||||
SmallVector<std::pair<unsigned,unsigned>, 4> CopyInfos;
|
||||
for (MachineBasicBlock::iterator I = TailBB->begin();
|
||||
I != TailBB->end() && I->isPHI();) {
|
||||
MachineInstr *MI = &*I;
|
||||
++I;
|
||||
ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi, true);
|
||||
}
|
||||
MachineBasicBlock::iterator Loc = PredBB->getFirstTerminator();
|
||||
for (unsigned i = 0, e = CopyInfos.size(); i != e; ++i) {
|
||||
Copies.push_back(BuildMI(*PredBB, Loc, DebugLoc(),
|
||||
TII->get(TargetOpcode::COPY),
|
||||
CopyInfos[i].first).addReg(CopyInfos[i].second));
|
||||
}
|
||||
|
||||
// Make PredFBB explicit.
|
||||
if (PredCond.empty())
|
||||
PredFBB = PredTBB;
|
||||
|
||||
// Make fall through explicit.
|
||||
if (!PredTBB)
|
||||
PredTBB = NextBB;
|
||||
if (!PredFBB)
|
||||
PredFBB = NextBB;
|
||||
|
||||
// Redirect
|
||||
if (PredFBB == TailBB)
|
||||
PredFBB = NewTarget;
|
||||
if (PredTBB == TailBB)
|
||||
PredTBB = NewTarget;
|
||||
|
||||
// Make the branch unconditional if possible
|
||||
if (PredTBB == PredFBB)
|
||||
PredFBB = NULL;
|
||||
|
||||
// Avoid adding fall through branches.
|
||||
if (PredFBB == NextBB)
|
||||
PredFBB = NULL;
|
||||
if (PredTBB == NextBB && PredFBB == NULL)
|
||||
PredTBB = NULL;
|
||||
|
||||
TII->RemoveBranch(*PredBB);
|
||||
|
||||
if (PredTBB)
|
||||
TII->InsertBranch(*PredBB, PredTBB, PredFBB, PredCond, DebugLoc());
|
||||
|
||||
PredBB->removeSuccessor(TailBB);
|
||||
PredBB->addSuccessor(NewTarget);
|
||||
|
||||
TDBBs.push_back(PredBB);
|
||||
|
||||
Changed = true;
|
||||
}
|
||||
return Changed;
|
||||
}
|
||||
|
||||
/// TailDuplicate - If it is profitable, duplicate TailBB's contents in each
|
||||
/// of its predecessors.
|
||||
bool
|
||||
@ -568,14 +704,18 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
|
||||
|
||||
DEBUG(dbgs() << "\n*** Tail-duplicating BB#" << TailBB->getNumber() << '\n');
|
||||
|
||||
DenseSet<unsigned> UsedByPhi;
|
||||
getRegsUsedByPHIs(*TailBB, &UsedByPhi);
|
||||
|
||||
if (isSimpleBB(TailBB))
|
||||
return duplicateSimpleBB(TailBB, TDBBs, UsedByPhi, Copies);
|
||||
|
||||
// Iterate through all the unique predecessors and tail-duplicate this
|
||||
// block into them, if possible. Copying the list ahead of time also
|
||||
// avoids trouble with the predecessor list reallocating.
|
||||
bool Changed = false;
|
||||
SmallSetVector<MachineBasicBlock*, 8> Preds(TailBB->pred_begin(),
|
||||
TailBB->pred_end());
|
||||
DenseSet<unsigned> UsedByPhi;
|
||||
getRegsUsedByPHIs(*TailBB, &UsedByPhi);
|
||||
for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(),
|
||||
PE = Preds.end(); PI != PE; ++PI) {
|
||||
MachineBasicBlock *PredBB = *PI;
|
||||
|
Loading…
Reference in New Issue
Block a user