From 8e60d4d240ebf86f8cc62d9a638f816ac255b875 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 06:46:48 +0000 Subject: [PATCH] Add support to the two-address pass for updating LiveIntervals in many of the common transformations. This includes updating repairIntervalsInRange() to handle more cases. llvm-svn: 175604 --- llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 51 +++++++++++++++----- llvm/lib/CodeGen/TwoAddressInstructionPass.cpp | 65 ++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 14 deletions(-) diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 7b1eed2..8177db6 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1038,20 +1038,36 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, ArrayRef OrigRegs) { - SlotIndex startIdx; - if (Begin == MBB->begin()) - startIdx = getMBBStartIdx(MBB); + SlotIndex endIdx; + if (End == MBB->end()) + endIdx = getMBBEndIdx(MBB).getPrevSlot(); else - startIdx = getInstructionIndex(prior(Begin)).getRegSlot(); + endIdx = getInstructionIndex(End); Indexes->repairIndexesInRange(MBB, Begin, End); + for (MachineBasicBlock::iterator I = End; I != Begin;) { + --I; + MachineInstr *MI = I; + for (MachineInstr::const_mop_iterator MOI = MI->operands_begin(), + MOE = MI->operands_end(); MOI != MOE; ++MOI) { + if (MOI->isReg() && + TargetRegisterInfo::isVirtualRegister(MOI->getReg()) && + !hasInterval(MOI->getReg())) { + LiveInterval &LI = getOrCreateInterval(MOI->getReg()); + computeVirtRegInterval(&LI); + } + } + } + for (unsigned i = 0, e = OrigRegs.size(); i != e; ++i) { unsigned Reg = OrigRegs[i]; if (!TargetRegisterInfo::isVirtualRegister(Reg)) continue; LiveInterval &LI = getInterval(Reg); + LiveInterval::iterator LII = LI.FindLiveRangeContaining(endIdx); + for (MachineBasicBlock::iterator I = End; I != Begin;) { --I; MachineInstr *MI = I; @@ -1063,13 +1079,26 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB, if (!MO.isReg() || MO.getReg() != Reg) continue; - assert(MO.isUse() && "Register defs are not yet supported."); - - if (!LI.liveAt(instrIdx)) { - LiveRange *LR = LI.getLiveRangeContaining(startIdx); - assert(LR && "Used registers must be live-in."); - LR->end = instrIdx.getRegSlot(); - break; + if (MO.isDef()) { + assert(LII != LI.end() && + "Dead register defs are not yet supported."); + if (!Indexes->getInstructionFromIndex(LII->start)) { + LII->start = instrIdx.getRegSlot(); + LII->valno->def = instrIdx.getRegSlot(); + } else if (LII->start != instrIdx.getRegSlot()) { + VNInfo *VNI = LI.getNextValue(instrIdx.getRegSlot(), VNInfoAllocator); + LiveRange LR = LiveRange(instrIdx.getRegSlot(), LII->start, VNI); + LII = LI.addRange(LR); + } + } else if (MO.isUse()) { + if (LII == LI.end()) + --LII; + + assert(LII->start < instrIdx && + "Registers with multiple used live ranges are not yet supported."); + SlotIndex endIdx = LII->end; + if (!endIdx.isBlock() && !Indexes->getInstructionFromIndex(endIdx)) + LII->end = instrIdx.getRegSlot(); } } } diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index cf14b4d..0da6662 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1149,7 +1149,29 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, } LV->addVirtualRegisterKilled(Reg, NewMIs[1]); } + + MachineBasicBlock::iterator Begin; + MachineBasicBlock::iterator End; + SmallVector OrigRegs; + if (LIS) { + Begin = MachineBasicBlock::iterator(NewMIs[0]); + if (Begin != MBB->begin()) + --Begin; + End = next(MachineBasicBlock::iterator(MI)); + + for (MachineInstr::const_mop_iterator MOI = MI.operands_begin(), + MOE = MI.operands_end(); MOI != MOE; ++MOI) { + if (MOI->isReg()) + OrigRegs.push_back(MOI->getReg()); + } + } + MI.eraseFromParent(); + + // Update LiveIntervals. + if (LIS) + LIS->repairIntervalsInRange(MBB, Begin, End, OrigRegs); + mi = NewMIs[1]; if (TransformSuccess) return true; @@ -1223,6 +1245,7 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, bool RemovedKillFlag = false; bool AllUsesCopied = true; unsigned LastCopiedReg = 0; + SlotIndex LastCopyIdx; unsigned RegB = 0; for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) { unsigned SrcIdx = TiedPairs[tpi].first; @@ -1267,9 +1290,17 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, DistanceMap.insert(std::make_pair(PrevMI, Dist)); DistanceMap[MI] = ++Dist; - SlotIndex CopyIdx; - if (Indexes) - CopyIdx = Indexes->insertMachineInstrInMaps(PrevMI).getRegSlot(); + if (LIS) { + LastCopyIdx = LIS->InsertMachineInstrInMaps(PrevMI).getRegSlot(); + + if (TargetRegisterInfo::isVirtualRegister(RegA)) { + LiveInterval &LI = LIS->getInterval(RegA); + VNInfo *VNI = LI.getNextValue(LastCopyIdx, LIS->getVNInfoAllocator()); + SlotIndex endIdx = + LIS->getInstructionIndex(MI).getRegSlot(IsEarlyClobber); + LI.addRange(LiveRange(LastCopyIdx, endIdx, VNI)); + } + } DEBUG(dbgs() << "\t\tprepend:\t" << *PrevMI); @@ -1315,6 +1346,18 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, LV->addVirtualRegisterKilled(RegB, PrevMI); } + // Update LiveIntervals. + if (LIS) { + LiveInterval &LI = LIS->getInterval(RegB); + SlotIndex MIIdx = LIS->getInstructionIndex(MI); + LiveInterval::const_iterator I = LI.find(MIIdx); + assert(I != LI.end() && "RegB must be live-in to use."); + + SlotIndex UseIdx = MIIdx.getRegSlot(IsEarlyClobber); + if (I->end == UseIdx) + LI.removeRange(LastCopyIdx, UseIdx); + } + } else if (RemovedKillFlag) { // Some tied uses of regB matched their destination registers, so // regB is still used in this instruction, but a kill flag was @@ -1469,6 +1512,13 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { llvm_unreachable(0); } + SmallVector OrigRegs; + if (LIS) { + OrigRegs.push_back(MI->getOperand(0).getReg()); + for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) + OrigRegs.push_back(MI->getOperand(i).getReg()); + } + bool DefEmitted = false; for (unsigned i = 1, e = MI->getNumOperands(); i < e; i += 2) { MachineOperand &UseMO = MI->getOperand(i); @@ -1512,6 +1562,8 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { DEBUG(dbgs() << "Inserted: " << *CopyMI); } + MachineBasicBlock::iterator EndMBBI = next(MachineBasicBlock::iterator(MI)); + if (!DefEmitted) { DEBUG(dbgs() << "Turned: " << *MI << " into an IMPLICIT_DEF"); MI->setDesc(TII->get(TargetOpcode::IMPLICIT_DEF)); @@ -1521,4 +1573,11 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { DEBUG(dbgs() << "Eliminated: " << *MI); MI->eraseFromParent(); } + + // Udpate LiveIntervals. + if (LIS) { + if (MBBI != MBB->begin()) + --MBBI; + LIS->repairIntervalsInRange(MBB, MBBI, EndMBBI, OrigRegs); + } } -- 2.7.4