mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Instead of processing every instruction when splitting interferences, only
process those instructions that define phi sources. This is a 47% speedup of StrongPHIElimination compile time on 403.gcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122627 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
12db7b68b6
commit
1558f5ed19
@ -107,8 +107,6 @@ namespace {
|
|||||||
/// Isolate a PHI.
|
/// Isolate a PHI.
|
||||||
void isolatePHI(MachineInstr*);
|
void isolatePHI(MachineInstr*);
|
||||||
|
|
||||||
void PartitionRegisters(MachineFunction& MF);
|
|
||||||
|
|
||||||
/// Traverses a basic block, splitting any interferences found between
|
/// Traverses a basic block, splitting any interferences found between
|
||||||
/// registers in the same congruence class. It takes two DenseMaps as
|
/// registers in the same congruence class. It takes two DenseMaps as
|
||||||
/// arguments that it also updates: CurrentDominatingParent, which maps
|
/// arguments that it also updates: CurrentDominatingParent, which maps
|
||||||
@ -142,6 +140,10 @@ namespace {
|
|||||||
|
|
||||||
DenseMap<unsigned, Node*> RegNodeMap;
|
DenseMap<unsigned, Node*> RegNodeMap;
|
||||||
|
|
||||||
|
// Maps a basic block to a list of its defs of registers that appear as PHI
|
||||||
|
// sources.
|
||||||
|
DenseMap<MachineBasicBlock*, std::vector<MachineInstr*> > PHISrcDefs;
|
||||||
|
|
||||||
// FIXME: Can these two data structures be combined? Would a std::multimap
|
// FIXME: Can these two data structures be combined? Would a std::multimap
|
||||||
// be any better?
|
// be any better?
|
||||||
|
|
||||||
@ -161,6 +163,16 @@ namespace {
|
|||||||
typedef DenseMap<unsigned, MachineInstr*> DestCopyMap;
|
typedef DenseMap<unsigned, MachineInstr*> DestCopyMap;
|
||||||
DestCopyMap InsertedDestCopies;
|
DestCopyMap InsertedDestCopies;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct MIIndexCompare {
|
||||||
|
MIIndexCompare(LiveIntervals* LiveIntervals) : LI(LiveIntervals) { }
|
||||||
|
|
||||||
|
bool operator()(const MachineInstr* LHS, const MachineInstr* RHS) const {
|
||||||
|
return LI->getInstructionIndex(LHS) < LI->getInstructionIndex(RHS);
|
||||||
|
}
|
||||||
|
|
||||||
|
LiveIntervals* LI;
|
||||||
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
char StrongPHIElimination::ID = 0;
|
char StrongPHIElimination::ID = 0;
|
||||||
@ -207,7 +219,27 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction& MF) {
|
|||||||
DT = &getAnalysis<MachineDominatorTree>();
|
DT = &getAnalysis<MachineDominatorTree>();
|
||||||
LI = &getAnalysis<LiveIntervals>();
|
LI = &getAnalysis<LiveIntervals>();
|
||||||
|
|
||||||
PartitionRegisters(MF);
|
for (MachineFunction::iterator I = MF.begin(), E = MF.end();
|
||||||
|
I != E; ++I) {
|
||||||
|
for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end();
|
||||||
|
BBI != BBE && BBI->isPHI(); ++BBI) {
|
||||||
|
unsigned DestReg = BBI->getOperand(0).getReg();
|
||||||
|
addReg(DestReg);
|
||||||
|
PHISrcDefs[I].push_back(BBI);
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) {
|
||||||
|
MachineOperand& SrcMO = BBI->getOperand(i);
|
||||||
|
unsigned SrcReg = SrcMO.getReg();
|
||||||
|
addReg(SrcReg);
|
||||||
|
unionRegs(DestReg, SrcReg);
|
||||||
|
|
||||||
|
for (MachineRegisterInfo::def_iterator DI = MRI->def_begin(SrcReg),
|
||||||
|
DE = MRI->def_end(); DI != DE; ++DI) {
|
||||||
|
PHISrcDefs[DI->getParent()].push_back(&*DI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Perform a depth-first traversal of the dominator tree, splitting
|
// Perform a depth-first traversal of the dominator tree, splitting
|
||||||
// interferences amongst PHI-congruence classes.
|
// interferences amongst PHI-congruence classes.
|
||||||
@ -232,7 +264,20 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction& MF) {
|
|||||||
// FIXME: Preserve the equivalence classes during copy insertion and use
|
// FIXME: Preserve the equivalence classes during copy insertion and use
|
||||||
// the preversed equivalence classes instead of recomputing them.
|
// the preversed equivalence classes instead of recomputing them.
|
||||||
RegNodeMap.clear();
|
RegNodeMap.clear();
|
||||||
PartitionRegisters(MF);
|
for (MachineFunction::iterator I = MF.begin(), E = MF.end();
|
||||||
|
I != E; ++I) {
|
||||||
|
for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end();
|
||||||
|
BBI != BBE && BBI->isPHI(); ++BBI) {
|
||||||
|
unsigned DestReg = BBI->getOperand(0).getReg();
|
||||||
|
addReg(DestReg);
|
||||||
|
|
||||||
|
for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) {
|
||||||
|
unsigned SrcReg = BBI->getOperand(i).getReg();
|
||||||
|
addReg(SrcReg);
|
||||||
|
unionRegs(DestReg, SrcReg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DenseMap<unsigned, unsigned> RegRenamingMap;
|
DenseMap<unsigned, unsigned> RegRenamingMap;
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
@ -336,6 +381,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction& MF) {
|
|||||||
|
|
||||||
Allocator.Reset();
|
Allocator.Reset();
|
||||||
RegNodeMap.clear();
|
RegNodeMap.clear();
|
||||||
|
PHISrcDefs.clear();
|
||||||
InsertedSrcCopySet.clear();
|
InsertedSrcCopySet.clear();
|
||||||
InsertedSrcCopyMap.clear();
|
InsertedSrcCopyMap.clear();
|
||||||
InsertedDestCopies.clear();
|
InsertedDestCopies.clear();
|
||||||
@ -410,23 +456,6 @@ void StrongPHIElimination::isolatePHI(MachineInstr* PHI) {
|
|||||||
Node->parent.setInt(Node->parent.getInt() | Node::kPHIIsolatedFlag);
|
Node->parent.setInt(Node->parent.getInt() | Node::kPHIIsolatedFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StrongPHIElimination::PartitionRegisters(MachineFunction& MF) {
|
|
||||||
for (MachineFunction::iterator I = MF.begin(), E = MF.end();
|
|
||||||
I != E; ++I) {
|
|
||||||
for (MachineBasicBlock::iterator BBI = I->begin(), BBE = I->end();
|
|
||||||
BBI != BBE && BBI->isPHI(); ++BBI) {
|
|
||||||
unsigned DestReg = BBI->getOperand(0).getReg();
|
|
||||||
addReg(DestReg);
|
|
||||||
|
|
||||||
for (unsigned i = 1; i < BBI->getNumOperands(); i += 2) {
|
|
||||||
unsigned SrcReg = BBI->getOperand(i).getReg();
|
|
||||||
addReg(SrcReg);
|
|
||||||
unionRegs(DestReg, SrcReg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// SplitInterferencesForBasicBlock - traverses a basic block, splitting any
|
/// SplitInterferencesForBasicBlock - traverses a basic block, splitting any
|
||||||
/// interferences found between registers in the same congruence class. It
|
/// interferences found between registers in the same congruence class. It
|
||||||
/// takes two DenseMaps as arguments that it also updates:
|
/// takes two DenseMaps as arguments that it also updates:
|
||||||
@ -471,10 +500,15 @@ StrongPHIElimination::SplitInterferencesForBasicBlock(
|
|||||||
MachineBasicBlock& MBB,
|
MachineBasicBlock& MBB,
|
||||||
DenseMap<unsigned, unsigned>& CurrentDominatingParent,
|
DenseMap<unsigned, unsigned>& CurrentDominatingParent,
|
||||||
DenseMap<unsigned, unsigned>& ImmediateDominatingParent) {
|
DenseMap<unsigned, unsigned>& ImmediateDominatingParent) {
|
||||||
for (MachineBasicBlock::iterator BBI = MBB.begin(), BBE = MBB.end();
|
// Sort defs by their order in the original basic block, as the code below
|
||||||
BBI != BBE; ++BBI) {
|
// assumes that it is processing definitions in dominance order.
|
||||||
for (MachineInstr::const_mop_iterator I = BBI->operands_begin(),
|
std::vector<MachineInstr*>& DefInstrs = PHISrcDefs[&MBB];
|
||||||
E = BBI->operands_end(); I != E; ++I) {
|
std::sort(DefInstrs.begin(), DefInstrs.end(), MIIndexCompare(LI));
|
||||||
|
|
||||||
|
for (std::vector<MachineInstr*>::const_iterator BBI = DefInstrs.begin(),
|
||||||
|
BBE = DefInstrs.end(); BBI != BBE; ++BBI) {
|
||||||
|
for (MachineInstr::const_mop_iterator I = (*BBI)->operands_begin(),
|
||||||
|
E = (*BBI)->operands_end(); I != E; ++I) {
|
||||||
const MachineOperand& MO = *I;
|
const MachineOperand& MO = *I;
|
||||||
|
|
||||||
// FIXME: This would be faster if it were possible to bail out of checking
|
// FIXME: This would be faster if it were possible to bail out of checking
|
||||||
@ -506,7 +540,7 @@ StrongPHIElimination::SplitInterferencesForBasicBlock(
|
|||||||
|
|
||||||
// Pop registers from the stack represented by ImmediateDominatingParent
|
// Pop registers from the stack represented by ImmediateDominatingParent
|
||||||
// until we find a parent that dominates the current instruction.
|
// until we find a parent that dominates the current instruction.
|
||||||
while (NewParent && (!DT->dominates(MRI->getVRegDef(NewParent), BBI)
|
while (NewParent && (!DT->dominates(MRI->getVRegDef(NewParent), *BBI)
|
||||||
|| !getRegColor(NewParent)))
|
|| !getRegColor(NewParent)))
|
||||||
NewParent = ImmediateDominatingParent[NewParent];
|
NewParent = ImmediateDominatingParent[NewParent];
|
||||||
|
|
||||||
@ -514,7 +548,7 @@ StrongPHIElimination::SplitInterferencesForBasicBlock(
|
|||||||
// instruction, so it is only necessary to check for the liveness of
|
// instruction, so it is only necessary to check for the liveness of
|
||||||
// NewParent in order to check for an interference.
|
// NewParent in order to check for an interference.
|
||||||
if (NewParent
|
if (NewParent
|
||||||
&& LI->getInterval(NewParent).liveAt(LI->getInstructionIndex(BBI))) {
|
&& LI->getInterval(NewParent).liveAt(LI->getInstructionIndex(*BBI))) {
|
||||||
// If there is an interference, always isolate the new register. This
|
// If there is an interference, always isolate the new register. This
|
||||||
// could be improved by using a heuristic that decides which of the two
|
// could be improved by using a heuristic that decides which of the two
|
||||||
// registers to isolate.
|
// registers to isolate.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user