From ba5b67f66d646b2e50eaa13f3497323c861892cd Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 17 Jul 2009 19:43:40 +0000 Subject: [PATCH] Simplify the coalescer (finally!) by making LiveIntervals::processImplicitDefs a little more aggressive and teaching liveintervals to make use of isUndef marker on MachineOperands. llvm-svn: 76223 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 77 ++++++++------ lib/CodeGen/SimpleRegisterCoalescing.cpp | 124 +---------------------- lib/CodeGen/SimpleRegisterCoalescing.h | 4 - 3 files changed, 46 insertions(+), 159 deletions(-) diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index d8f2089f31a..261fa5e0f86 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -123,7 +123,6 @@ void LiveIntervals::processImplicitDefs() { ++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 @@ void LiveIntervals::processImplicitDefs() { 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 @@ void LiveIntervals::processImplicitDefs() { 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 @@ void LiveIntervals::processImplicitDefs() { 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 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, 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 @@ void LiveIntervals::computeIntervals() { DOUT << "********** COMPUTING LIVE INTERVALS **********\n" << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'; - + + SmallVector UndefUses; for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end(); MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; @@ -1013,10 +1021,14 @@ void LiveIntervals::computeIntervals() { // 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 @@ void LiveIntervals::computeIntervals() { 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 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI, 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 = IMPLICIT_DEF - // 12 %reg1024 = INSERT_SUBREG %reg1024, %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 @@ rewriteInstructionsForSpills(const LiveInterval &li, bool TrySplit, 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 = IMPLICIT_DEF diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index 444952f330c..3c39351eb16 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -786,35 +786,6 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(unsigned SrcReg, unsigned DstReg, } } -/// 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 @@ bool SimpleRegisterCoalescing::CanCoalesceWithImpDef(MachineInstr *CopyMI, } -/// 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 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 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { 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 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { 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 @@ SimpleRegisterCoalescing::TurnCopyIntoImpDef(MachineBasicBlock::iterator &I, 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), diff --git a/lib/CodeGen/SimpleRegisterCoalescing.h b/lib/CodeGen/SimpleRegisterCoalescing.h index b1810ed413a..7c7d820e8c4 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.h +++ b/lib/CodeGen/SimpleRegisterCoalescing.h @@ -277,10 +277,6 @@ namespace llvm { /// 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);