1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 03:33:20 +01:00

Clear kill flags on the fly when joining intervals.

With physreg joining out of the way, it is easy to recognize the
instructions that need their kill flags cleared while testing for
interference.

This allows us to skip the final scan of all instructions for an 11%
speedup of the coalescer pass.

llvm-svn: 157169
This commit is contained in:
Jakob Stoklund Olesen 2012-05-20 21:41:05 +00:00
parent c86575e757
commit dadb6e60b9

View File

@ -1143,6 +1143,10 @@ bool RegisterCoalescer::joinReservedPhysReg(CoalescerPair &CP) {
// reserved register. Also skip merging the live ranges, the reserved
// register live range doesn't need to be accurate as long as all the
// defs are there.
// We don't track kills for reserved registers.
MRI->clearKillFlags(CP.getSrcReg());
return true;
}
@ -1387,6 +1391,10 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
LiveInterval::const_iterator J = RHS.begin();
LiveInterval::const_iterator JE = RHS.end();
// Collect interval end points that will no longer be kills.
SmallVector<MachineInstr*, 8> LHSOldKills;
SmallVector<MachineInstr*, 8> RHSOldKills;
// Skip ahead until the first place of potential sharing.
if (I != IE && J != JE) {
if (I->start < J->start) {
@ -1407,6 +1415,14 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
if (LHSValNoAssignments[I->valno->id] !=
RHSValNoAssignments[J->valno->id])
return false;
// Extended live ranges should no longer be killed.
if (!I->end.isBlock() && I->end < J->end)
if (MachineInstr *MI = LIS->getInstructionFromIndex(I->end))
LHSOldKills.push_back(MI);
if (!J->end.isBlock() && J->end < I->end)
if (MachineInstr *MI = LIS->getInstructionFromIndex(J->end))
RHSOldKills.push_back(MI);
}
if (I->end < J->end)
@ -1433,6 +1449,12 @@ bool RegisterCoalescer::joinIntervals(CoalescerPair &CP) {
NewVNInfo[RHSValID]->setHasPHIKill(true);
}
// Clear kill flags where live ranges are extended.
while (!LHSOldKills.empty())
LHSOldKills.pop_back_val()->clearRegisterKills(LHS.reg, TRI);
while (!RHSOldKills.empty())
RHSOldKills.pop_back_val()->clearRegisterKills(RHS.reg, TRI);
if (LHSValNoAssignments.empty())
LHSValNoAssignments.push_back(-1);
if (RHSValNoAssignments.empty())
@ -1624,42 +1646,6 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
});
}
// Perform a final pass over the instructions and compute spill weights
// and remove identity moves.
SmallVector<unsigned, 4> DeadDefs;
for (MachineFunction::iterator mbbi = MF->begin(), mbbe = MF->end();
mbbi != mbbe; ++mbbi) {
MachineBasicBlock* mbb = mbbi;
for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
mii != mie; ) {
MachineInstr *MI = mii;
++mii;
// Check for now unnecessary kill flags.
if (LIS->isNotInMIMap(MI)) continue;
SlotIndex DefIdx = LIS->getInstructionIndex(MI).getRegSlot();
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isKill()) continue;
unsigned reg = MO.getReg();
if (!reg || !LIS->hasInterval(reg)) continue;
if (!LIS->getInterval(reg).killedAt(DefIdx)) {
MO.setIsKill(false);
continue;
}
// When leaving a kill flag on a physreg, check if any subregs should
// remain alive.
if (!TargetRegisterInfo::isPhysicalRegister(reg))
continue;
for (const uint16_t *SR = TRI->getSubRegisters(reg);
unsigned S = *SR; ++SR)
if (LIS->hasInterval(S) && LIS->getInterval(S).liveAt(DefIdx))
MI->addRegisterDefined(S, TRI);
}
}
}
// After deleting a lot of copies, register classes may be less constrained.
// Removing sub-register operands may allow GR32_ABCD -> GR32 and DPR_VFP2 ->
// DPR inflation.