From 767e04307f70cad9e2ba46b3812504ee1d8c1721 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 06:46:34 +0000 Subject: Remove verification after PHIElimination when using LiveIntervals, and move it after the two-address pass. The remaining problems in 'make check' are occurring later. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175598 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 8e6f809747..f5d41c786a 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1437,6 +1437,9 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) { } } + if (LIS) + MF->verify(this, "After two-address instruction pass"); + return MadeChange; } -- cgit v1.2.3-70-g09d2 From 6cf93d740a600024f2de924614a4d4d0dc1cb852 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 06:46:46 +0000 Subject: Move the computation of the IsEarlyClobber flag into its own loop, since the correct value is needed in every iteration of the loop for updating LiveIntervals. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175603 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index f5d41c786a..cf14b4dea6 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1215,6 +1215,11 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, TiedPairList &TiedPairs, unsigned &Dist) { bool IsEarlyClobber = false; + for (unsigned tpi = 0, tpe = TiedPairs.size(); tpi != tpe; ++tpi) { + const MachineOperand &DstMO = MI->getOperand(TiedPairs[tpi].second); + IsEarlyClobber |= DstMO.isEarlyClobber(); + } + bool RemovedKillFlag = false; bool AllUsesCopied = true; unsigned LastCopiedReg = 0; @@ -1225,7 +1230,6 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI, const MachineOperand &DstMO = MI->getOperand(DstIdx); unsigned RegA = DstMO.getReg(); - IsEarlyClobber |= DstMO.isEarlyClobber(); // Grab RegB from the instruction because it may have changed if the // instruction was commuted. -- cgit v1.2.3-70-g09d2 From 9030fc22dd73684901ecb749c9688e289bd1a777 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 06:46:48 +0000 Subject: 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 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 51 ++++++++++++++++++------ lib/CodeGen/TwoAddressInstructionPass.cpp | 65 +++++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 14 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') 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 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 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); + } } -- cgit v1.2.3-70-g09d2 From fdf45175a8444c421c03627c139777d1de48e516 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 20 Feb 2013 07:39:20 +0000 Subject: Fully qualify llvm::next to avoid ambiguity when building as C++11. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175608 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveInterval.cpp | 2 +- lib/CodeGen/TwoAddressInstructionPass.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index 68f4b16023..74793bed5e 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -440,7 +440,7 @@ void LiveInterval::join(LiveInterval &Other, iterator OutIt = begin(); OutIt->valno = NewVNInfo[LHSValNoAssignments[OutIt->valno->id]]; - for (iterator I = next(OutIt), E = end(); I != E; ++I) { + for (iterator I = llvm::next(OutIt), E = end(); I != E; ++I) { VNInfo* nextValNo = NewVNInfo[LHSValNoAssignments[I->valno->id]]; assert(nextValNo != 0 && "Huh?"); diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 0da6662441..99d36071cf 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1157,7 +1157,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, Begin = MachineBasicBlock::iterator(NewMIs[0]); if (Begin != MBB->begin()) --Begin; - End = next(MachineBasicBlock::iterator(MI)); + End = llvm::next(MachineBasicBlock::iterator(MI)); for (MachineInstr::const_mop_iterator MOI = MI.operands_begin(), MOE = MI.operands_end(); MOI != MOE; ++MOI) { @@ -1562,7 +1562,8 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { DEBUG(dbgs() << "Inserted: " << *CopyMI); } - MachineBasicBlock::iterator EndMBBI = next(MachineBasicBlock::iterator(MI)); + MachineBasicBlock::iterator EndMBBI = + llvm::next(MachineBasicBlock::iterator(MI)); if (!DefEmitted) { DEBUG(dbgs() << "Turned: " << *MI << " into an IMPLICIT_DEF"); -- cgit v1.2.3-70-g09d2 From c5b6135fb55362f5c052625043ebf3286f799f86 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 22:10:00 +0000 Subject: Find anchoring end points for repairIntervalsInRange and repairIndexesInRange automatically. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175673 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveIntervalAnalysis.cpp | 7 +++++++ lib/CodeGen/SlotIndexes.cpp | 9 +++++++++ lib/CodeGen/TwoAddressInstructionPass.cpp | 17 +++++------------ 3 files changed, 21 insertions(+), 12 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index e07922b54c..a716e8bbab 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1038,6 +1038,13 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, ArrayRef OrigRegs) { + // Find anchor points, which are at the beginning/end of blocks or at + // instructions that already have indexes. + while (Begin != MBB->begin() && !Indexes->hasIndex(Begin)) + --Begin; + while (End != MBB->end() && !Indexes->hasIndex(End)) + ++End; + SlotIndex endIdx; if (End == MBB->end()) endIdx = getMBBEndIdx(MBB).getPrevSlot(); diff --git a/lib/CodeGen/SlotIndexes.cpp b/lib/CodeGen/SlotIndexes.cpp index b4e562e45b..f2937941ee 100644 --- a/lib/CodeGen/SlotIndexes.cpp +++ b/lib/CodeGen/SlotIndexes.cpp @@ -146,6 +146,15 @@ void SlotIndexes::renumberIndexes(IndexList::iterator curItr) { void SlotIndexes::repairIndexesInRange(MachineBasicBlock *MBB, MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End) { + // FIXME: Is this really necessary? The only caller repairIntervalsForRange() + // does the same thing. + // Find anchor points, which are at the beginning/end of blocks or at + // instructions that already have indexes. + while (Begin != MBB->begin() && !hasIndex(Begin)) + --Begin; + while (End != MBB->end() && !hasIndex(End)) + ++End; + bool includeStart = (Begin == MBB->begin()); SlotIndex startIdx; if (includeStart) diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 99d36071cf..43d0655708 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1150,15 +1150,8 @@ 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 = llvm::next(MachineBasicBlock::iterator(MI)); - for (MachineInstr::const_mop_iterator MOI = MI.operands_begin(), MOE = MI.operands_end(); MOI != MOE; ++MOI) { if (MOI->isReg()) @@ -1169,8 +1162,11 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, MI.eraseFromParent(); // Update LiveIntervals. - if (LIS) + if (LIS) { + MachineBasicBlock::iterator Begin(NewMIs[0]); + MachineBasicBlock::iterator End(NewMIs[1]); LIS->repairIntervalsInRange(MBB, Begin, End, OrigRegs); + } mi = NewMIs[1]; if (TransformSuccess) @@ -1576,9 +1572,6 @@ eliminateRegSequence(MachineBasicBlock::iterator &MBBI) { } // Udpate LiveIntervals. - if (LIS) { - if (MBBI != MBB->begin()) - --MBBI; + if (LIS) LIS->repairIntervalsInRange(MBB, MBBI, EndMBBI, OrigRegs); - } } -- cgit v1.2.3-70-g09d2 From 6189288766d9cf2e1cf82c1b41655e33754da83b Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Wed, 20 Feb 2013 22:10:02 +0000 Subject: Only use LiveIntervals in TwoAddressInstructionPass, not a mix of Liveintervals and SlotIndexes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175674 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 43d0655708..45d2a1b373 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -67,7 +67,6 @@ class TwoAddressInstructionPass : public MachineFunctionPass { const InstrItineraryData *InstrItins; MachineRegisterInfo *MRI; LiveVariables *LV; - SlotIndexes *Indexes; LiveIntervals *LIS; AliasAnalysis *AA; CodeGenOpt::Level OptLevel; @@ -533,8 +532,8 @@ commuteInstruction(MachineBasicBlock::iterator &mi, if (LV) // Update live variables LV->replaceKillInstruction(RegC, MI, NewMI); - if (Indexes) - Indexes->replaceMachineInstrInMaps(MI, NewMI); + if (LIS) + LIS->ReplaceMachineInstrInMaps(MI, NewMI); MBB->insert(mi, NewMI); // Insert the new inst MBB->erase(mi); // Nuke the old inst. @@ -587,8 +586,8 @@ TwoAddressInstructionPass::convertInstTo3Addr(MachineBasicBlock::iterator &mi, DEBUG(dbgs() << "2addr: TO 3-ADDR: " << *NewMI); bool Sunk = false; - if (Indexes) - Indexes->replaceMachineInstrInMaps(mi, NewMI); + if (LIS) + LIS->ReplaceMachineInstrInMaps(mi, NewMI); if (NewMI->findRegisterUseOperand(RegB, false, TRI)) // FIXME: Temporary workaround. If the new instruction doesn't @@ -1378,7 +1377,6 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) { TII = TM.getInstrInfo(); TRI = TM.getRegisterInfo(); InstrItins = TM.getInstrItineraryData(); - Indexes = getAnalysisIfAvailable(); LV = getAnalysisIfAvailable(); LIS = getAnalysisIfAvailable(); AA = &getAnalysis(); -- cgit v1.2.3-70-g09d2 From 214df4285a974c61450477cbcf5c4a196d574a6a Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Thu, 21 Feb 2013 04:33:02 +0000 Subject: Update isKilledAt in TwoAddressInstructionPass.cpp to use LiveIntervals when available. With this commit there are no longer any assertion or verifier failures when running 'make check' without LiveVariables. There are still 56 failing tests with codegen differences and 1 unexpectedly passing test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175719 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 45d2a1b373..d4108fb0d7 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -347,11 +347,33 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII, /// static bool isKilled(MachineInstr &MI, unsigned Reg, const MachineRegisterInfo *MRI, - const TargetInstrInfo *TII) { + const TargetInstrInfo *TII, + LiveIntervals *LIS) { MachineInstr *DefMI = &MI; for (;;) { - if (!DefMI->killsRegister(Reg)) + if (LIS && TargetRegisterInfo::isVirtualRegister(Reg) && + !LIS->isNotInMIMap(DefMI)) { + // FIXME: Sometimes tryInstructionTransform() will add instructions and + // test whether they can be folded before keeping them. In this case it + // sets a kill before recursively calling tryInstructionTransform() again. + // If there is no interval available, we assume that this instruction is + // one of those. A kill flag is manually inserted on the operand so the + // check below will handle it. + LiveInterval &LI = LIS->getInterval(Reg); + // This is to match the kill flag version where undefs don't have kill + // flags. + if (!LI.hasAtLeastOneValue()) + return false; + + SlotIndex useIdx = LIS->getInstructionIndex(DefMI); + LiveInterval::const_iterator I = LI.find(useIdx); + assert(I != LI.end() && "Reg must be live-in to use."); + if (!SlotIndex::isSameInstr(I->end, useIdx)) + return false; + } else if (!DefMI->killsRegister(Reg)) { return false; + } + if (TargetRegisterInfo::isPhysicalRegister(Reg)) return true; MachineRegisterInfo::def_iterator Begin = MRI->def_begin(Reg); @@ -1000,7 +1022,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, assert(TargetRegisterInfo::isVirtualRegister(regB) && "cannot make instruction into two-address form"); - bool regBKilled = isKilled(MI, regB, MRI, TII); + bool regBKilled = isKilled(MI, regB, MRI, TII, LIS); if (TargetRegisterInfo::isVirtualRegister(regA)) scanUses(regA); @@ -1020,7 +1042,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, if (regCIdx != ~0U) { regC = MI.getOperand(regCIdx).getReg(); - if (!regBKilled && isKilled(MI, regC, MRI, TII)) + if (!regBKilled && isKilled(MI, regC, MRI, TII, LIS)) // If C dies but B does not, swap the B and C operands. // This makes the live ranges of A and C joinable. TryCommute = true; -- cgit v1.2.3-70-g09d2 From 3a9805f26ead8746cb56645cb909a7b64d165b83 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Thu, 21 Feb 2013 07:02:28 +0000 Subject: Split part of isKilled() into a separate function for use elsewhere. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175726 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 50 +++++++++++++++++-------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index d4108fb0d7..8d242ec51a 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -330,6 +330,33 @@ static bool isCopyToReg(MachineInstr &MI, const TargetInstrInfo *TII, return true; } +/// isPLainlyKilled - Test if the given register value, which is used by the +// given instruction, is killed by the given instruction. +static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, + LiveIntervals *LIS) { + if (LIS && TargetRegisterInfo::isVirtualRegister(Reg) && + !LIS->isNotInMIMap(MI)) { + // FIXME: Sometimes tryInstructionTransform() will add instructions and + // test whether they can be folded before keeping them. In this case it + // sets a kill before recursively calling tryInstructionTransform() again. + // If there is no interval available, we assume that this instruction is + // one of those. A kill flag is manually inserted on the operand so the + // check below will handle it. + LiveInterval &LI = LIS->getInterval(Reg); + // This is to match the kill flag version where undefs don't have kill + // flags. + if (!LI.hasAtLeastOneValue()) + return false; + + SlotIndex useIdx = LIS->getInstructionIndex(MI); + LiveInterval::const_iterator I = LI.find(useIdx); + assert(I != LI.end() && "Reg must be live-in to use."); + return SlotIndex::isSameInstr(I->end, useIdx); + } + + return MI->killsRegister(Reg); +} + /// isKilled - Test if the given register value, which is used by the given /// instruction, is killed by the given instruction. This looks through /// coalescable copies to see if the original value is potentially not killed. @@ -351,29 +378,8 @@ static bool isKilled(MachineInstr &MI, unsigned Reg, LiveIntervals *LIS) { MachineInstr *DefMI = &MI; for (;;) { - if (LIS && TargetRegisterInfo::isVirtualRegister(Reg) && - !LIS->isNotInMIMap(DefMI)) { - // FIXME: Sometimes tryInstructionTransform() will add instructions and - // test whether they can be folded before keeping them. In this case it - // sets a kill before recursively calling tryInstructionTransform() again. - // If there is no interval available, we assume that this instruction is - // one of those. A kill flag is manually inserted on the operand so the - // check below will handle it. - LiveInterval &LI = LIS->getInterval(Reg); - // This is to match the kill flag version where undefs don't have kill - // flags. - if (!LI.hasAtLeastOneValue()) - return false; - - SlotIndex useIdx = LIS->getInstructionIndex(DefMI); - LiveInterval::const_iterator I = LI.find(useIdx); - assert(I != LI.end() && "Reg must be live-in to use."); - if (!SlotIndex::isSameInstr(I->end, useIdx)) - return false; - } else if (!DefMI->killsRegister(Reg)) { + if (!isPlainlyKilled(DefMI, Reg, LIS)) return false; - } - if (TargetRegisterInfo::isPhysicalRegister(Reg)) return true; MachineRegisterInfo::def_iterator Begin = MRI->def_begin(Reg); -- cgit v1.2.3-70-g09d2 From 17cec5a68523fe346fb752b1661cc8e640dd520b Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Thu, 21 Feb 2013 07:02:30 +0000 Subject: Make another kill check LiveIntervals-aware. This brings the number of remaining failures in 'make check' without LiveVariables down to 39, with 1 unexpectedly passing test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175727 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 8d242ec51a..e0dba3f291 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -499,7 +499,7 @@ isProfitableToCommute(unsigned regA, unsigned regB, unsigned regC, // insert => %reg1030 = MOV8rr %reg1029 // %reg1030 = ADD8rr %reg1029, %reg1028, %EFLAGS - if (!MI->killsRegister(regC)) + if (!isPlainlyKilled(MI, regC, LIS)) return false; // Ok, we have something like: -- cgit v1.2.3-70-g09d2 From a931a12e04b856421977c86d94789cd8b47d6ad3 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Thu, 21 Feb 2013 22:58:42 +0000 Subject: Stop relying on physical register kill flags in isKilled() in the two-address pass. One of the callers of isKilled() can cope with overapproximation of kills and the other can't, so I added a flag to indicate this. In theory this could pessimize code slightly, but in practice most physical register uses are kills, and most important kills of physical registers are the only uses of that register prior to register allocation, so we can recognize them as kills even without kill flags. This is relevant because LiveIntervals gets rid of all kill flags. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175821 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index e0dba3f291..e31264207c 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -372,12 +372,19 @@ static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, /// normal heuristics commute the (two-address) add, which lets /// coalescing eliminate the extra copy. /// +/// If allowFalsePositives is true then likely kills are treated as kills even +/// if it can't be proven that they are kills. static bool isKilled(MachineInstr &MI, unsigned Reg, const MachineRegisterInfo *MRI, const TargetInstrInfo *TII, - LiveIntervals *LIS) { + LiveIntervals *LIS, + bool allowFalsePositives) { MachineInstr *DefMI = &MI; for (;;) { + // All uses of physical registers are likely to be kills. + if (TargetRegisterInfo::isPhysicalRegister(Reg) && + (allowFalsePositives || MRI->hasOneUse(Reg))) + return true; if (!isPlainlyKilled(DefMI, Reg, LIS)) return false; if (TargetRegisterInfo::isPhysicalRegister(Reg)) @@ -1028,7 +1035,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, assert(TargetRegisterInfo::isVirtualRegister(regB) && "cannot make instruction into two-address form"); - bool regBKilled = isKilled(MI, regB, MRI, TII, LIS); + bool regBKilled = isKilled(MI, regB, MRI, TII, LIS, true); if (TargetRegisterInfo::isVirtualRegister(regA)) scanUses(regA); @@ -1048,7 +1055,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, if (regCIdx != ~0U) { regC = MI.getOperand(regCIdx).getReg(); - if (!regBKilled && isKilled(MI, regC, MRI, TII, LIS)) + if (!regBKilled && isKilled(MI, regC, MRI, TII, LIS, false)) // If C dies but B does not, swap the B and C operands. // This makes the live ranges of A and C joinable. TryCommute = true; -- cgit v1.2.3-70-g09d2 From 80885e524ffceaba5ed237338a10f807895e9f8e Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sat, 23 Feb 2013 04:49:13 +0000 Subject: Make rescheduleMIBelowKill() and rescheduleKillAboveMI() LiveIntervals-aware in TwoAddressInstructionPass. The code in rescheduleMIBelowKill() is a bit tricky, since multiple instructions need to be moved down, one-at-a-time, in reverse order. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175955 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 115 ++++++++++++++++++++++-------- 1 file changed, 85 insertions(+), 30 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index e31264207c..40c1a1b703 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -734,9 +734,9 @@ bool TwoAddressInstructionPass:: rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, unsigned Reg) { - // Bail immediately if we don't have LV available. We use it to find kills - // efficiently. - if (!LV) + // Bail immediately if we don't have LV or LIS available. We use them to find + // kills efficiently. + if (!LV && !LIS) return false; MachineInstr *MI = &*mi; @@ -745,7 +745,22 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, // Must be created from unfolded load. Don't waste time trying this. return false; - MachineInstr *KillMI = LV->getVarInfo(Reg).findKill(MBB); + MachineInstr *KillMI = 0; + if (LIS) { + LiveInterval &LI = LIS->getInterval(Reg); + assert(LI.end() != LI.begin() && + "Reg should not have empty live interval."); + + SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); + LiveInterval::const_iterator I = LI.find(MBBEndIdx); + if (I != LI.end() && I->start < MBBEndIdx) + return false; + + --I; + KillMI = LIS->getInstructionFromIndex(I->end); + } else { + KillMI = LV->getVarInfo(Reg).findKill(MBB); + } if (!KillMI || MI == KillMI || KillMI->isCopy() || KillMI->isCopyLike()) // Don't mess with copies, they may be coalesced later. return false; @@ -781,24 +796,27 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, Defs.insert(MOReg); else { Uses.insert(MOReg); - if (MO.isKill() && MOReg != Reg) + if (MOReg != Reg && (MO.isKill() || + (LIS && isPlainlyKilled(MI, MOReg, LIS)))) Kills.insert(MOReg); } } // Move the copies connected to MI down as well. - MachineBasicBlock::iterator From = MI; - MachineBasicBlock::iterator To = llvm::next(From); - while (To->isCopy() && Defs.count(To->getOperand(1).getReg())) { - Defs.insert(To->getOperand(0).getReg()); - ++To; + MachineBasicBlock::iterator Begin = MI; + MachineBasicBlock::iterator AfterMI = llvm::next(Begin); + + MachineBasicBlock::iterator End = AfterMI; + while (End->isCopy() && Defs.count(End->getOperand(1).getReg())) { + Defs.insert(End->getOperand(0).getReg()); + ++End; } // Check if the reschedule will not break depedencies. unsigned NumVisited = 0; MachineBasicBlock::iterator KillPos = KillMI; ++KillPos; - for (MachineBasicBlock::iterator I = To; I != KillPos; ++I) { + for (MachineBasicBlock::iterator I = End; I != KillPos; ++I) { MachineInstr *OtherMI = I; // DBG_VALUE cannot be counted against the limit. if (OtherMI->isDebugValue()) @@ -829,11 +847,13 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, } else { if (Defs.count(MOReg)) return false; + bool isKill = MO.isKill() || + (LIS && isPlainlyKilled(OtherMI, MOReg, LIS)); if (MOReg != Reg && - ((MO.isKill() && Uses.count(MOReg)) || Kills.count(MOReg))) + ((isKill && Uses.count(MOReg)) || Kills.count(MOReg))) // Don't want to extend other live ranges and update kills. return false; - if (MOReg == Reg && !MO.isKill()) + if (MOReg == Reg && !isKill) // We can't schedule across a use of the register in question. return false; // Ensure that if this is register in question, its the kill we expect. @@ -844,19 +864,35 @@ rescheduleMIBelowKill(MachineBasicBlock::iterator &mi, } // Move debug info as well. - while (From != MBB->begin() && llvm::prior(From)->isDebugValue()) - --From; + while (Begin != MBB->begin() && llvm::prior(Begin)->isDebugValue()) + --Begin; + + nmi = End; + MachineBasicBlock::iterator InsertPos = KillPos; + if (LIS) { + // We have to move the copies first so that the MBB is still well-formed + // when calling handleMove(). + for (MachineBasicBlock::iterator MBBI = AfterMI; MBBI != End;) { + MachineInstr *CopyMI = MBBI; + ++MBBI; + MBB->splice(InsertPos, MBB, CopyMI); + LIS->handleMove(CopyMI); + InsertPos = CopyMI; + } + End = llvm::next(MachineBasicBlock::iterator(MI)); + } // Copies following MI may have been moved as well. - nmi = To; - MBB->splice(KillPos, MBB, From, To); + MBB->splice(InsertPos, MBB, Begin, End); DistanceMap.erase(DI); // Update live variables - LV->removeVirtualRegisterKilled(Reg, KillMI); - LV->addVirtualRegisterKilled(Reg, MI); - if (LIS) + if (LIS) { LIS->handleMove(MI); + } else { + LV->removeVirtualRegisterKilled(Reg, KillMI); + LV->addVirtualRegisterKilled(Reg, MI); + } DEBUG(dbgs() << "\trescheduled below kill: " << *KillMI); return true; @@ -892,9 +928,9 @@ bool TwoAddressInstructionPass:: rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, unsigned Reg) { - // Bail immediately if we don't have LV available. We use it to find kills - // efficiently. - if (!LV) + // Bail immediately if we don't have LV or LIS available. We use them to find + // kills efficiently. + if (!LV && !LIS) return false; MachineInstr *MI = &*mi; @@ -903,7 +939,22 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, // Must be created from unfolded load. Don't waste time trying this. return false; - MachineInstr *KillMI = LV->getVarInfo(Reg).findKill(MBB); + MachineInstr *KillMI = 0; + if (LIS) { + LiveInterval &LI = LIS->getInterval(Reg); + assert(LI.end() != LI.begin() && + "Reg should not have empty live interval."); + + SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); + LiveInterval::const_iterator I = LI.find(MBBEndIdx); + if (I != LI.end() && I->start < MBBEndIdx) + return false; + + --I; + KillMI = LIS->getInstructionFromIndex(I->end); + } else { + KillMI = LV->getVarInfo(Reg).findKill(MBB); + } if (!KillMI || MI == KillMI || KillMI->isCopy() || KillMI->isCopyLike()) // Don't mess with copies, they may be coalesced later. return false; @@ -930,10 +981,11 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, continue; if (isDefTooClose(MOReg, DI->second, MI)) return false; - if (MOReg == Reg && !MO.isKill()) + bool isKill = MO.isKill() || (LIS && isPlainlyKilled(KillMI, MOReg, LIS)); + if (MOReg == Reg && !isKill) return false; Uses.insert(MOReg); - if (MO.isKill() && MOReg != Reg) + if (isKill && MOReg != Reg) Kills.insert(MOReg); } else if (TargetRegisterInfo::isPhysicalRegister(MOReg)) { Defs.insert(MOReg); @@ -973,7 +1025,8 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, if (Kills.count(MOReg)) // Don't want to extend other live ranges and update kills. return false; - if (OtherMI != MI && MOReg == Reg && !MO.isKill()) + if (OtherMI != MI && MOReg == Reg && + !(MO.isKill() || (LIS && isPlainlyKilled(OtherMI, MOReg, LIS)))) // We can't schedule across a use of the register in question. return false; } else { @@ -1007,10 +1060,12 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, DistanceMap.erase(DI); // Update live variables - LV->removeVirtualRegisterKilled(Reg, KillMI); - LV->addVirtualRegisterKilled(Reg, MI); - if (LIS) + if (LIS) { LIS->handleMove(KillMI); + } else { + LV->removeVirtualRegisterKilled(Reg, KillMI); + LV->addVirtualRegisterKilled(Reg, MI); + } DEBUG(dbgs() << "\trescheduled kill: " << *KillMI); return true; -- cgit v1.2.3-70-g09d2 From 4c57942608094a74543920b7c809e442fa90dd72 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sat, 23 Feb 2013 04:49:20 +0000 Subject: Make TwoAddressInstructionPass::sink3AddrInstruction() LiveIntervals-aware. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175956 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 49 +++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 15 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 40c1a1b703..cbe07db3fc 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -163,6 +163,8 @@ INITIALIZE_PASS_END(TwoAddressInstructionPass, "twoaddressinstruction", char &llvm::TwoAddressInstructionPassID = TwoAddressInstructionPass::ID; +static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, LiveIntervals *LIS); + /// sink3AddrInstruction - A two-address instruction has been converted to a /// three-address instruction to avoid clobbering a register. Try to sink it /// past the instruction that would kill the above mentioned register to reduce @@ -204,14 +206,29 @@ sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg, // Find the instruction that kills SavedReg. MachineInstr *KillMI = NULL; - for (MachineRegisterInfo::use_nodbg_iterator - UI = MRI->use_nodbg_begin(SavedReg), - UE = MRI->use_nodbg_end(); UI != UE; ++UI) { - MachineOperand &UseMO = UI.getOperand(); - if (!UseMO.isKill()) - continue; - KillMI = UseMO.getParent(); - break; + if (LIS) { + LiveInterval &LI = LIS->getInterval(SavedReg); + assert(LI.end() != LI.begin() && + "Reg should not have empty live interval."); + + SlotIndex MBBEndIdx = LIS->getMBBEndIdx(MBB).getPrevSlot(); + LiveInterval::const_iterator I = LI.find(MBBEndIdx); + if (I != LI.end() && I->start < MBBEndIdx) + return false; + + --I; + KillMI = LIS->getInstructionFromIndex(I->end); + } + if (!KillMI) { + for (MachineRegisterInfo::use_nodbg_iterator + UI = MRI->use_nodbg_begin(SavedReg), + UE = MRI->use_nodbg_end(); UI != UE; ++UI) { + MachineOperand &UseMO = UI.getOperand(); + if (!UseMO.isKill()) + continue; + KillMI = UseMO.getParent(); + break; + } } // If we find the instruction that kills SavedReg, and it is in an @@ -250,7 +267,7 @@ sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg, if (DefReg == MOReg) return false; - if (MO.isKill()) { + if (MO.isKill() || (LIS && isPlainlyKilled(OtherMI, MOReg, LIS))) { if (OtherMI == KillMI && MOReg == SavedReg) // Save the operand that kills the register. We want to unset the kill // marker if we can sink MI past it. @@ -263,13 +280,15 @@ sink3AddrInstruction(MachineInstr *MI, unsigned SavedReg, } assert(KillMO && "Didn't find kill"); - // Update kill and LV information. - KillMO->setIsKill(false); - KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI); - KillMO->setIsKill(true); + if (!LIS) { + // Update kill and LV information. + KillMO->setIsKill(false); + KillMO = MI->findRegisterUseOperand(SavedReg, false, TRI); + KillMO->setIsKill(true); - if (LV) - LV->replaceKillInstruction(SavedReg, KillMI, MI); + if (LV) + LV->replaceKillInstruction(SavedReg, KillMI, MI); + } // Move instruction to its destination. MBB->remove(MI); -- cgit v1.2.3-70-g09d2 From b4bd022731b28a80f59818870cc7df5d4771d793 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sat, 23 Feb 2013 04:49:22 +0000 Subject: Fix a bug with the LiveIntervals updating in the two-address pass found by running ASCI_Purple/SMG2000 in the test-suite. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175957 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index cbe07db3fc..aca85b2aa1 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -370,7 +370,7 @@ static bool isPlainlyKilled(MachineInstr *MI, unsigned Reg, SlotIndex useIdx = LIS->getInstructionIndex(MI); LiveInterval::const_iterator I = LI.find(useIdx); assert(I != LI.end() && "Reg must be live-in to use."); - return SlotIndex::isSameInstr(I->end, useIdx); + return !I->end.isBlock() && SlotIndex::isSameInstr(I->end, useIdx); } return MI->killsRegister(Reg); -- cgit v1.2.3-70-g09d2 From 1ea93c79bc8b044935f867b334668623c587f5a8 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sat, 23 Feb 2013 23:13:28 +0000 Subject: TargetInstrInfo::commuteInstruction() doesn't actually return a new instruction unless it was requested to with an optional parameter that defaults to false, so we don't need to handle that case in TwoAddressInstructionPass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175974 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index aca85b2aa1..2ed6be4f00 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -581,19 +581,9 @@ commuteInstruction(MachineBasicBlock::iterator &mi, } DEBUG(dbgs() << "2addr: COMMUTED TO: " << *NewMI); - // If the instruction changed to commute it, update livevar. - if (NewMI != MI) { - if (LV) - // Update live variables - LV->replaceKillInstruction(RegC, MI, NewMI); - if (LIS) - LIS->ReplaceMachineInstrInMaps(MI, NewMI); - - MBB->insert(mi, NewMI); // Insert the new inst - MBB->erase(mi); // Nuke the old inst. - mi = NewMI; - DistanceMap.insert(std::make_pair(NewMI, Dist)); - } + assert(NewMI == MI && + "TargetInstrInfo::commuteInstruction() should not return a new " + "instruction unless it was requested."); // Update source register map. unsigned FromRegC = getMappedReg(RegC, SrcRegMap); -- cgit v1.2.3-70-g09d2 From c5a6349ae84309534e0ade8c7c7ddada808e7729 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sun, 24 Feb 2013 00:27:26 +0000 Subject: TwoAddrInstructionPass::tryInstructionTransform() has a case where it calls itself recursively with a new instruction that has not been finalized, in order to determine whether to keep the instruction. On 'make check' and test-suite the only cases where the recursive invocation made any transformations were simple instruction commutations, so I am restricting the recursive invocation to do only this. The other cases wouldn't work correctly when updating LiveIntervals, since the new instructions don't have slot indices and LiveIntervals hasn't yet been updated. If the other transformations were actually triggering in any test case it would be possible to support it with a lot of effort, but since they don't it's not worth it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175979 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 2ed6be4f00..34946ec1ce 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -120,7 +120,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass { bool tryInstructionTransform(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, unsigned SrcIdx, unsigned DstIdx, - unsigned Dist); + unsigned Dist, bool shouldOnlyCommute); void scanUses(unsigned DstReg); @@ -1085,11 +1085,13 @@ rescheduleKillAboveMI(MachineBasicBlock::iterator &mi, /// either eliminate the tied operands or improve the opportunities for /// coalescing away the register copy. Returns true if no copy needs to be /// inserted to untie mi's operands (either because they were untied, or -/// because mi was rescheduled, and will be visited again later). +/// because mi was rescheduled, and will be visited again later). If the +/// shouldOnlyCommute flag is true, only instruction commutation is attempted. bool TwoAddressInstructionPass:: tryInstructionTransform(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, - unsigned SrcIdx, unsigned DstIdx, unsigned Dist) { + unsigned SrcIdx, unsigned DstIdx, + unsigned Dist, bool shouldOnlyCommute) { if (OptLevel == CodeGenOpt::None) return false; @@ -1138,6 +1140,9 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, return false; } + if (shouldOnlyCommute) + return false; + // If there is one more use of regB later in the same MBB, consider // re-schedule this MI below it. if (rescheduleMIBelowKill(mi, nmi, regB)) { @@ -1214,7 +1219,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, unsigned NewSrcIdx = NewMIs[1]->findRegisterUseOperandIdx(regB); MachineBasicBlock::iterator NewMI = NewMIs[1]; bool TransformSuccess = - tryInstructionTransform(NewMI, mi, NewSrcIdx, NewDstIdx, Dist); + tryInstructionTransform(NewMI, mi, NewSrcIdx, NewDstIdx, Dist, true); if (TransformSuccess || NewMIs[1]->getOperand(NewSrcIdx).isKill()) { // Success, or at least we made an improvement. Keep the unfolded @@ -1539,7 +1544,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) { unsigned SrcReg = mi->getOperand(SrcIdx).getReg(); unsigned DstReg = mi->getOperand(DstIdx).getReg(); if (SrcReg != DstReg && - tryInstructionTransform(mi, nmi, SrcIdx, DstIdx, Dist)) { + tryInstructionTransform(mi, nmi, SrcIdx, DstIdx, Dist, false)) { // The tied operands have been eliminated or shifted further down the // block to ease elimination. Continue processing with 'nmi'. TiedOperands.clear(); -- cgit v1.2.3-70-g09d2 From eb1b7254cf1ce480c423c2ae0ff1b68c6ada6180 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sun, 24 Feb 2013 00:27:29 +0000 Subject: TwoAddressInstructionPass::tryInstructionTransform() only potentially returns true when shouldOnlyCommute is false, so we can remove code that checks otherwise. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175980 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 34946ec1ce..fe7a7d7bda 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1218,10 +1218,11 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, unsigned NewDstIdx = NewMIs[1]->findRegisterDefOperandIdx(regA); unsigned NewSrcIdx = NewMIs[1]->findRegisterUseOperandIdx(regB); MachineBasicBlock::iterator NewMI = NewMIs[1]; - bool TransformSuccess = + bool TransformResult = tryInstructionTransform(NewMI, mi, NewSrcIdx, NewDstIdx, Dist, true); - if (TransformSuccess || - NewMIs[1]->getOperand(NewSrcIdx).isKill()) { + assert(!TransformResult && + "tryInstructionTransform() should return false."); + if (NewMIs[1]->getOperand(NewSrcIdx).isKill()) { // Success, or at least we made an improvement. Keep the unfolded // instructions and discard the original. if (LV) { @@ -1272,8 +1273,6 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, } mi = NewMIs[1]; - if (TransformSuccess) - return true; } else { // Transforming didn't eliminate the tie and didn't lead to an // improvement. Clean up the unfolded instructions and keep the -- cgit v1.2.3-70-g09d2 From cc6137e30b40ddf3cdbbb6ebbe01e5b5c76da2e2 Mon Sep 17 00:00:00 2001 From: Cameron Zwarich Date: Sun, 24 Feb 2013 01:26:05 +0000 Subject: Add a use of an otherwise unused variable to remove a warning in non-Asserts builds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175981 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/TwoAddressInstructionPass.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/CodeGen/TwoAddressInstructionPass.cpp') diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index fe7a7d7bda..26c5fe4dcb 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -1220,6 +1220,7 @@ tryInstructionTransform(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator NewMI = NewMIs[1]; bool TransformResult = tryInstructionTransform(NewMI, mi, NewSrcIdx, NewDstIdx, Dist, true); + (void)TransformResult; assert(!TransformResult && "tryInstructionTransform() should return false."); if (NewMIs[1]->getOperand(NewSrcIdx).isKill()) { -- cgit v1.2.3-70-g09d2