mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-26 18:20:39 +00:00
On last fix to the early tail duplication.
With this I am able to bootstrap clang with early tail duplication enabled for any small bb and setting tail-dup-size to a relatively large value(8) to stress this code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132816 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -82,7 +82,8 @@ namespace {
|
|||||||
MachineBasicBlock *PredBB,
|
MachineBasicBlock *PredBB,
|
||||||
DenseMap<unsigned, unsigned> &LocalVRMap,
|
DenseMap<unsigned, unsigned> &LocalVRMap,
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> &Copies,
|
SmallVector<std::pair<unsigned,unsigned>, 4> &Copies,
|
||||||
const DenseSet<unsigned> &UsedByPhi);
|
const DenseSet<unsigned> &UsedByPhi,
|
||||||
|
bool Remove);
|
||||||
void DuplicateInstruction(MachineInstr *MI,
|
void DuplicateInstruction(MachineInstr *MI,
|
||||||
MachineBasicBlock *TailBB,
|
MachineBasicBlock *TailBB,
|
||||||
MachineBasicBlock *PredBB,
|
MachineBasicBlock *PredBB,
|
||||||
@@ -336,7 +337,8 @@ void TailDuplicatePass::ProcessPHI(MachineInstr *MI,
|
|||||||
MachineBasicBlock *PredBB,
|
MachineBasicBlock *PredBB,
|
||||||
DenseMap<unsigned, unsigned> &LocalVRMap,
|
DenseMap<unsigned, unsigned> &LocalVRMap,
|
||||||
SmallVector<std::pair<unsigned,unsigned>, 4> &Copies,
|
SmallVector<std::pair<unsigned,unsigned>, 4> &Copies,
|
||||||
const DenseSet<unsigned> &RegsUsedByPhi) {
|
const DenseSet<unsigned> &RegsUsedByPhi,
|
||||||
|
bool Remove) {
|
||||||
unsigned DefReg = MI->getOperand(0).getReg();
|
unsigned DefReg = MI->getOperand(0).getReg();
|
||||||
unsigned SrcOpIdx = getPHISrcRegOpIdx(MI, PredBB);
|
unsigned SrcOpIdx = getPHISrcRegOpIdx(MI, PredBB);
|
||||||
assert(SrcOpIdx && "Unable to find matching PHI source?");
|
assert(SrcOpIdx && "Unable to find matching PHI source?");
|
||||||
@@ -351,6 +353,9 @@ void TailDuplicatePass::ProcessPHI(MachineInstr *MI,
|
|||||||
if (isDefLiveOut(DefReg, TailBB, MRI) || RegsUsedByPhi.count(DefReg))
|
if (isDefLiveOut(DefReg, TailBB, MRI) || RegsUsedByPhi.count(DefReg))
|
||||||
AddSSAUpdateEntry(DefReg, NewDef, PredBB);
|
AddSSAUpdateEntry(DefReg, NewDef, PredBB);
|
||||||
|
|
||||||
|
if (!Remove)
|
||||||
|
return;
|
||||||
|
|
||||||
// Remove PredBB from the PHI node.
|
// Remove PredBB from the PHI node.
|
||||||
MI->RemoveOperand(SrcOpIdx+1);
|
MI->RemoveOperand(SrcOpIdx+1);
|
||||||
MI->RemoveOperand(SrcOpIdx);
|
MI->RemoveOperand(SrcOpIdx);
|
||||||
@@ -594,7 +599,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
|
|||||||
if (MI->isPHI()) {
|
if (MI->isPHI()) {
|
||||||
// Replace the uses of the def of the PHI with the register coming
|
// Replace the uses of the def of the PHI with the register coming
|
||||||
// from PredBB.
|
// from PredBB.
|
||||||
ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi);
|
ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi, true);
|
||||||
} else {
|
} else {
|
||||||
// Replace def of virtual registers with new registers, and update
|
// Replace def of virtual registers with new registers, and update
|
||||||
// uses with PHI source register or the new registers.
|
// uses with PHI source register or the new registers.
|
||||||
@@ -644,7 +649,7 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
|
|||||||
// Replace the uses of the def of the PHI with the register coming
|
// Replace the uses of the def of the PHI with the register coming
|
||||||
// from PredBB.
|
// from PredBB.
|
||||||
MachineInstr *MI = &*I++;
|
MachineInstr *MI = &*I++;
|
||||||
ProcessPHI(MI, TailBB, PrevBB, LocalVRMap, CopyInfos, UsedByPhi);
|
ProcessPHI(MI, TailBB, PrevBB, LocalVRMap, CopyInfos, UsedByPhi, true);
|
||||||
if (MI->getParent())
|
if (MI->getParent())
|
||||||
MI->eraseFromParent();
|
MI->eraseFromParent();
|
||||||
}
|
}
|
||||||
@@ -675,6 +680,57 @@ TailDuplicatePass::TailDuplicate(MachineBasicBlock *TailBB, MachineFunction &MF,
|
|||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If this is after register allocation, there are no phis to fix.
|
||||||
|
if (!PreRegAlloc)
|
||||||
|
return Changed;
|
||||||
|
|
||||||
|
// If we made no changes so far, we are safe.
|
||||||
|
if (!Changed)
|
||||||
|
return Changed;
|
||||||
|
|
||||||
|
|
||||||
|
// Handle the nasty case in that we duplicated a block that is part of a loop
|
||||||
|
// into some but not all of its predecessors. For example:
|
||||||
|
// 1 -> 2 <-> 3
|
||||||
|
// \
|
||||||
|
// \---> rest
|
||||||
|
// if we duplicate 2 into 1 but not into 3, we end up with
|
||||||
|
// 12 -> 3 <-> 2 -> rest
|
||||||
|
// \ /
|
||||||
|
// \----->-----/
|
||||||
|
// If there was a "var = phi(1, 3)" in 2, it has to be ultimately replaced
|
||||||
|
// with a phi in 3 (which now dominates 2).
|
||||||
|
// What we do here is introduce a copy in 3 of the register defined by the
|
||||||
|
// phi, just like when we are duplicating 2 into 3, but we don't copy any
|
||||||
|
// real instructions or remove the 3 -> 2 edge from the phi in 2.
|
||||||
|
for (SmallSetVector<MachineBasicBlock *, 8>::iterator PI = Preds.begin(),
|
||||||
|
PE = Preds.end(); PI != PE; ++PI) {
|
||||||
|
MachineBasicBlock *PredBB = *PI;
|
||||||
|
if (std::find(TDBBs.begin(), TDBBs.end(), PredBB) != TDBBs.end())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// EH edges
|
||||||
|
if (PredBB->succ_size() != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DenseMap<unsigned, unsigned> LocalVRMap;
|
||||||
|
SmallVector<std::pair<unsigned,unsigned>, 4> CopyInfos;
|
||||||
|
MachineBasicBlock::iterator I = TailBB->begin();
|
||||||
|
// Process PHI instructions first.
|
||||||
|
while (I != TailBB->end() && I->isPHI()) {
|
||||||
|
// Replace the uses of the def of the PHI with the register coming
|
||||||
|
// from PredBB.
|
||||||
|
MachineInstr *MI = &*I++;
|
||||||
|
ProcessPHI(MI, TailBB, PredBB, LocalVRMap, CopyInfos, UsedByPhi, false);
|
||||||
|
}
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user