diff options
author | Cameron Zwarich <zwarich@apple.com> | 2013-02-20 06:46:48 +0000 |
---|---|---|
committer | Cameron Zwarich <zwarich@apple.com> | 2013-02-20 06:46:48 +0000 |
commit | 9030fc22dd73684901ecb749c9688e289bd1a777 (patch) | |
tree | 80617332dbbc87af3474cc7a8ed7e7f375df0afe /lib | |
parent | 6cf93d740a600024f2de924614a4d4d0dc1cb852 (diff) |
Add support to the two-address pass for updating LiveIntervals in many of the
common transformations. This includes updating repairIntervalsInRange() to
handle more cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175604 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 51 | ||||
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 65 |
2 files changed, 102 insertions, 14 deletions
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 7b1eed2a34..8177db6194 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1038,20 +1038,36 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, ArrayRef<unsigned> 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/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index cf14b4dea6..0da6662441 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1149,7 +1149,29 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, } LV->addVirtualRegisterKilled(Reg, NewMIs[1]); } + + MachineBasicBlock::iterator Begin; + MachineBasicBlock::iterator End; + SmallVector<unsigned, 4> 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<unsigned, 4> 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); + } } |