[llvm-commits] [llvm] r76223 - in /llvm/trunk/lib/CodeGen: LiveIntervalAnalysis.cpp SimpleRegisterCoalescing.cpp SimpleRegisterCoalescing.h
Evan Cheng
evan.cheng at apple.com
Fri Jul 17 12:43:51 PDT 2009
Author: evancheng
Date: Fri Jul 17 14:43:40 2009
New Revision: 76223
URL: http://llvm.org/viewvc/llvm-project?rev=76223&view=rev
Log:
Simplify the coalescer (finally!) by making LiveIntervals::processImplicitDefs a little more aggressive and teaching liveintervals to make use of isUndef marker on MachineOperands.
Modified:
llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h
Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=76223&r1=76222&r2=76223&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Fri Jul 17 14:43:40 2009
@@ -123,7 +123,6 @@
++I;
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
unsigned Reg = MI->getOperand(0).getReg();
- MI->getOperand(0).setIsUndef();
ImpDefRegs.insert(Reg);
ImpDefMIs.push_back(MI);
continue;
@@ -175,11 +174,13 @@
for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) {
MachineInstr *MI = ImpDefMIs[i];
unsigned Reg = MI->getOperand(0).getReg();
- if (TargetRegisterInfo::isPhysicalRegister(Reg))
- // Physical registers are not liveout (yet).
- continue;
- if (!ImpDefRegs.count(Reg))
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
+ !ImpDefRegs.count(Reg)) {
+ // Delete all "local" implicit_def's. That include those which define
+ // physical registers since they cannot be liveout.
+ MI->eraseFromParent();
continue;
+ }
// If there are multiple defs of the same register and at least one
// is not an implicit_def, do not insert implicit_def's before the
@@ -195,6 +196,10 @@
if (Skip)
continue;
+ // The only implicit_def which we want to keep are those that are live
+ // out of its block.
+ MI->eraseFromParent();
+
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
UE = mri_->use_end(); UI != UE; ) {
MachineOperand &RMO = UI.getOperand();
@@ -203,12 +208,19 @@
MachineBasicBlock *RMBB = RMI->getParent();
if (RMBB == MBB)
continue;
+
+ // Turn a copy use into an implicit_def.
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (tii_->isMoveInstr(*RMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+ Reg == SrcReg) {
+ RMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
+ for (int j = RMI->getNumOperands() - 1, ee = 0; j > ee; --j)
+ RMI->RemoveOperand(j);
+ continue;
+ }
+
const TargetRegisterClass* RC = mri_->getRegClass(Reg);
unsigned NewVReg = mri_->createVirtualRegister(RC);
- MachineInstrBuilder MIB =
- BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
- tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
- (*MIB).getOperand(0).setIsUndef();
RMO.setReg(NewVReg);
RMO.setIsUndef();
RMO.setIsKill();
@@ -593,17 +605,12 @@
unsigned MOIdx,
LiveInterval &interval) {
DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
- LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
-
- if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
- DOUT << "is a implicit_def\n";
- return;
- }
// Virtual registers may be defined multiple times (due to phi
// elimination and 2-addr elimination). Much of what we do only has to be
// done once for the vreg. We use an empty interval to detect the first
// time we see a vreg.
+ LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
if (interval.empty()) {
// Get the Idx of the defining instructions.
unsigned defIndex = getDefIndex(MIIdx);
@@ -981,7 +988,8 @@
DOUT << "********** COMPUTING LIVE INTERVALS **********\n"
<< "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n';
-
+
+ SmallVector<unsigned, 8> UndefUses;
for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end();
MBBI != E; ++MBBI) {
MachineBasicBlock *MBB = MBBI;
@@ -1013,10 +1021,14 @@
// Handle defs.
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.getReg())
+ continue;
+
// handle register defs - build intervals
- if (MO.isReg() && MO.getReg() && MO.isDef()) {
+ if (MO.isDef())
handleRegisterDef(MBB, MI, MIIndex, MO, i);
- }
+ else if (MO.isUndef())
+ UndefUses.push_back(MO.getReg());
}
// Skip over the empty slots after each instruction.
@@ -1031,6 +1043,14 @@
MIIndex += InstrSlots::NUM;
}
}
+
+ // Create empty intervals for registers defined by implicit_def's (except
+ // for those implicit_def that define values which are liveout of their
+ // blocks.
+ for (unsigned i = 0, e = UndefUses.size(); i != e; ++i) {
+ unsigned UndefReg = UndefUses[i];
+ (void)getOrCreateInterval(UndefReg);
+ }
}
bool LiveIntervals::findLiveInMBBs(unsigned Start, unsigned End,
@@ -1523,23 +1543,13 @@
continue;
if (RegJ == RegI) {
Ops.push_back(j);
- HasUse |= MOj.isUse();
- HasDef |= MOj.isDef();
+ if (!MOj.isUndef()) {
+ HasUse |= MOj.isUse();
+ HasDef |= MOj.isDef();
+ }
}
}
- if (HasUse && !li.liveAt(getUseIndex(index)))
- // Must be defined by an implicit def. It should not be spilled. Note,
- // this is for correctness reason. e.g.
- // 8 %reg1024<def> = IMPLICIT_DEF
- // 12 %reg1024<def> = INSERT_SUBREG %reg1024<kill>, %reg1025, 2
- // The live range [12, 14) are not part of the r1024 live interval since
- // it's defined by an implicit def. It will not conflicts with live
- // interval of r1025. Now suppose both registers are spilled, you can
- // easily see a situation where both registers are reloaded before
- // the INSERT_SUBREG and both target registers that would overlap.
- HasUse = false;
-
// Create a new virtual register for the spill interval.
// Create the new register now so we can map the fold instruction
// to the new register so when it is unfolded we get the correct
@@ -1728,7 +1738,8 @@
unsigned index = getInstructionIndex(MI);
if (index < start || index >= end)
continue;
- if (O.isUse() && !li.liveAt(getUseIndex(index)))
+
+ if (O.isUndef())
// Must be defined by an implicit def. It should not be spilled. Note,
// this is for correctness reason. e.g.
// 8 %reg1024<def> = IMPLICIT_DEF
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp?rev=76223&r1=76222&r2=76223&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.cpp Fri Jul 17 14:43:40 2009
@@ -786,35 +786,6 @@
}
}
-/// RemoveDeadImpDef - Remove implicit_def instructions which are "re-defining"
-/// registers due to insert_subreg coalescing. e.g.
-/// r1024 = op
-/// r1025 = implicit_def
-/// r1025 = insert_subreg r1025, r1024
-/// = op r1025
-/// =>
-/// r1025 = op
-/// r1025 = implicit_def
-/// r1025 = insert_subreg r1025, r1025
-/// = op r1025
-void
-SimpleRegisterCoalescing::RemoveDeadImpDef(unsigned Reg, LiveInterval &LI) {
- for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(Reg),
- E = mri_->reg_end(); I != E; ) {
- MachineOperand &O = I.getOperand();
- MachineInstr *DefMI = &*I;
- ++I;
- if (!O.isDef())
- continue;
- if (DefMI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF)
- continue;
- if (!LI.liveBeforeAndAt(li_->getInstructionIndex(DefMI)))
- continue;
- li_->RemoveMachineInstrFromMaps(DefMI);
- DefMI->eraseFromParent();
- }
-}
-
/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
/// due to live range lengthening as the result of coalescing.
void SimpleRegisterCoalescing::RemoveUnnecessaryKills(unsigned Reg,
@@ -1002,65 +973,6 @@
}
-/// TurnCopiesFromValNoToImpDefs - The specified value# is defined by an
-/// implicit_def and it is being removed. Turn all copies from this value#
-/// into implicit_defs.
-void SimpleRegisterCoalescing::TurnCopiesFromValNoToImpDefs(LiveInterval &li,
- VNInfo *VNI) {
- SmallVector<MachineInstr*, 4> ImpDefs;
- MachineOperand *LastUse = NULL;
- unsigned LastUseIdx = li_->getUseIndex(VNI->def);
- for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(li.reg),
- RE = mri_->reg_end(); RI != RE;) {
- MachineOperand *MO = &RI.getOperand();
- MachineInstr *MI = &*RI;
- ++RI;
- if (MO->isDef()) {
- if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF)
- ImpDefs.push_back(MI);
- continue;
- }
- if (JoinedCopies.count(MI))
- continue;
- unsigned UseIdx = li_->getUseIndex(li_->getInstructionIndex(MI));
- LiveInterval::iterator ULR = li.FindLiveRangeContaining(UseIdx);
- if (ULR == li.end() || ULR->valno != VNI)
- continue;
- // If the use is a copy, turn it into an identity copy.
- unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
- if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
- SrcReg == li.reg) {
- // Change it to an implicit_def.
- MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
- for (int i = MI->getNumOperands() - 1, e = 0; i > e; --i)
- MI->RemoveOperand(i);
- // It's no longer a copy, update the valno it defines.
- unsigned DefIdx = li_->getDefIndex(UseIdx);
- LiveInterval &DstInt = li_->getInterval(DstReg);
- LiveInterval::iterator DLR = DstInt.FindLiveRangeContaining(DefIdx);
- assert(DLR != DstInt.end() && "Live range not found!");
- assert(DLR->valno->copy == MI);
- DLR->valno->copy = NULL;
- ReMatCopies.insert(MI);
- } else if (UseIdx > LastUseIdx) {
- LastUseIdx = UseIdx;
- LastUse = MO;
- }
- }
- if (LastUse) {
- LastUse->setIsKill();
- li.addKill(VNI, LastUseIdx+1, false);
- } else {
- // Remove dead implicit_def's.
- while (!ImpDefs.empty()) {
- MachineInstr *ImpDef = ImpDefs.back();
- ImpDefs.pop_back();
- li_->RemoveMachineInstrFromMaps(ImpDef);
- ImpDef->eraseFromParent();
- }
- }
-}
-
/// isWinToJoinVRWithSrcPhysReg - Return true if it's worth while to join a
/// a virtual destination register with physical source register.
bool
@@ -1786,13 +1698,6 @@
if (TargetRegisterInfo::isVirtualRegister(DstReg))
RemoveUnnecessaryKills(DstReg, *ResDstInt);
- if (isInsSubReg)
- // Avoid:
- // r1024 = op
- // r1024 = implicit_def
- // ...
- // = r1024
- RemoveDeadImpDef(DstReg, *ResDstInt);
UpdateRegDefsUses(SrcReg, DstReg, SubIdx);
// SrcReg is guarateed to be the register whose live interval that is
@@ -1808,29 +1713,6 @@
delete SavedLI;
}
- if (isEmpty) {
- // Now the copy is being coalesced away, the val# previously defined
- // by the copy is being defined by an IMPLICIT_DEF which defines a zero
- // length interval. Remove the val#.
- unsigned CopyIdx = li_->getDefIndex(li_->getInstructionIndex(CopyMI));
- const LiveRange *LR = ResDstInt->getLiveRangeContaining(CopyIdx);
- VNInfo *ImpVal = LR->valno;
- assert(ImpVal->def == CopyIdx);
- unsigned NextDef = LR->end;
- TurnCopiesFromValNoToImpDefs(*ResDstInt, ImpVal);
- ResDstInt->removeValNo(ImpVal);
- LR = ResDstInt->FindLiveRangeContaining(NextDef);
- if (LR != ResDstInt->end() && LR->valno->def == NextDef) {
- // Special case: vr1024 = implicit_def
- // vr1024 = insert_subreg vr1024, vr1025, c
- // The insert_subreg becomes a "copy" that defines a val# which can itself
- // be coalesced away.
- MachineInstr *DefMI = li_->getInstructionFromIndex(NextDef);
- if (DefMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
- LR->valno->copy = DefMI;
- }
- }
-
// If resulting interval has a preference that no longer fits because of subreg
// coalescing, just clear the preference.
unsigned Preference = getRegAllocPreference(ResDstInt->reg, *mf_, mri_, tri_);
@@ -2695,10 +2577,8 @@
if (EndMBB != MBB)
return false;
DstInt.removeValNo(DstLR->valno);
- CopyMI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
- for (int i = CopyMI->getNumOperands() - 1, e = 0; i > e; --i)
- CopyMI->RemoveOperand(i);
- CopyMI->getOperand(0).setIsUndef();
+ li_->RemoveMachineInstrFromMaps(CopyMI);
+ CopyMI->eraseFromParent();
bool NoUse = mri_->use_empty(SrcReg);
if (NoUse) {
for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg),
Modified: llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h?rev=76223&r1=76222&r2=76223&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h (original)
+++ llvm/trunk/lib/CodeGen/SimpleRegisterCoalescing.h Fri Jul 17 14:43:40 2009
@@ -277,10 +277,6 @@
/// subregister.
void UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, unsigned SubIdx);
- /// RemoveDeadImpDef - Remove implicit_def instructions which are
- /// "re-defining" registers due to insert_subreg coalescing. e.g.
- void RemoveDeadImpDef(unsigned Reg, LiveInterval &LI);
-
/// RemoveUnnecessaryKills - Remove kill markers that are no longer accurate
/// due to live range lengthening as the result of coalescing.
void RemoveUnnecessaryKills(unsigned Reg, LiveInterval &LI);
More information about the llvm-commits
mailing list