From 315b42c3545c5f0de3f8f74f7d5fe315338bc32f Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 17 Mar 2011 00:23:45 +0000 Subject: [PATCH] Rewrite instructions as part of ConnectedVNInfoEqClasses::Distribute. llvm-svn: 127779 --- llvm/include/llvm/CodeGen/LiveInterval.h | 11 +++--- llvm/lib/CodeGen/LiveInterval.cpp | 49 ++++++++++++++++-------- llvm/lib/CodeGen/SplitKit.cpp | 25 +----------- llvm/lib/CodeGen/SplitKit.h | 7 ---- 4 files changed, 40 insertions(+), 52 deletions(-) diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h index 427af879609e..785f31b4dc24 100644 --- a/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/llvm/include/llvm/CodeGen/LiveInterval.h @@ -548,8 +548,8 @@ namespace llvm { /// } class ConnectedVNInfoEqClasses { - LiveIntervals &lis_; - IntEqClasses eqClass_; + LiveIntervals &LIS; + IntEqClasses EqClass; // Note that values a and b are connected. void Connect(unsigned a, unsigned b); @@ -557,7 +557,7 @@ namespace llvm { unsigned Renumber(); public: - explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : lis_(lis) {} + explicit ConnectedVNInfoEqClasses(LiveIntervals &lis) : LIS(lis) {} /// Classify - Classify the values in LI into connected components. /// Return the number of connected components. @@ -565,12 +565,13 @@ namespace llvm { /// getEqClass - Classify creates equivalence classes numbered 0..N. Return /// the equivalence class assigned the VNI. - unsigned getEqClass(const VNInfo *VNI) const { return eqClass_[VNI->id]; } + unsigned getEqClass(const VNInfo *VNI) const { return EqClass[VNI->id]; } /// Distribute - Distribute values in LIV[0] into a separate LiveInterval /// for each connected component. LIV must have a LiveInterval for each /// connected component. The LiveIntervals in Liv[1..] must be empty. - void Distribute(LiveInterval *LIV[]); + /// Instructions using LIV[0] are rewritten. + void Distribute(LiveInterval *LIV[], MachineRegisterInfo &MRI); }; diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp index 18ec9d566729..ac602a9e34c4 100644 --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -719,8 +719,8 @@ void LiveRange::print(raw_ostream &os) const { unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { // Create initial equivalence classes. - eqClass_.clear(); - eqClass_.grow(LI->getNumValNums()); + EqClass.clear(); + EqClass.grow(LI->getNumValNums()); const VNInfo *used = 0, *unused = 0; @@ -731,48 +731,65 @@ unsigned ConnectedVNInfoEqClasses::Classify(const LiveInterval *LI) { // Group all unused values into one class. if (VNI->isUnused()) { if (unused) - eqClass_.join(unused->id, VNI->id); + EqClass.join(unused->id, VNI->id); unused = VNI; continue; } used = VNI; if (VNI->isPHIDef()) { - const MachineBasicBlock *MBB = lis_.getMBBFromIndex(VNI->def); + const MachineBasicBlock *MBB = LIS.getMBBFromIndex(VNI->def); assert(MBB && "Phi-def has no defining MBB"); // Connect to values live out of predecessors. for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) if (const VNInfo *PVNI = - LI->getVNInfoAt(lis_.getMBBEndIdx(*PI).getPrevSlot())) - eqClass_.join(VNI->id, PVNI->id); + LI->getVNInfoAt(LIS.getMBBEndIdx(*PI).getPrevSlot())) + EqClass.join(VNI->id, PVNI->id); } else { // Normal value defined by an instruction. Check for two-addr redef. // FIXME: This could be coincidental. Should we really check for a tied // operand constraint? // Note that VNI->def may be a use slot for an early clobber def. if (const VNInfo *UVNI = LI->getVNInfoAt(VNI->def.getPrevSlot())) - eqClass_.join(VNI->id, UVNI->id); + EqClass.join(VNI->id, UVNI->id); } } // Lump all the unused values in with the last used value. if (used && unused) - eqClass_.join(used->id, unused->id); + EqClass.join(used->id, unused->id); - eqClass_.compress(); - return eqClass_.getNumClasses(); + EqClass.compress(); + return EqClass.getNumClasses(); } -void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) { +void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[], + MachineRegisterInfo &MRI) { assert(LIV[0] && "LIV[0] must be set"); LiveInterval &LI = *LIV[0]; - // First move runs to new intervals. + // Rewrite instructions. + for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LI.reg), + RE = MRI.reg_end(); RI != RE;) { + MachineOperand &MO = RI.getOperand(); + MachineInstr *MI = MO.getParent(); + ++RI; + if (MO.isUse() && MO.isUndef()) + continue; + // DBG_VALUE instructions should have been eliminated earlier. + SlotIndex Idx = LIS.getInstructionIndex(MI); + Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); + const VNInfo *VNI = LI.getVNInfoAt(Idx); + assert(VNI && "Interval not live at use."); + MO.setReg(LIV[getEqClass(VNI)]->reg); + } + + // Move runs to new intervals. LiveInterval::iterator J = LI.begin(), E = LI.end(); - while (J != E && eqClass_[J->valno->id] == 0) + while (J != E && EqClass[J->valno->id] == 0) ++J; for (LiveInterval::iterator I = J; I != E; ++I) { - if (unsigned eq = eqClass_[I->valno->id]) { + if (unsigned eq = EqClass[I->valno->id]) { assert((LIV[eq]->empty() || LIV[eq]->expiredAt(I->start)) && "New intervals should be empty"); LIV[eq]->ranges.push_back(*I); @@ -783,11 +800,11 @@ void ConnectedVNInfoEqClasses::Distribute(LiveInterval *LIV[]) { // Transfer VNInfos to their new owners and renumber them. unsigned j = 0, e = LI.getNumValNums(); - while (j != e && eqClass_[j] == 0) + while (j != e && EqClass[j] == 0) ++j; for (unsigned i = j; i != e; ++i) { VNInfo *VNI = LI.getValNumInfo(i); - if (unsigned eq = eqClass_[i]) { + if (unsigned eq = EqClass[i]) { VNI->id = LIV[eq]->getNumValNums(); LIV[eq]->valnos.push_back(VNI); } else { diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index 9c1f75c42a04..6f7b972c43a9 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -771,28 +771,6 @@ void SplitEditor::rewriteAssigned(bool ExtendRanges) { } } -/// rewriteSplit - Rewrite uses of Intvs[0] according to the ConEQ mapping. -void SplitEditor::rewriteComponents(const SmallVectorImpl &Intvs, - const ConnectedVNInfoEqClasses &ConEq) { - for (MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(Intvs[0]->reg), - RE = MRI.reg_end(); RI != RE;) { - MachineOperand &MO = RI.getOperand(); - MachineInstr *MI = MO.getParent(); - ++RI; - if (MO.isUse() && MO.isUndef()) - continue; - // DBG_VALUE instructions should have been eliminated earlier. - SlotIndex Idx = LIS.getInstructionIndex(MI); - Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex(); - DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t' - << Idx << ':'); - const VNInfo *VNI = Intvs[0]->getVNInfoAt(Idx); - assert(VNI && "Interval not live at use."); - MO.setReg(Intvs[ConEq.getEqClass(VNI)]->reg); - DEBUG(dbgs() << VNI->id << '\t' << *MI); - } -} - void SplitEditor::deleteRematVictims() { SmallVector Dead; for (LiveInterval::const_vni_iterator I = Edit->getParent().vni_begin(), @@ -889,8 +867,7 @@ void SplitEditor::finish() { dups.push_back(li); for (unsigned i = 1; i != NumComp; ++i) dups.push_back(&Edit->create(MRI, LIS, VRM)); - rewriteComponents(dups, ConEQ); - ConEQ.Distribute(&dups[0]); + ConEQ.Distribute(&dups[0], MRI); } // Calculate spill weight and allocation hints for new intervals. diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index 3f1a03c0ba4f..e371a4dd176e 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -265,13 +265,6 @@ class SplitEditor { /// rewriteAssigned - Rewrite all uses of Edit.getReg() to assigned registers. void rewriteAssigned(bool ExtendRanges); - /// rewriteComponents - Rewrite all uses of Intv[0] according to the eq - /// classes in ConEQ. - /// This must be done when Intvs[0] is styill live at all uses, before calling - /// ConEq.Distribute(). - void rewriteComponents(const SmallVectorImpl &Intvs, - const ConnectedVNInfoEqClasses &ConEq); - /// deleteRematVictims - Delete defs that are dead after rematerializing. void deleteRematVictims();