diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp | 247 |
1 files changed, 98 insertions, 149 deletions
diff --git a/contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index b29ea19..2843c1a 100644 --- a/contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/contrib/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -15,6 +15,7 @@ #define DEBUG_TYPE "regcoalescing" #include "SimpleRegisterCoalescing.h" #include "VirtRegMap.h" +#include "LiveDebugVariables.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/Value.h" #include "llvm/Analysis/AliasAnalysis.h" @@ -64,9 +65,25 @@ DisablePhysicalJoin("disable-physical-join", cl::desc("Avoid coalescing physical register copies"), cl::init(false), cl::Hidden); -INITIALIZE_AG_PASS(SimpleRegisterCoalescing, RegisterCoalescer, +static cl::opt<bool> +VerifyCoalescing("verify-coalescing", + cl::desc("Verify machine instrs before and after register coalescing"), + cl::Hidden); + +INITIALIZE_AG_PASS_BEGIN(SimpleRegisterCoalescing, RegisterCoalescer, "simple-register-coalescing", "Simple Register Coalescing", - false, false, true); + false, false, true) +INITIALIZE_PASS_DEPENDENCY(LiveIntervals) +INITIALIZE_PASS_DEPENDENCY(LiveDebugVariables) +INITIALIZE_PASS_DEPENDENCY(SlotIndexes) +INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) +INITIALIZE_PASS_DEPENDENCY(StrongPHIElimination) +INITIALIZE_PASS_DEPENDENCY(PHIElimination) +INITIALIZE_PASS_DEPENDENCY(TwoAddressInstructionPass) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) +INITIALIZE_AG_PASS_END(SimpleRegisterCoalescing, RegisterCoalescer, + "simple-register-coalescing", "Simple Register Coalescing", + false, false, true) char &llvm::SimpleRegisterCoalescingID = SimpleRegisterCoalescing::ID; @@ -75,14 +92,14 @@ void SimpleRegisterCoalescing::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<AliasAnalysis>(); AU.addRequired<LiveIntervals>(); AU.addPreserved<LiveIntervals>(); + AU.addRequired<LiveDebugVariables>(); + AU.addPreserved<LiveDebugVariables>(); AU.addPreserved<SlotIndexes>(); AU.addRequired<MachineLoopInfo>(); AU.addPreserved<MachineLoopInfo>(); AU.addPreservedID(MachineDominatorsID); - if (StrongPHIElim) - AU.addPreservedID(StrongPHIEliminationID); - else - AU.addPreservedID(PHIEliminationID); + AU.addPreservedID(StrongPHIEliminationID); + AU.addPreservedID(PHIEliminationID); AU.addPreservedID(TwoAddressInstructionPassID); MachineFunctionPass::getAnalysisUsage(AU); } @@ -124,7 +141,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(const CoalescerPair &CP, // Get the location that B is defined at. Two options: either this value has // an unknown definition point or it is defined at CopyIdx. If unknown, we // can't process it. - if (!BValNo->getCopy()) return false; + if (!BValNo->isDefByCopy()) return false; assert(BValNo->def == CopyIdx && "Copy doesn't define the value?"); // AValNo is the value number in A that defines the copy, A3 in the example. @@ -218,7 +235,7 @@ bool SimpleRegisterCoalescing::AdjustCopiesBackFrom(const CoalescerPair &CP, continue; LiveInterval &SRLI = li_->getInterval(*SR); SRLI.addRange(LiveRange(FillerStart, FillerEnd, - SRLI.getNextValue(FillerStart, 0, true, + SRLI.getNextValue(FillerStart, 0, li_->getVNInfoAllocator()))); } } @@ -266,9 +283,6 @@ bool SimpleRegisterCoalescing::HasOtherReachingDefs(LiveInterval &IntA, for (; BI != IntB.ranges.end() && AI->end >= BI->start; ++BI) { if (BI->valno == BValNo) continue; - // When BValNo is null, we're looking for a dummy clobber-value for a subreg. - if (!BValNo && !BI->valno->isDefAccurate() && !BI->valno->getCopy()) - continue; if (BI->start <= AI->start && BI->end > AI->start) return true; if (BI->start > AI->start && BI->start < AI->end) @@ -278,16 +292,6 @@ bool SimpleRegisterCoalescing::HasOtherReachingDefs(LiveInterval &IntA, return false; } -static void -TransferImplicitOps(MachineInstr *MI, MachineInstr *NewMI) { - for (unsigned i = MI->getDesc().getNumOperands(), e = MI->getNumOperands(); - i != e; ++i) { - MachineOperand &MO = MI->getOperand(i); - if (MO.isReg() && MO.isImplicit()) - NewMI->addOperand(MO); - } -} - /// RemoveCopyByCommutingDef - We found a non-trivially-coalescable copy with /// IntA being the source and IntB being the dest, thus this defines a value /// number in IntB. If the source value number (in IntA) is defined by a @@ -324,8 +328,7 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, if (!li_->hasInterval(CP.getDstReg())) return false; - SlotIndex CopyIdx = - li_->getInstructionIndex(CopyMI).getDefIndex(); + SlotIndex CopyIdx = li_->getInstructionIndex(CopyMI).getDefIndex(); LiveInterval &IntA = li_->getInterval(CP.isFlipped() ? CP.getDstReg() : CP.getSrcReg()); @@ -334,27 +337,19 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, // BValNo is a value number in B that is defined by a copy from A. 'B3' in // the example above. - LiveInterval::iterator BLR = IntB.FindLiveRangeContaining(CopyIdx); - if (BLR == IntB.end()) return false; - VNInfo *BValNo = BLR->valno; + VNInfo *BValNo = IntB.getVNInfoAt(CopyIdx); + if (!BValNo || !BValNo->isDefByCopy()) + return false; - // Get the location that B is defined at. Two options: either this value has - // an unknown definition point or it is defined at CopyIdx. If unknown, we - // can't process it. - if (!BValNo->getCopy()) return false; assert(BValNo->def == CopyIdx && "Copy doesn't define the value?"); // AValNo is the value number in A that defines the copy, A3 in the example. - LiveInterval::iterator ALR = - IntA.FindLiveRangeContaining(CopyIdx.getUseIndex()); // + VNInfo *AValNo = IntA.getVNInfoAt(CopyIdx.getUseIndex()); + assert(AValNo && "COPY source not live"); - assert(ALR != IntA.end() && "Live range not found!"); - VNInfo *AValNo = ALR->valno; // If other defs can reach uses of this def, then it's not safe to perform - // the optimization. FIXME: Do isPHIDef and isDefAccurate both need to be - // tested? - if (AValNo->isPHIDef() || !AValNo->isDefAccurate() || - AValNo->isUnused() || AValNo->hasPHIKill()) + // the optimization. + if (AValNo->isPHIDef() || AValNo->isUnused() || AValNo->hasPHIKill()) return false; MachineInstr *DefMI = li_->getInstructionFromIndex(AValNo->def); if (!DefMI) @@ -411,7 +406,8 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, return false; } - DEBUG(dbgs() << "\tRemoveCopyByCommutingDef: " << *DefMI); + DEBUG(dbgs() << "\tRemoveCopyByCommutingDef: " << AValNo->def << '\t' + << *DefMI); // At this point we have decided that it is legal to do this // transformation. Start by commuting the instruction. @@ -427,10 +423,6 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, unsigned OpIdx = NewMI->findRegisterUseOperandIdx(IntA.reg, false); NewMI->getOperand(OpIdx).setIsKill(); - bool BHasPHIKill = BValNo->hasPHIKill(); - SmallVector<VNInfo*, 4> BDeadValNos; - std::map<SlotIndex, SlotIndex> BExtend; - // If ALR and BLR overlaps and end of BLR extends beyond end of ALR, e.g. // A = or A, B // ... @@ -439,9 +431,6 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, // C = A<kill> // ... // = B - bool Extended = BLR->end > ALR->end && ALR->end != ALR->start; - if (Extended) - BExtend[ALR->end] = BLR->end; // Update uses of IntA of the specific Val# with IntB. for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(IntA.reg), @@ -467,52 +456,24 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, UseMO.setReg(NewReg); if (UseMI == CopyMI) continue; - if (UseMO.isKill()) { - if (Extended) - UseMO.setIsKill(false); - } if (!UseMI->isCopy()) continue; if (UseMI->getOperand(0).getReg() != IntB.reg || UseMI->getOperand(0).getSubReg()) continue; - // This copy will become a noop. If it's defining a new val#, - // remove that val# as well. However this live range is being - // extended to the end of the existing live range defined by the copy. + // This copy will become a noop. If it's defining a new val#, merge it into + // BValNo. SlotIndex DefIdx = UseIdx.getDefIndex(); - const LiveRange *DLR = IntB.getLiveRangeContaining(DefIdx); - if (!DLR) + VNInfo *DVNI = IntB.getVNInfoAt(DefIdx); + if (!DVNI) continue; - BHasPHIKill |= DLR->valno->hasPHIKill(); - assert(DLR->valno->def == DefIdx); - BDeadValNos.push_back(DLR->valno); - BExtend[DLR->start] = DLR->end; + DEBUG(dbgs() << "\t\tnoop: " << DefIdx << '\t' << *UseMI); + assert(DVNI->def == DefIdx); + BValNo = IntB.MergeValueNumberInto(BValNo, DVNI); JoinedCopies.insert(UseMI); } - // We need to insert a new liverange: [ALR.start, LastUse). It may be we can - // simply extend BLR if CopyMI doesn't end the range. - DEBUG({ - dbgs() << "Extending: "; - IntB.print(dbgs(), tri_); - }); - - // Remove val#'s defined by copies that will be coalesced away. - for (unsigned i = 0, e = BDeadValNos.size(); i != e; ++i) { - VNInfo *DeadVNI = BDeadValNos[i]; - if (TargetRegisterInfo::isPhysicalRegister(IntB.reg)) { - for (const unsigned *AS = tri_->getAliasSet(IntB.reg); *AS; ++AS) { - if (!li_->hasInterval(*AS)) - continue; - LiveInterval &ASLI = li_->getInterval(*AS); - if (const LiveRange *ASLR = ASLI.getLiveRangeContaining(DeadVNI->def)) - ASLI.removeValNo(ASLR->valno); - } - } - IntB.removeValNo(BDeadValNos[i]); - } - // Extend BValNo by merging in IntA live ranges of AValNo. Val# definition // is updated. VNInfo *ValNo = BValNo; @@ -521,30 +482,12 @@ bool SimpleRegisterCoalescing::RemoveCopyByCommutingDef(const CoalescerPair &CP, for (LiveInterval::iterator AI = IntA.begin(), AE = IntA.end(); AI != AE; ++AI) { if (AI->valno != AValNo) continue; - SlotIndex End = AI->end; - std::map<SlotIndex, SlotIndex>::iterator - EI = BExtend.find(End); - if (EI != BExtend.end()) - End = EI->second; - IntB.addRange(LiveRange(AI->start, End, ValNo)); + IntB.addRange(LiveRange(AI->start, AI->end, ValNo)); } - ValNo->setHasPHIKill(BHasPHIKill); - - DEBUG({ - dbgs() << " result = "; - IntB.print(dbgs(), tri_); - dbgs() << "\nShortening: "; - IntA.print(dbgs(), tri_); - }); + DEBUG(dbgs() << "\t\textended: " << IntB << '\n'); IntA.removeValNo(AValNo); - - DEBUG({ - dbgs() << " result = "; - IntA.print(dbgs(), tri_); - dbgs() << '\n'; - }); - + DEBUG(dbgs() << "\t\ttrimmed: " << IntA << '\n'); ++numCommutes; return true; } @@ -644,6 +587,7 @@ SimpleRegisterCoalescing::TrimLiveIntervalToLastUse(SlotIndex CopyIdx, /// ReMaterializeTrivialDef - If the source of a copy is defined by a trivial /// computation, replace the copy by rematerialize the definition. bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, + bool preserveSrcInt, unsigned DstReg, unsigned DstSubIdx, MachineInstr *CopyMI) { @@ -652,12 +596,12 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, assert(SrcLR != SrcInt.end() && "Live range not found!"); VNInfo *ValNo = SrcLR->valno; // If other defs can reach uses of this def, then it's not safe to perform - // the optimization. FIXME: Do isPHIDef and isDefAccurate both need to be - // tested? - if (ValNo->isPHIDef() || !ValNo->isDefAccurate() || - ValNo->isUnused() || ValNo->hasPHIKill()) + // the optimization. + if (ValNo->isPHIDef() || ValNo->isUnused() || ValNo->hasPHIKill()) return false; MachineInstr *DefMI = li_->getInstructionFromIndex(ValNo->def); + if (!DefMI) + return false; assert(DefMI && "Defining instruction disappeared"); const TargetInstrDesc &TID = DefMI->getDesc(); if (!TID.isAsCheapAsAMove()) @@ -681,8 +625,8 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, return false; } - // If destination register has a sub-register index on it, make sure it mtches - // the instruction register class. + // If destination register has a sub-register index on it, make sure it + // matches the instruction register class. if (DstSubIdx) { const TargetInstrDesc &TID = DefMI->getDesc(); if (TID.getNumDefs() != 1) @@ -699,30 +643,12 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, RemoveCopyFlag(DstReg, CopyMI); - // If copy kills the source register, find the last use and propagate - // kill. - bool checkForDeadDef = false; MachineBasicBlock *MBB = CopyMI->getParent(); - if (SrcLR->end == CopyIdx.getDefIndex()) - if (!TrimLiveIntervalToLastUse(CopyIdx, MBB, SrcInt, SrcLR)) { - checkForDeadDef = true; - } - MachineBasicBlock::iterator MII = llvm::next(MachineBasicBlock::iterator(CopyMI)); tii_->reMaterialize(*MBB, MII, DstReg, DstSubIdx, DefMI, *tri_); MachineInstr *NewMI = prior(MII); - if (checkForDeadDef) { - // PR4090 fix: Trim interval failed because there was no use of the - // source interval in this MBB. If the def is in this MBB too then we - // should mark it dead: - if (DefMI->getParent() == MBB) { - DefMI->addRegisterDead(SrcInt.reg, tri_); - SrcLR->end = SrcLR->start.getNextSlot(); - } - } - // CopyMI may have implicit operands, transfer them over to the newly // rematerialized instruction. And update implicit def interval valnos. for (unsigned i = CopyMI->getDesc().getNumOperands(), @@ -734,13 +660,18 @@ bool SimpleRegisterCoalescing::ReMaterializeTrivialDef(LiveInterval &SrcInt, RemoveCopyFlag(MO.getReg(), CopyMI); } - TransferImplicitOps(CopyMI, NewMI); + NewMI->copyImplicitOps(CopyMI); li_->ReplaceMachineInstrInMaps(CopyMI, NewMI); CopyMI->eraseFromParent(); ReMatCopies.insert(CopyMI); ReMatDefs.insert(DefMI); DEBUG(dbgs() << "Remat: " << *NewMI); ++NumReMats; + + // The source interval can become smaller because we removed a use. + if (preserveSrcInt) + li_->shrinkToUses(&SrcInt); + return true; } @@ -756,6 +687,9 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(const CoalescerPair &CP) { unsigned DstReg = CP.getDstReg(); unsigned SubIdx = CP.getSubIdx(); + // Update LiveDebugVariables. + ldv_->renameRegister(SrcReg, DstReg, SubIdx); + for (MachineRegisterInfo::reg_iterator I = mri_->reg_begin(SrcReg); MachineInstr *UseMI = I.skipInstruction();) { // A PhysReg copy that won't be coalesced can perhaps be rematerialized @@ -768,7 +702,7 @@ SimpleRegisterCoalescing::UpdateRegDefsUses(const CoalescerPair &CP) { UseMI->getOperand(0).getReg() != SrcReg && UseMI->getOperand(0).getReg() != DstReg && !JoinedCopies.count(UseMI) && - ReMaterializeTrivialDef(li_->getInterval(SrcReg), + ReMaterializeTrivialDef(li_->getInterval(SrcReg), false, UseMI->getOperand(0).getReg(), 0, UseMI)) continue; } @@ -874,7 +808,7 @@ void SimpleRegisterCoalescing::RemoveCopyFlag(unsigned DstReg, if (li_->hasInterval(DstReg)) { LiveInterval &LI = li_->getInterval(DstReg); if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) - if (LR->valno->getCopy() == CopyMI) + if (LR->valno->def == DefIdx) LR->valno->setCopy(0); } if (!TargetRegisterInfo::isPhysicalRegister(DstReg)) @@ -884,7 +818,7 @@ void SimpleRegisterCoalescing::RemoveCopyFlag(unsigned DstReg, continue; LiveInterval &LI = li_->getInterval(*AS); if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) - if (LR->valno->getCopy() == CopyMI) + if (LR->valno->def == DefIdx) LR->valno->setCopy(0); } } @@ -1044,23 +978,19 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { return false; } - DEBUG(dbgs() << "\tConsidering merging %reg" << CP.getSrcReg()); + DEBUG(dbgs() << "\tConsidering merging " << PrintReg(CP.getSrcReg(), tri_)); // Enforce policies. if (CP.isPhys()) { - DEBUG(dbgs() <<" with physreg %" << tri_->getName(CP.getDstReg()) << "\n"); + DEBUG(dbgs() <<" with physreg " << PrintReg(CP.getDstReg(), tri_) << "\n"); // Only coalesce to allocatable physreg. if (!li_->isAllocatable(CP.getDstReg())) { DEBUG(dbgs() << "\tRegister is an unallocatable physreg.\n"); return false; // Not coalescable. } } else { - DEBUG({ - dbgs() << " with reg%" << CP.getDstReg(); - if (CP.getSubIdx()) - dbgs() << ":" << tri_->getSubRegIndexName(CP.getSubIdx()); - dbgs() << " to " << CP.getNewRC()->getName() << "\n"; - }); + DEBUG(dbgs() << " with " << PrintReg(CP.getDstReg(), tri_, CP.getSubIdx()) + << " to " << CP.getNewRC()->getName() << "\n"); // Avoid constraining virtual register regclass too much. if (CP.isCrossClass()) { @@ -1114,7 +1044,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // Before giving up coalescing, if definition of source is defined by // trivial computation, try rematerializing it. if (!CP.isFlipped() && - ReMaterializeTrivialDef(JoinVInt, CP.getDstReg(), 0, CopyMI)) + ReMaterializeTrivialDef(JoinVInt, true, CP.getDstReg(), 0, CopyMI)) return true; ++numAborts; @@ -1134,7 +1064,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // If definition of source is defined by trivial computation, try // rematerializing it. if (!CP.isFlipped() && - ReMaterializeTrivialDef(li_->getInterval(CP.getSrcReg()), + ReMaterializeTrivialDef(li_->getInterval(CP.getSrcReg()), true, CP.getDstReg(), 0, CopyMI)) return true; @@ -1317,7 +1247,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(CoalescerPair &CP) { for (LiveInterval::vni_iterator i = LHS.vni_begin(), e = LHS.vni_end(); i != e; ++i) { VNInfo *VNI = *i; - if (VNI->isUnused() || VNI->getCopy() == 0) // Src not defined by a copy? + if (VNI->isUnused() || !VNI->isDefByCopy()) // Src not defined by a copy? continue; // Never join with a register that has EarlyClobber redefs. @@ -1341,7 +1271,7 @@ bool SimpleRegisterCoalescing::JoinIntervals(CoalescerPair &CP) { for (LiveInterval::vni_iterator i = RHS.vni_begin(), e = RHS.vni_end(); i != e; ++i) { VNInfo *VNI = *i; - if (VNI->isUnused() || VNI->getCopy() == 0) // Src not defined by a copy? + if (VNI->isUnused() || !VNI->isDefByCopy()) // Src not defined by a copy? continue; // Never join with a register that has EarlyClobber redefs. @@ -1495,9 +1425,9 @@ void SimpleRegisterCoalescing::CopyCoalesceInMBB(MachineBasicBlock *MBB, std::vector<CopyRec> &TryAgain) { DEBUG(dbgs() << MBB->getName() << ":\n"); - std::vector<CopyRec> VirtCopies; - std::vector<CopyRec> PhysCopies; - std::vector<CopyRec> ImpDefCopies; + SmallVector<CopyRec, 8> VirtCopies; + SmallVector<CopyRec, 8> PhysCopies; + SmallVector<CopyRec, 8> ImpDefCopies; for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end(); MII != E;) { MachineInstr *Inst = MII++; @@ -1690,6 +1620,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { tri_ = tm_->getRegisterInfo(); tii_ = tm_->getInstrInfo(); li_ = &getAnalysis<LiveIntervals>(); + ldv_ = &getAnalysis<LiveDebugVariables>(); AA = &getAnalysis<AliasAnalysis>(); loopInfo = &getAnalysis<MachineLoopInfo>(); @@ -1697,6 +1628,9 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'); + if (VerifyCoalescing) + mf_->verify(this, "Before register coalescing"); + for (TargetRegisterInfo::regclass_iterator I = tri_->regclass_begin(), E = tri_->regclass_end(); I != E; ++I) allocatableRCRegs_.insert(std::make_pair(*I, @@ -1739,9 +1673,11 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { DoDelete = false; if (MI->allDefsAreDead()) { - LiveInterval &li = li_->getInterval(SrcReg); - if (!ShortenDeadCopySrcLiveRange(li, MI)) - ShortenDeadCopyLiveRange(li, MI); + if (li_->hasInterval(SrcReg)) { + LiveInterval &li = li_->getInterval(SrcReg); + if (!ShortenDeadCopySrcLiveRange(li, MI)) + ShortenDeadCopyLiveRange(li, MI); + } DoDelete = true; } if (!DoDelete) { @@ -1821,13 +1757,26 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) { if (!MO.isReg() || !MO.isKill()) continue; unsigned reg = MO.getReg(); if (!reg || !li_->hasInterval(reg)) continue; - if (!li_->getInterval(reg).killedAt(DefIdx)) + if (!li_->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 unsigned *SR = tri_->getSubRegisters(reg); + unsigned S = *SR; ++SR) + if (li_->hasInterval(S) && li_->getInterval(S).liveAt(DefIdx)) + MI->addRegisterDefined(S, tri_); } } } DEBUG(dump()); + DEBUG(ldv_->dump()); + if (VerifyCoalescing) + mf_->verify(this, "After register coalescing"); return true; } |