X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FStrongPHIElimination.cpp;h=0bf6f8e4c2384daad8a1cb1644477deac2a79fac;hb=081c34b725980f995be9080eaec24cd3dfaaf065;hp=b276e80e92b681915b7cc5cd2f1abdcbfc78f42b;hpb=9b49120408e6c0e10e18ce38cae7120c954fe708;p=oota-llvm.git diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp index b276e80e92b..0bf6f8e4c23 100644 --- a/lib/CodeGen/StrongPHIElimination.cpp +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterCoalescer.h" @@ -32,24 +33,26 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" using namespace llvm; namespace { - struct VISIBILITY_HIDDEN StrongPHIElimination : public MachineFunctionPass { + struct StrongPHIElimination : public MachineFunctionPass { static char ID; // Pass identification, replacement for typeid - StrongPHIElimination() : MachineFunctionPass((intptr_t)&ID) {} + StrongPHIElimination() : MachineFunctionPass(ID) { + initializeStrongPHIEliminationPass(*PassRegistry::getPassRegistry()); + } // Waiting stores, for each MBB, the set of copies that need to // be inserted into that MBB DenseMap > Waiting; + std::multimap > Waiting; // Stacks holds the renaming stack for each register std::map > Stacks; // Registers in UsedByAnother are PHI nodes that are themselves - // used as operands to another another PHI node + // used as operands to another PHI node std::set UsedByAnother; // RenameSets are the is a map from a PHI-defined register @@ -70,7 +73,10 @@ namespace { bool runOnMachineFunction(MachineFunction &Fn); virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); AU.addRequired(); + AU.addRequired(); + AU.addPreserved(); AU.addRequired(); // TODO: Actually make this true. @@ -139,19 +145,22 @@ namespace { std::vector& DF, std::vector >& locals); void ScheduleCopies(MachineBasicBlock* MBB, std::set& pushed); - void InsertCopies(MachineBasicBlock* MBB, + void InsertCopies(MachineDomTreeNode* MBB, SmallPtrSet& v); - void mergeLiveIntervals(unsigned primary, unsigned secondary, - MachineBasicBlock* pred); + bool mergeLiveIntervals(unsigned primary, unsigned secondary); }; } char StrongPHIElimination::ID = 0; -static RegisterPass -X("strong-phi-node-elimination", - "Eliminate PHI nodes for register allocation, intelligently"); +INITIALIZE_PASS_BEGIN(StrongPHIElimination, "strong-phi-node-elimination", + "Eliminate PHI nodes for register allocation, intelligently", false, false) +INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) +INITIALIZE_PASS_DEPENDENCY(SlotIndexes) +INITIALIZE_PASS_DEPENDENCY(LiveIntervals) +INITIALIZE_PASS_END(StrongPHIElimination, "strong-phi-node-elimination", + "Eliminate PHI nodes for register allocation, intelligently", false, false) -const PassInfo *const llvm::StrongPHIEliminationID = &X; +char &llvm::StrongPHIEliminationID = StrongPHIElimination::ID; /// computeDFS - Computes the DFS-in and DFS-out numbers of the dominator tree /// of the given MachineFunction. These numbers are then used in other parts @@ -294,8 +303,8 @@ StrongPHIElimination::computeDomForest( static bool isLiveIn(unsigned r, MachineBasicBlock* MBB, LiveIntervals& LI) { LiveInterval& I = LI.getOrCreateInterval(r); - unsigned idx = LI.getMBBStartIdx(MBB); - return I.liveBeforeAndAt(idx); + SlotIndex idx = LI.getMBBStartIdx(MBB); + return I.liveAt(idx); } /// isLiveOut - help method that determines, from a regno, if a register is @@ -303,10 +312,9 @@ static bool isLiveIn(unsigned r, MachineBasicBlock* MBB, static bool isLiveOut(unsigned r, MachineBasicBlock* MBB, LiveIntervals& LI) { for (MachineBasicBlock::succ_iterator PI = MBB->succ_begin(), - E = MBB->succ_end(); PI != E; ++PI) { + E = MBB->succ_end(); PI != E; ++PI) if (isLiveIn(r, *PI, LI)) return true; - } return false; } @@ -418,9 +426,9 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { // Iterate over all the PHI nodes in this block MachineBasicBlock::iterator P = MBB->begin(); - while (P != MBB->end() && P->getOpcode() == TargetInstrInfo::PHI) { + while (P != MBB->end() && P->isPHI()) { unsigned DestReg = P->getOperand(0).getReg(); - + // Don't both doing PHI elimination for dead PHI's. if (P->registerDefIsDead(DestReg)) { ++P; @@ -428,7 +436,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { } LiveInterval& PI = LI.getOrCreateInterval(DestReg); - unsigned pIdx = LI.getDefIndex(LI.getInstructionIndex(P)); + SlotIndex pIdx = LI.getInstructionIndex(P).getDefIndex(); VNInfo* PVN = PI.getLiveRangeContaining(pIdx)->valno; PhiValueNumber.insert(std::make_pair(DestReg, PVN->id)); @@ -442,6 +450,17 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { // Iterate over the operands of the PHI node for (int i = P->getNumOperands() - 1; i >= 2; i-=2) { unsigned SrcReg = P->getOperand(i-1).getReg(); + + // Don't need to try to coalesce a register with itself. + if (SrcReg == DestReg) { + ProcessedNames.insert(SrcReg); + continue; + } + + // We don't need to insert copies for implicit_defs. + MachineInstr* DefMI = MRI.getVRegDef(SrcReg); + if (DefMI->isImplicitDef()) + ProcessedNames.insert(SrcReg); // Check for trivial interferences via liveness information, allowing us // to avoid extra work later. Any registers that interfere cannot both @@ -458,7 +477,7 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { if (isLiveIn(SrcReg, P->getParent(), LI) || isLiveOut(P->getOperand(0).getReg(), MRI.getVRegDef(SrcReg)->getParent(), LI) || - ( MRI.getVRegDef(SrcReg)->getOpcode() == TargetInstrInfo::PHI && + ( MRI.getVRegDef(SrcReg)->isPHI() && isLiveIn(P->getOperand(0).getReg(), MRI.getVRegDef(SrcReg)->getParent(), LI) ) || ProcessedNames.count(SrcReg) || @@ -541,6 +560,12 @@ void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) { } // Add the renaming set for this PHI node to our overall renaming information + for (std::map::iterator QI = PHIUnion.begin(), + QE = PHIUnion.end(); QI != QE; ++QI) { + DEBUG(dbgs() << "Adding Renaming: " << QI->first << " -> " + << P->getOperand(0).getReg() << "\n"); + } + RenameSets.insert(std::make_pair(P->getOperand(0).getReg(), PHIUnion)); // Remember which registers are already renamed, so that we don't try to @@ -631,13 +656,13 @@ void StrongPHIElimination::processPHIUnion(MachineInstr* Inst, void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, std::set& pushed) { // FIXME: This function needs to update LiveIntervals - std::map& copy_set= Waiting[MBB]; + std::multimap& copy_set= Waiting[MBB]; - std::map worklist; + std::multimap worklist; std::map map; // Setup worklist of initial copies - for (std::map::iterator I = copy_set.begin(), + for (std::multimap::iterator I = copy_set.begin(), E = copy_set.end(); I != E; ) { map.insert(std::make_pair(I->first, I->first)); map.insert(std::make_pair(I->second, I->second)); @@ -646,9 +671,9 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, worklist.insert(*I); // Avoid iterator invalidation - unsigned first = I->first; + std::multimap::iterator OI = I; ++I; - copy_set.erase(first); + copy_set.erase(OI); } else { ++I; } @@ -664,8 +689,9 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, // Iterate over the worklist, inserting copies while (!worklist.empty() || !copy_set.empty()) { while (!worklist.empty()) { - std::pair curr = *worklist.begin(); - worklist.erase(curr.first); + std::multimap::iterator WI = worklist.begin(); + std::pair curr = *WI; + worklist.erase(WI); const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(curr.first); @@ -676,20 +702,27 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, // Insert copy from curr.second to a temporary at // the Phi defining curr.second MachineBasicBlock::iterator PI = MRI.getVRegDef(curr.second); - TII->copyRegToReg(*PI->getParent(), PI, t, - curr.second, RC, RC); + BuildMI(*PI->getParent(), PI, DebugLoc(), TII->get(TargetOpcode::COPY), + t).addReg(curr.second); + DEBUG(dbgs() << "Inserted copy from " << curr.second << " to " << t + << "\n"); // Push temporary on Stacks Stacks[curr.second].push_back(t); // Insert curr.second in pushed pushed.insert(curr.second); + + // Create a live interval for this temporary + InsertedPHIDests.push_back(std::make_pair(t, --PI)); } // Insert copy from map[curr.first] to curr.second - TII->copyRegToReg(*MBB, MBB->getFirstTerminator(), curr.second, - map[curr.first], RC, RC); + BuildMI(*MBB, MBB->getFirstTerminator(), DebugLoc(), + TII->get(TargetOpcode::COPY), curr.second).addReg(map[curr.first]); map[curr.first] = curr.second; + DEBUG(dbgs() << "Inserted copy from " << curr.first << " to " + << curr.second << "\n"); // Push this copy onto InsertedPHICopies so we can // update LiveIntervals with it. @@ -697,15 +730,16 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, InsertedPHIDests.push_back(std::make_pair(curr.second, --MI)); // If curr.first is a destination in copy_set... - for (std::map::iterator I = copy_set.begin(), + for (std::multimap::iterator I = copy_set.begin(), E = copy_set.end(); I != E; ) if (curr.first == I->second) { std::pair temp = *I; + worklist.insert(temp); // Avoid iterator invalidation + std::multimap::iterator OI = I; ++I; - copy_set.erase(temp.first); - worklist.insert(temp); + copy_set.erase(OI); break; } else { @@ -714,24 +748,38 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, } if (!copy_set.empty()) { - std::pair curr = *copy_set.begin(); - copy_set.erase(curr.first); - - const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(curr.first); + std::multimap::iterator CI = copy_set.begin(); + std::pair curr = *CI; + worklist.insert(curr); + copy_set.erase(CI); - // Insert a copy from dest to a new temporary t at the end of b - unsigned t = MF->getRegInfo().createVirtualRegister(RC); - TII->copyRegToReg(*MBB, MBB->getFirstTerminator(), t, - curr.second, RC, RC); - map[curr.second] = t; + LiveInterval& I = LI.getInterval(curr.second); + MachineBasicBlock::iterator term = MBB->getFirstTerminator(); + SlotIndex endIdx = SlotIndex(); + if (term != MBB->end()) + endIdx = LI.getInstructionIndex(term); + else + endIdx = LI.getMBBEndIdx(MBB); - worklist.insert(curr); + if (I.liveAt(endIdx)) { + const TargetRegisterClass *RC = + MF->getRegInfo().getRegClass(curr.first); + + // Insert a copy from dest to a new temporary t at the end of b + unsigned t = MF->getRegInfo().createVirtualRegister(RC); + BuildMI(*MBB, MBB->getFirstTerminator(), DebugLoc(), + TII->get(TargetOpcode::COPY), t).addReg(curr.second); + map[curr.second] = t; + + MachineBasicBlock::iterator TI = MBB->getFirstTerminator(); + InsertedPHIDests.push_back(std::make_pair(t, --TI)); + } } } // Renumber the instructions so that we can perform the index computations // needed to create new live intervals. - LI.computeNumbering(); + LI.renumber(); // For copies that we inserted at the ends of predecessors, we construct // live intervals. This is pretty easy, since we know that the destination @@ -740,35 +788,69 @@ void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB, // PHI, we don't create multiple overlapping live intervals. std::set RegHandled; for (SmallVector, 4>::iterator I = - InsertedPHIDests.begin(), E = InsertedPHIDests.end(); I != E; ++I) - if (RegHandled.insert(I->first).second) - LI.addLiveRangeToEndOfBlock(I->first, I->second); + InsertedPHIDests.begin(), E = InsertedPHIDests.end(); I != E; ++I) { + if (RegHandled.insert(I->first).second) { + LiveInterval& Int = LI.getOrCreateInterval(I->first); + SlotIndex instrIdx = LI.getInstructionIndex(I->second); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(I->second->getParent()).getNextSlot(), + true); + + LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, I->second); + R.valno->setCopy(I->second); + R.valno->def = LI.getInstructionIndex(I->second).getDefIndex(); + } + } } /// InsertCopies - insert copies into MBB and all of its successors -void StrongPHIElimination::InsertCopies(MachineBasicBlock* MBB, +void StrongPHIElimination::InsertCopies(MachineDomTreeNode* MDTN, SmallPtrSet& visited) { + MachineBasicBlock* MBB = MDTN->getBlock(); visited.insert(MBB); std::set pushed; + LiveIntervals& LI = getAnalysis(); // Rewrite register uses from Stacks for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); - I != E; ++I) + I != E; ++I) { + if (I->isPHI()) + continue; + for (unsigned i = 0; i < I->getNumOperands(); ++i) - if (I->getOperand(i).isRegister() && + if (I->getOperand(i).isReg() && Stacks[I->getOperand(i).getReg()].size()) { + // Remove the live range for the old vreg. + LiveInterval& OldInt = LI.getInterval(I->getOperand(i).getReg()); + LiveInterval::iterator OldLR = + OldInt.FindLiveRangeContaining(LI.getInstructionIndex(I).getUseIndex()); + if (OldLR != OldInt.end()) + OldInt.removeRange(*OldLR, true); + + // Change the register I->getOperand(i).setReg(Stacks[I->getOperand(i).getReg()].back()); + + // Add a live range for the new vreg + LiveInterval& Int = LI.getInterval(I->getOperand(i).getReg()); + VNInfo* FirstVN = *Int.vni_begin(); + FirstVN->setHasPHIKill(false); + LiveRange LR (LI.getMBBStartIdx(I->getParent()), + LI.getInstructionIndex(I).getUseIndex().getNextSlot(), + FirstVN); + + Int.addRange(LR); } + } // Schedule the copies for this block ScheduleCopies(MBB, pushed); - // Recur to our successors - for (GraphTraits::ChildIteratorType I = - GraphTraits::child_begin(MBB), E = - GraphTraits::child_end(MBB); I != E; ++I) - if (!visited.count(*I)) + // Recur down the dominator tree. + for (MachineDomTreeNode::iterator I = MDTN->begin(), + E = MDTN->end(); I != E; ++I) + if (!visited.count((*I)->getBlock())) InsertCopies(*I, visited); // As we exit this block, pop the names we pushed while processing it @@ -777,68 +859,47 @@ void StrongPHIElimination::InsertCopies(MachineBasicBlock* MBB, Stacks[*I].pop_back(); } -void StrongPHIElimination::mergeLiveIntervals(unsigned primary, - unsigned secondary, - MachineBasicBlock* pred) { +bool StrongPHIElimination::mergeLiveIntervals(unsigned primary, + unsigned secondary) { LiveIntervals& LI = getAnalysis(); LiveInterval& LHS = LI.getOrCreateInterval(primary); LiveInterval& RHS = LI.getOrCreateInterval(secondary); - LI.computeNumbering(); - const LiveRange* RangeMergingIn = - RHS.getLiveRangeContaining(LI.getMBBEndIdx(pred)); - VNInfo* RHSVN = RangeMergingIn->valno; - VNInfo* NewVN = LHS.getNextValue(RangeMergingIn->valno->def, - RangeMergingIn->valno->copy, - LI.getVNInfoAllocator()); - - // If we discover that a live range was defined by a two-addr - // instruction, we need to merge over the input as well, even if - // it has a different VNInfo. - SmallPtrSet MergedVNs; - MergedVNs.insert(RHSVN); + LI.renumber(); DenseMap VNMap; - VNMap.insert(std::make_pair(RangeMergingIn->valno, NewVN)); - - // Find all VNs that are the inputs to two-address instructiosn - // chaining upwards from the VN we're trying to merge. - bool addedVN = true; - while (addedVN) { - addedVN = false; - unsigned defIndex = RHSVN->def; - - if (defIndex != ~0U) { - MachineInstr* instr = LI.getInstructionFromIndex(defIndex); - - for (unsigned i = 0; i < instr->getNumOperands(); ++i) { - if (instr->getOperand(i).isReg() && - instr->getOperand(i).getReg() == secondary) - if (instr->isRegReDefinedByTwoAddr(secondary, i)) { - RHSVN = RHS.getLiveRangeContaining(defIndex-1)->valno; - addedVN = true; - - VNInfo* NextVN = LHS.getNextValue(RHSVN->def, - RHSVN->copy, - LI.getVNInfoAllocator()); - VNMap.insert(std::make_pair(RHSVN, NextVN)); - - break; - } - } - } + for (LiveInterval::iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { + LiveRange R = *I; + + SlotIndex Start = R.start; + SlotIndex End = R.end; + if (LHS.getLiveRangeContaining(Start)) + return false; + + if (LHS.getLiveRangeContaining(End)) + return false; + + LiveInterval::iterator RI = std::upper_bound(LHS.begin(), LHS.end(), R); + if (RI != LHS.end() && RI->start < End) + return false; } - // Merge VNs from RHS into LHS using the mapping we computed above. - for (DenseMap::iterator VI = VNMap.begin(), - VE = VNMap.end(); VI != VE; ++VI) { - LHS.MergeValueInAsValue(RHS, VI->first, VI->second); - RHS.removeValNo(VI->first); + for (LiveInterval::iterator I = RHS.begin(), E = RHS.end(); I != E; ++I) { + LiveRange R = *I; + VNInfo* OldVN = R.valno; + VNInfo*& NewVN = VNMap[OldVN]; + if (!NewVN) { + NewVN = LHS.createValueCopy(OldVN, LI.getVNInfoAllocator()); + } + + LiveRange LR (R.start, R.end, NewVN); + LHS.addRange(LR); } - if (RHS.begin() == RHS.end()) - LI.removeInterval(RHS.reg); + LI.removeInterval(RHS.reg); + + return true; } bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { @@ -849,34 +910,94 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { // Determine which phi node operands need copies for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - if (!I->empty() && - I->begin()->getOpcode() == TargetInstrInfo::PHI) + if (!I->empty() && I->begin()->isPHI()) processBlock(I); + // Break interferences where two different phis want to coalesce + // in the same register. + std::set seen; + typedef std::map > + RenameSetType; + for (RenameSetType::iterator I = RenameSets.begin(), E = RenameSets.end(); + I != E; ++I) { + for (std::map::iterator + OI = I->second.begin(), OE = I->second.end(); OI != OE; ) { + if (!seen.count(OI->first)) { + seen.insert(OI->first); + ++OI; + } else { + Waiting[OI->second].insert(std::make_pair(OI->first, I->first)); + unsigned reg = OI->first; + ++OI; + I->second.erase(reg); + DEBUG(dbgs() << "Removing Renaming: " << reg << " -> " << I->first + << "\n"); + } + } + } + // Insert copies // FIXME: This process should probably preserve LiveIntervals SmallPtrSet visited; - InsertCopies(Fn.begin(), visited); + MachineDominatorTree& MDT = getAnalysis(); + InsertCopies(MDT.getRootNode(), visited); // Perform renaming - typedef std::map > - RenameSetType; for (RenameSetType::iterator I = RenameSets.begin(), E = RenameSets.end(); I != E; ++I) - for (std::map::iterator SI = - I->second.begin(), SE = I->second.end(); SI != SE; ++SI) { - mergeLiveIntervals(I->first, SI->first, SI->second); - Fn.getRegInfo().replaceRegWith(SI->first, I->first); + while (I->second.size()) { + std::map::iterator SI = I->second.begin(); + + DEBUG(dbgs() << "Renaming: " << SI->first << " -> " << I->first << "\n"); + + if (SI->first != I->first) { + if (mergeLiveIntervals(I->first, SI->first)) { + Fn.getRegInfo().replaceRegWith(SI->first, I->first); + + if (RenameSets.count(SI->first)) { + I->second.insert(RenameSets[SI->first].begin(), + RenameSets[SI->first].end()); + RenameSets.erase(SI->first); + } + } else { + // Insert a last-minute copy if a conflict was detected. + const TargetInstrInfo *TII = Fn.getTarget().getInstrInfo(); + BuildMI(*SI->second, SI->second->getFirstTerminator(), DebugLoc(), + TII->get(TargetOpcode::COPY), I->first).addReg(SI->first); + + LI.renumber(); + + LiveInterval& Int = LI.getOrCreateInterval(I->first); + SlotIndex instrIdx = + LI.getInstructionIndex(--SI->second->getFirstTerminator()); + if (Int.liveAt(instrIdx.getDefIndex())) + Int.removeRange(instrIdx.getDefIndex(), + LI.getMBBEndIdx(SI->second).getNextSlot(), true); + + LiveRange R = LI.addLiveRangeToEndOfBlock(I->first, + --SI->second->getFirstTerminator()); + R.valno->setCopy(--SI->second->getFirstTerminator()); + R.valno->def = instrIdx.getDefIndex(); + + DEBUG(dbgs() << "Renaming failed: " << SI->first << " -> " + << I->first << "\n"); + } + } + + LiveInterval& Int = LI.getOrCreateInterval(I->first); + const LiveRange* LR = + Int.getLiveRangeContaining(LI.getMBBEndIdx(SI->second)); + LR->valno->setHasPHIKill(true); + + I->second.erase(SI->first); } - // FIXME: Insert last-minute copies - // Remove PHIs std::vector phis; for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { for (MachineBasicBlock::iterator BI = I->begin(), BE = I->end(); BI != BE; ++BI) - if (BI->getOpcode() == TargetInstrInfo::PHI) + if (BI->isPHI()) phis.push_back(BI); } @@ -891,7 +1012,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { if (PI.containsOneValue()) { LI.removeInterval(DestReg); } else { - unsigned idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); PI.removeRange(*PI.getLiveRangeContaining(idx), true); } } else { @@ -900,12 +1021,12 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { // trim them because they might have other legitimate uses. for (unsigned i = 1; i < PInstr->getNumOperands(); i += 2) { unsigned reg = PInstr->getOperand(i).getReg(); + MachineBasicBlock* MBB = PInstr->getOperand(i+1).getMBB(); LiveInterval& InputI = LI.getInterval(reg); if (MBB != PInstr->getParent() && InputI.liveAt(LI.getMBBStartIdx(PInstr->getParent())) && - InputI.expiredAt(LI.getInstructionIndex(PInstr) + - LiveIntervals::InstrSlots::NUM)) + InputI.expiredAt(LI.getInstructionIndex(PInstr).getNextIndex())) InputI.removeRange(LI.getMBBStartIdx(PInstr->getParent()), LI.getInstructionIndex(PInstr), true); @@ -913,9 +1034,9 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { // If the PHI is not dead, then the valno defined by the PHI // now has an unknown def. - unsigned idx = LI.getDefIndex(LI.getInstructionIndex(PInstr)); + SlotIndex idx = LI.getInstructionIndex(PInstr).getDefIndex(); const LiveRange* PLR = PI.getLiveRangeContaining(idx); - PLR->valno->def = ~0U; + PLR->valno->setIsPHIDef(true); LiveRange R (LI.getMBBStartIdx(PInstr->getParent()), PLR->start, PLR->valno); PI.addRange(R); @@ -925,7 +1046,7 @@ bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) { PInstr->eraseFromParent(); } - LI.computeNumbering(); + LI.renumber(); return true; }