diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 35 | ||||
-rw-r--r-- | lib/CodeGen/BranchFolding.cpp | 20 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 137 | ||||
-rw-r--r-- | lib/CodeGen/MachineVerifier.cpp | 177 | ||||
-rw-r--r-- | lib/CodeGen/PHIElimination.cpp | 34 | ||||
-rw-r--r-- | lib/CodeGen/PHIElimination.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/RegAllocLinearScan.cpp | 21 | ||||
-rw-r--r-- | lib/CodeGen/Spiller.cpp | 287 | ||||
-rw-r--r-- | lib/CodeGen/Spiller.h | 12 | ||||
-rw-r--r-- | lib/CodeGen/TwoAddressInstructionPass.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/VirtRegRewriter.cpp | 31 |
11 files changed, 325 insertions, 449 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index 1c8b8f4..fcdcfd3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -727,7 +727,8 @@ void DwarfException::EmitExceptionTable() { // somewhere. This predicate should be moved to a shared location that is // in target-independent code. // - if (LSDASection->getKind().isWriteable() || + if ((LSDASection->getKind().isWriteable() && + !LSDASection->getKind().isReadOnlyWithRel()) || Asm->TM.getRelocationModel() == Reloc::Static) TTypeFormat = dwarf::DW_EH_PE_absptr; else @@ -917,14 +918,36 @@ void DwarfException::EmitExceptionTable() { } // Emit the Catch TypeInfos. + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); + unsigned Index = 1; + for (std::vector<GlobalVariable *>::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { - const GlobalVariable *GV = *I; - PrintRelDirective(); - - if (GV) { - O << Asm->Mang->getMangledName(GV); + const GlobalVariable *TI = *I; + + if (TI) { + if (!LSDASection->getKind().isReadOnlyWithRel() && + (TTypeFormat == dwarf::DW_EH_PE_absptr || + TI->getLinkage() == GlobalValue::InternalLinkage)) { + // Print out the unadorned name of the type info. + PrintRelDirective(); + O << Asm->Mang->getMangledName(TI); + } else { + bool IsTypeInfoIndirect = false, IsTypeInfoPCRel = false; + const MCExpr *TypeInfoRef = + TLOF.getSymbolForDwarfGlobalReference(TI, Asm->Mang, Asm->MMI, + IsTypeInfoIndirect, + IsTypeInfoPCRel); + + if (!IsTypeInfoPCRel) + TypeInfoRef = CreateLabelDiff(TypeInfoRef, "typeinforef_addr", + Index++); + + O << MAI->getData32bitsDirective(); + TypeInfoRef->print(O, MAI); + } } else { + PrintRelDirective(); O << "0x0"; } diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index 94bfb72..f807e8f 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -41,8 +41,12 @@ using namespace llvm; STATISTIC(NumDeadBlocks, "Number of dead blocks removed"); STATISTIC(NumBranchOpts, "Number of branches optimized"); STATISTIC(NumTailMerge , "Number of block tails merged"); +STATISTIC(NumTailDups , "Number of tail duplicated blocks"); +STATISTIC(NumInstrDups , "Additional instructions due to tail duplication"); + static cl::opt<cl::boolOrDefault> FlagEnableTailMerge("enable-tail-merge", cl::init(cl::BOU_UNSET), cl::Hidden); + // Throttle for huge numbers of predecessors (compile speed problems) static cl::opt<unsigned> TailMergeThreshold("tail-merge-threshold", @@ -193,7 +197,6 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF, MadeChange |= OptimizeImpDefsBlock(MBB); } - bool MadeChangeThisIteration = true; while (MadeChangeThisIteration) { MadeChangeThisIteration = false; @@ -202,10 +205,15 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF, MadeChange |= MadeChangeThisIteration; } - // Do tail duplication once after tail merging is done. Otherwise it is + // Do tail duplication after tail merging is done. Otherwise it is // tough to avoid situations where tail duplication and tail merging undo // each other's transformations ad infinitum. - MadeChange |= TailDuplicateBlocks(MF); + MadeChangeThisIteration = true; + while (MadeChangeThisIteration) { + MadeChangeThisIteration = false; + MadeChangeThisIteration |= TailDuplicateBlocks(MF); + MadeChange |= MadeChangeThisIteration; + } // See if any jump tables have become mergable or dead as the code generator // did its thing. @@ -1003,9 +1011,6 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1, bool BranchFolder::TailDuplicateBlocks(MachineFunction &MF) { bool MadeChange = false; - // Make sure blocks are numbered in order - MF.RenumberBlocks(); - for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = I++; @@ -1017,6 +1022,7 @@ bool BranchFolder::TailDuplicateBlocks(MachineFunction &MF) { // If it is dead, remove it. if (MBB->pred_empty()) { + NumInstrDups -= MBB->size(); RemoveDeadBlock(MBB); MadeChange = true; ++NumDeadBlocks; @@ -1097,6 +1103,7 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB, MachineInstr *NewMI = MF.CloneMachineInstr(I); PredBB->insert(PredBB->end(), NewMI); } + NumInstrDups += TailBB->size() - 1; // subtract one for removed branch // Update the CFG. PredBB->removeSuccessor(PredBB->succ_begin()); @@ -1107,6 +1114,7 @@ bool BranchFolder::TailDuplicate(MachineBasicBlock *TailBB, PredBB->addSuccessor(*I); Changed = true; + ++NumTailDups; } // If TailBB was duplicated into all its predecessors except for the prior diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index a60d34f..bbfc82b 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -53,16 +53,9 @@ static cl::opt<bool> DisableReMat("disable-rematerialization", static cl::opt<bool> EnableFastSpilling("fast-spill", cl::init(false), cl::Hidden); -static cl::opt<bool> EarlyCoalescing("early-coalescing", - cl::init(false), cl::Hidden); - -static cl::opt<int> CoalescingLimit("early-coalescing-limit", - cl::init(-1), cl::Hidden); - STATISTIC(numIntervals , "Number of original intervals"); STATISTIC(numFolds , "Number of loads/stores folded into instructions"); STATISTIC(numSplits , "Number of intervals split"); -STATISTIC(numCoalescing, "Number of early coalescing performed"); char LiveIntervals::ID = 0; static RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis"); @@ -96,7 +89,6 @@ void LiveIntervals::releaseMemory() { delete I->second; r2iMap_.clear(); - phiJoinCopies.clear(); // Release VNInfo memroy regions after all VNInfo objects are dtor'd. VNInfoAllocator.Reset(); @@ -121,7 +113,6 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) { allocatableRegs_ = tri_->getAllocatableSet(fn); computeIntervals(); - performEarlyCoalescing(); numIntervals += getNumIntervals(); @@ -409,7 +400,6 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb, // Remove the old range that we now know has an incorrect number. VNInfo *VNI = interval.getValNumInfo(0); MachineInstr *Killer = vi.Kills[0]; - phiJoinCopies.push_back(Killer); SlotIndex Start = getMBBStartIdx(Killer->getParent()); SlotIndex End = getInstructionIndex(Killer).getDefIndex(); DEBUG({ @@ -653,133 +643,6 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, DEBUG(errs() << " +" << LR << '\n'); } -bool LiveIntervals:: -isSafeAndProfitableToCoalesce(LiveInterval &DstInt, - LiveInterval &SrcInt, - SmallVector<MachineInstr*,16> &IdentCopies, - SmallVector<MachineInstr*,16> &OtherCopies) { - unsigned NumIdent = 0; - for (MachineRegisterInfo::def_iterator ri = mri_->def_begin(SrcInt.reg), - re = mri_->def_end(); ri != re; ++ri) { - MachineInstr *MI = &*ri; - unsigned SrcReg, DstReg, SrcSubReg, DstSubReg; - if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg)) - return false; - if (SrcReg != DstInt.reg) { - // Non-identity copy - we cannot handle overlapping intervals - if (DstInt.liveAt(getInstructionIndex(MI))) - return false; - OtherCopies.push_back(MI); - } else { - IdentCopies.push_back(MI); - ++NumIdent; - } - } - - return IdentCopies.size() > OtherCopies.size(); -} - -void LiveIntervals::performEarlyCoalescing() { - if (!EarlyCoalescing) - return; - - /// Perform early coalescing: eliminate copies which feed into phi joins - /// and whose sources are defined by the phi joins. - for (unsigned i = 0, e = phiJoinCopies.size(); i != e; ++i) { - MachineInstr *Join = phiJoinCopies[i]; - if (CoalescingLimit != -1 && (int)numCoalescing == CoalescingLimit) - break; - - unsigned PHISrc, PHIDst, SrcSubReg, DstSubReg; - bool isMove= tii_->isMoveInstr(*Join, PHISrc, PHIDst, SrcSubReg, DstSubReg); -#ifndef NDEBUG - assert(isMove && "PHI join instruction must be a move!"); -#else - isMove = isMove; -#endif - - LiveInterval &DstInt = getInterval(PHIDst); - LiveInterval &SrcInt = getInterval(PHISrc); - SmallVector<MachineInstr*, 16> IdentCopies; - SmallVector<MachineInstr*, 16> OtherCopies; - if (!isSafeAndProfitableToCoalesce(DstInt, SrcInt, - IdentCopies, OtherCopies)) - continue; - - DEBUG(errs() << "PHI Join: " << *Join); - assert(DstInt.containsOneValue() && "PHI join should have just one val#!"); - assert(std::distance(mri_->use_begin(PHISrc), mri_->use_end()) == 1 && - "PHI join src should not be used elsewhere"); - VNInfo *VNI = DstInt.getValNumInfo(0); - - // Change the non-identity copies to directly target the phi destination. - for (unsigned i = 0, e = OtherCopies.size(); i != e; ++i) { - MachineInstr *PHICopy = OtherCopies[i]; - SlotIndex MIIndex = getInstructionIndex(PHICopy); - DEBUG(errs() << "Moving: " << MIIndex << ' ' << *PHICopy); - SlotIndex DefIndex = MIIndex.getDefIndex(); - LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - SlotIndex StartIndex = SLR->start; - SlotIndex EndIndex = SLR->end; - - // Delete val# defined by the now identity copy and add the range from - // beginning of the mbb to the end of the range. - SrcInt.removeValNo(SLR->valno); - DEBUG(errs() << " added range [" << StartIndex << ',' - << EndIndex << "] to reg" << DstInt.reg << '\n'); - assert (!DstInt.liveAt(StartIndex) && "Cannot coalesce when dst live!"); - VNInfo *NewVNI = DstInt.getNextValue(DefIndex, PHICopy, true, - VNInfoAllocator); - NewVNI->setHasPHIKill(true); - DstInt.addRange(LiveRange(StartIndex, EndIndex, NewVNI)); - for (unsigned j = 0, ee = PHICopy->getNumOperands(); j != ee; ++j) { - MachineOperand &MO = PHICopy->getOperand(j); - if (!MO.isReg() || MO.getReg() != PHISrc) - continue; - MO.setReg(PHIDst); - } - } - - // Now let's eliminate all the would-be identity copies. - for (unsigned i = 0, e = IdentCopies.size(); i != e; ++i) { - MachineInstr *PHICopy = IdentCopies[i]; - DEBUG(errs() << "Coalescing: " << *PHICopy); - - SlotIndex MIIndex = getInstructionIndex(PHICopy); - SlotIndex DefIndex = MIIndex.getDefIndex(); - LiveRange *SLR = SrcInt.getLiveRangeContaining(DefIndex); - SlotIndex StartIndex = SLR->start; - SlotIndex EndIndex = SLR->end; - - // Delete val# defined by the now identity copy and add the range from - // beginning of the mbb to the end of the range. - SrcInt.removeValNo(SLR->valno); - RemoveMachineInstrFromMaps(PHICopy); - PHICopy->eraseFromParent(); - DEBUG(errs() << " added range [" << StartIndex << ',' - << EndIndex << "] to reg" << DstInt.reg << '\n'); - DstInt.addRange(LiveRange(StartIndex, EndIndex, VNI)); - } - - // Remove the phi join and update the phi block liveness. - SlotIndex MIIndex = getInstructionIndex(Join); - SlotIndex UseIndex = MIIndex.getUseIndex(); - SlotIndex DefIndex = MIIndex.getDefIndex(); - LiveRange *SLR = SrcInt.getLiveRangeContaining(UseIndex); - LiveRange *DLR = DstInt.getLiveRangeContaining(DefIndex); - DLR->valno->setCopy(0); - DLR->valno->setIsDefAccurate(false); - DstInt.addRange(LiveRange(SLR->start, SLR->end, DLR->valno)); - SrcInt.removeRange(SLR->start, SLR->end); - assert(SrcInt.empty()); - removeInterval(PHISrc); - RemoveMachineInstrFromMaps(Join); - Join->eraseFromParent(); - - ++numCoalescing; - } -} - /// computeIntervals - computes the live intervals for virtual /// registers. for some ordering of the machine instructions [1,N] a /// live interval is an interval [i, j) where 1 <= i <= j < N for diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index be9f68f..a1c74c0 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -42,23 +42,18 @@ using namespace llvm; namespace { - struct MachineVerifier : public MachineFunctionPass { - static char ID; // Pass ID, replacement for typeid + struct MachineVerifier { - MachineVerifier(bool allowDoubleDefs = false) : - MachineFunctionPass(&ID), + MachineVerifier(Pass *pass, bool allowDoubleDefs) : + PASS(pass), allowVirtDoubleDefs(allowDoubleDefs), allowPhysDoubleDefs(allowDoubleDefs), OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS")) - {} - - void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - MachineFunctionPass::getAnalysisUsage(AU); - } + {} bool runOnMachineFunction(MachineFunction &MF); + Pass *const PASS; const bool allowVirtDoubleDefs; const bool allowPhysDoubleDefs; @@ -112,6 +107,10 @@ namespace { // regsKilled and regsLiveOut. RegSet vregsPassed; + // Vregs that must pass through MBB because they are needed by a successor + // block. This set is disjoint from regsLiveOut. + RegSet vregsRequired; + BBInfo() : reachable(false) {} // Add register to vregsPassed if it belongs there. Return true if @@ -133,6 +132,34 @@ namespace { return changed; } + // Add register to vregsRequired if it belongs there. Return true if + // anything changed. + bool addRequired(unsigned Reg) { + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + return false; + if (regsLiveOut.count(Reg)) + return false; + return vregsRequired.insert(Reg).second; + } + + // Same for a full set. + bool addRequired(const RegSet &RS) { + bool changed = false; + for (RegSet::const_iterator I = RS.begin(), E = RS.end(); I != E; ++I) + if (addRequired(*I)) + changed = true; + return changed; + } + + // Same for a full map. + bool addRequired(const RegMap &RM) { + bool changed = false; + for (RegMap::const_iterator I = RM.begin(), E = RM.end(); I != E; ++I) + if (addRequired(I->first)) + changed = true; + return changed; + } + // Live-out registers are either in regsLiveOut or vregsPassed. bool isLiveOut(unsigned Reg) const { return regsLiveOut.count(Reg) || vregsPassed.count(Reg); @@ -146,6 +173,9 @@ namespace { return Reg < regsReserved.size() && regsReserved.test(Reg); } + // Analysis information if available + LiveVariables *LiveVars; + void visitMachineFunctionBefore(); void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB); void visitMachineInstrBefore(const MachineInstr *MI); @@ -163,20 +193,44 @@ namespace { void calcMaxRegsPassed(); void calcMinRegsPassed(); void checkPHIOps(const MachineBasicBlock *MBB); + + void calcRegsRequired(); + void verifyLiveVariables(); + }; + + struct MachineVerifierPass : public MachineFunctionPass { + static char ID; // Pass ID, replacement for typeid + bool AllowDoubleDefs; + + explicit MachineVerifierPass(bool allowDoubleDefs = false) + : MachineFunctionPass(&ID), + AllowDoubleDefs(allowDoubleDefs) {} + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + bool runOnMachineFunction(MachineFunction &MF) { + MF.verify(this, AllowDoubleDefs); + return false; + } }; + } -char MachineVerifier::ID = 0; -static RegisterPass<MachineVerifier> +char MachineVerifierPass::ID = 0; +static RegisterPass<MachineVerifierPass> MachineVer("machineverifier", "Verify generated machine code"); static const PassInfo *const MachineVerifyID = &MachineVer; FunctionPass *llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) { - return new MachineVerifier(allowPhysDoubleDefs); + return new MachineVerifierPass(allowPhysDoubleDefs); } -void MachineFunction::verify() const { - MachineVerifier().runOnMachineFunction(const_cast<MachineFunction&>(*this)); +void MachineFunction::verify(Pass *p, bool allowDoubleDefs) const { + MachineVerifier(p, allowDoubleDefs) + .runOnMachineFunction(const_cast<MachineFunction&>(*this)); } bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { @@ -202,6 +256,12 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) { TRI = TM->getRegisterInfo(); MRI = &MF.getRegInfo(); + if (PASS) { + LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>(); + } else { + LiveVars = NULL; + } + visitMachineFunctionBefore(); for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end(); MFI!=MFE; ++MFI) { @@ -518,8 +578,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { } else if (MO->isUse()) { regsLiveInButUnused.erase(Reg); + bool isKill = false; if (MO->isKill()) { - addRegWithSubRegs(regsKilled, Reg); + isKill = true; // Tied operands on two-address instuctions MUST NOT have a <kill> flag. if (MI->isRegTiedToDefOperand(MONum)) report("Illegal kill flag on two-address instruction operand", @@ -529,8 +590,20 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { unsigned defIdx; if (MI->isRegTiedToDefOperand(MONum, &defIdx) && MI->getOperand(defIdx).getReg() == Reg) - addRegWithSubRegs(regsKilled, Reg); + isKill = true; + } + if (isKill) { + addRegWithSubRegs(regsKilled, Reg); + + // Check that LiveVars knows this kill + if (LiveVars && TargetRegisterInfo::isVirtualRegister(Reg)) { + LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg); + if (std::find(VI.Kills.begin(), + VI.Kills.end(), MI) == VI.Kills.end()) + report("Kill missing from LiveVariables", MO, MONum); + } } + // Use of a dead register. if (!regsLive.count(Reg)) { if (TargetRegisterInfo::isPhysicalRegister(Reg)) { @@ -734,6 +807,41 @@ void MachineVerifier::calcMinRegsPassed() { } } +// Calculate the set of virtual registers that must be passed through each basic +// block in order to satisfy the requirements of successor blocks. This is very +// similar to calcMaxRegsPassed, only backwards. +void MachineVerifier::calcRegsRequired() { + // First push live-in regs to predecessors' vregsRequired. + DenseSet<const MachineBasicBlock*> todo; + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) { + const MachineBasicBlock &MBB(*MFI); + BBInfo &MInfo = MBBInfoMap[&MBB]; + for (MachineBasicBlock::const_pred_iterator PrI = MBB.pred_begin(), + PrE = MBB.pred_end(); PrI != PrE; ++PrI) { + BBInfo &PInfo = MBBInfoMap[*PrI]; + if (PInfo.addRequired(MInfo.vregsLiveIn)) + todo.insert(*PrI); + } + } + + // Iteratively push vregsRequired to predecessors. This will converge to the + // same final state regardless of DenseSet iteration order. + while (!todo.empty()) { + const MachineBasicBlock *MBB = *todo.begin(); + todo.erase(MBB); + BBInfo &MInfo = MBBInfoMap[MBB]; + for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(), + PrE = MBB->pred_end(); PrI != PrE; ++PrI) { + if (*PrI == MBB) + continue; + BBInfo &SInfo = MBBInfoMap[*PrI]; + if (SInfo.addRequired(MInfo.vregsRequired)) + todo.insert(*PrI); + } + } +} + // Check PHI instructions at the beginning of MBB. It is assumed that // calcMinRegsPassed has been run so BBInfo::isLiveOut is valid. void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) { @@ -849,4 +957,39 @@ void MachineVerifier::visitMachineFunctionAfter() { } } } + + // Now check LiveVariables info if available + if (LiveVars) { + calcRegsRequired(); + verifyLiveVariables(); + } } + +void MachineVerifier::verifyLiveVariables() { + assert(LiveVars && "Don't call verifyLiveVariables without LiveVars"); + for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister, + RegE = MRI->getLastVirtReg()-1; Reg != RegE; ++Reg) { + LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg); + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) { + BBInfo &MInfo = MBBInfoMap[MFI]; + + // Our vregsRequired should be identical to LiveVariables' AliveBlocks + if (MInfo.vregsRequired.count(Reg)) { + if (!VI.AliveBlocks.test(MFI->getNumber())) { + report("LiveVariables: Block missing from AliveBlocks", MFI); + *OS << "Virtual register %reg" << Reg + << " must be live through the block.\n"; + } + } else { + if (VI.AliveBlocks.test(MFI->getNumber())) { + report("LiveVariables: Block should not be in AliveBlocks", MFI); + *OS << "Virtual register %reg" << Reg + << " is not needed live through the block.\n"; + } + } + } + } +} + + diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp index cd38dd1..b3802ed 100644 --- a/lib/CodeGen/PHIElimination.cpp +++ b/lib/CodeGen/PHIElimination.cpp @@ -21,7 +21,6 @@ #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/Function.h" #include "llvm/Target/TargetMachine.h" #include "llvm/ADT/SmallPtrSet.h" @@ -37,37 +36,17 @@ using namespace llvm; STATISTIC(NumAtomic, "Number of atomic phis lowered"); STATISTIC(NumSplits, "Number of critical edges split on demand"); -static cl::opt<bool> -SplitEdges("split-phi-edges", - cl::desc("Split critical edges during phi elimination"), - cl::init(false), cl::Hidden); - char PHIElimination::ID = 0; static RegisterPass<PHIElimination> X("phi-node-elimination", "Eliminate PHI nodes for register allocation"); const PassInfo *const llvm::PHIEliminationID = &X; -namespace llvm { FunctionPass *createLocalRegisterAllocator(); } - -// Should we run edge splitting? -static bool shouldSplitEdges() { - // Edge splitting breaks the local register allocator. It cannot tolerate - // LiveVariables being run. - if (RegisterRegAlloc::getDefault() == createLocalRegisterAllocator) - return false; - return SplitEdges; -} - void llvm::PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const { AU.addPreserved<LiveVariables>(); AU.addPreserved<MachineDominatorTree>(); - if (shouldSplitEdges()) { - AU.addRequired<LiveVariables>(); - } else { - AU.setPreservesCFG(); - AU.addPreservedID(MachineLoopInfoID); - } + // rdar://7401784 This would be nice: + // AU.addPreservedID(MachineLoopInfoID); MachineFunctionPass::getAnalysisUsage(AU); } @@ -79,9 +58,9 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) { bool Changed = false; // Split critical edges to help the coalescer - if (shouldSplitEdges()) + if (LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>()) for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) - Changed |= SplitPHIEdges(Fn, *I); + Changed |= SplitPHIEdges(Fn, *I, *LV); // Populate VRegPHIUseCount analyzePHINodes(Fn); @@ -361,10 +340,11 @@ void llvm::PHIElimination::analyzePHINodes(const MachineFunction& Fn) { } bool llvm::PHIElimination::SplitPHIEdges(MachineFunction &MF, - MachineBasicBlock &MBB) { + MachineBasicBlock &MBB, + LiveVariables &LV) { if (MBB.empty() || MBB.front().getOpcode() != TargetInstrInfo::PHI) return false; // Quick exit for basic blocks without PHIs. - LiveVariables &LV = getAnalysis<LiveVariables>(); + for (MachineBasicBlock::const_iterator BBI = MBB.begin(), BBE = MBB.end(); BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) { for (unsigned i = 1, e = BBI->getNumOperands(); i != e; i += 2) { diff --git a/lib/CodeGen/PHIElimination.h b/lib/CodeGen/PHIElimination.h index 94716ee..f8c9fe7 100644 --- a/lib/CodeGen/PHIElimination.h +++ b/lib/CodeGen/PHIElimination.h @@ -90,7 +90,8 @@ namespace llvm { void analyzePHINodes(const MachineFunction& Fn); /// Split critical edges where necessary for good coalescer performance. - bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB); + bool SplitPHIEdges(MachineFunction &MF, MachineBasicBlock &MBB, + LiveVariables &LV); /// isLiveOut - Determine if Reg is live out from MBB, when not /// considering PHI nodes. This means that Reg is either killed by diff --git a/lib/CodeGen/RegAllocLinearScan.cpp b/lib/CodeGen/RegAllocLinearScan.cpp index 6930abf..fff50da 100644 --- a/lib/CodeGen/RegAllocLinearScan.cpp +++ b/lib/CodeGen/RegAllocLinearScan.cpp @@ -59,11 +59,6 @@ PreSplitIntervals("pre-alloc-split", cl::desc("Pre-register allocation live interval splitting"), cl::init(false), cl::Hidden); -static cl::opt<bool> -NewSpillFramework("new-spill-framework", - cl::desc("New spilling framework"), - cl::init(false), cl::Hidden); - static RegisterRegAlloc linearscanRegAlloc("linearscan", "linear scan register allocator", createLinearScanRegisterAllocator); @@ -441,9 +436,7 @@ bool RALinScan::runOnMachineFunction(MachineFunction &fn) { vrm_ = &getAnalysis<VirtRegMap>(); if (!rewriter_.get()) rewriter_.reset(createVirtRegRewriter()); - if (NewSpillFramework) { - spiller_.reset(createSpiller(mf_, li_, ls_, vrm_)); - } + spiller_.reset(createSpiller(mf_, li_, ls_, loopInfo, vrm_)); initIntervalSets(); @@ -1157,11 +1150,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { SmallVector<LiveInterval*, 8> spillIs; std::vector<LiveInterval*> added; - if (!NewSpillFramework) { - added = li_->addIntervalsForSpills(*cur, spillIs, loopInfo, *vrm_); - } else { - added = spiller_->spill(cur); - } + added = spiller_->spill(cur, spillIs); std::sort(added.begin(), added.end(), LISorter()); addStackInterval(cur, ls_, li_, mri_, *vrm_); @@ -1241,11 +1230,7 @@ void RALinScan::assignRegOrStackSlotAtInterval(LiveInterval* cur) { earliestStartInterval : sli; std::vector<LiveInterval*> newIs; - if (!NewSpillFramework) { - newIs = li_->addIntervalsForSpills(*sli, spillIs, loopInfo, *vrm_); - } else { - newIs = spiller_->spill(sli); - } + newIs = spiller_->spill(sli, spillIs); addStackInterval(sli, ls_, li_, mri_, *vrm_); std::copy(newIs.begin(), newIs.end(), std::back_inserter(added)); spilled.insert(sli->reg); diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp index 9107325..20c4a28 100644 --- a/lib/CodeGen/Spiller.cpp +++ b/lib/CodeGen/Spiller.cpp @@ -18,11 +18,25 @@ #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; +namespace { + enum SpillerName { trivial, standard }; +} + +static cl::opt<SpillerName> +spillerOpt("spiller", + cl::desc("Spiller to use: (default: standard)"), + cl::Prefix, + cl::values(clEnumVal(trivial, "trivial spiller"), + clEnumVal(standard, "default spiller"), + clEnumValEnd), + cl::init(standard)); + Spiller::~Spiller() {} namespace { @@ -49,153 +63,9 @@ protected: tii = mf->getTarget().getInstrInfo(); } - /// Ensures there is space before the given machine instruction, returns the - /// instruction's new number. - SlotIndex makeSpaceBefore(MachineInstr *mi) { - //if (!lis->hasGapBeforeInstr(lis->getInstructionIndex(mi))) { - // FIXME: Should be updated to use rewrite-in-place methods when they're - // introduced. Currently broken. - //lis->scaleNumbering(2); - //ls->scaleNumbering(2); - //} - - SlotIndex miIdx = lis->getInstructionIndex(mi); - - //assert(lis->hasGapBeforeInstr(miIdx)); - - return miIdx; - } - - /// Ensure there is space after the given machine instruction, returns the - /// instruction's new number. - SlotIndex makeSpaceAfter(MachineInstr *mi) { - //if (!lis->hasGapAfterInstr(lis->getInstructionIndex(mi))) { - // FIXME: Should be updated to use rewrite-in-place methods when they're - // introduced. Currently broken. - // lis->scaleNumbering(2); - // ls->scaleNumbering(2); - //} - - SlotIndex miIdx = lis->getInstructionIndex(mi); - - //assert(lis->hasGapAfterInstr(miIdx)); - - return miIdx; - } - - /// Insert a store of the given vreg to the given stack slot immediately - /// after the given instruction. Returns the base index of the inserted - /// instruction. The caller is responsible for adding an appropriate - /// LiveInterval to the LiveIntervals analysis. - SlotIndex insertStoreAfter(MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - - MachineBasicBlock::iterator nextInstItr(next(mi)); - - SlotIndex miIdx = makeSpaceAfter(mi); - - tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg, - true, ss, trc); - MachineBasicBlock::iterator storeInstItr(next(mi)); - MachineInstr *storeInst = &*storeInstItr; - - return lis->InsertMachineInstrInMaps(storeInst); - } - - /// Insert a store of the given vreg to the given stack slot immediately - /// before the given instructnion. Returns the base index of the inserted - /// Instruction. - SlotIndex insertStoreBefore(MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - SlotIndex miIdx = makeSpaceBefore(mi); - - tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc); - MachineBasicBlock::iterator storeInstItr(prior(mi)); - MachineInstr *storeInst = &*storeInstItr; - - return lis->InsertMachineInstrInMaps(storeInst); - } - - void insertStoreAfterInstOnInterval(LiveInterval *li, - MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - - SlotIndex storeInstIdx = insertStoreAfter(mi, ss, vreg, trc); - SlotIndex start = lis->getInstructionIndex(mi).getDefIndex(), - end = storeInstIdx.getUseIndex(); - - VNInfo *vni = - li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator()); - vni->addKill(storeInstIdx); - DEBUG(errs() << " Inserting store range: [" << start - << ", " << end << ")\n"); - LiveRange lr(start, end, vni); - - li->addRange(lr); - } - - /// Insert a load of the given vreg from the given stack slot immediately - /// after the given instruction. Returns the base index of the inserted - /// instruction. The caller is responsibel for adding/removing an appropriate - /// range vreg's LiveInterval. - SlotIndex insertLoadAfter(MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - - MachineBasicBlock::iterator nextInstItr(next(mi)); - - SlotIndex miIdx = makeSpaceAfter(mi); - - tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc); - MachineBasicBlock::iterator loadInstItr(next(mi)); - MachineInstr *loadInst = &*loadInstItr; - - return lis->InsertMachineInstrInMaps(loadInst); - } - - /// Insert a load of the given vreg from the given stack slot immediately - /// before the given instruction. Returns the base index of the inserted - /// instruction. The caller is responsible for adding an appropriate - /// LiveInterval to the LiveIntervals analysis. - SlotIndex insertLoadBefore(MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - SlotIndex miIdx = makeSpaceBefore(mi); - - tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc); - MachineBasicBlock::iterator loadInstItr(prior(mi)); - MachineInstr *loadInst = &*loadInstItr; - - return lis->InsertMachineInstrInMaps(loadInst); - } - - void insertLoadBeforeInstOnInterval(LiveInterval *li, - MachineInstr *mi, unsigned ss, - unsigned vreg, - const TargetRegisterClass *trc) { - - SlotIndex loadInstIdx = insertLoadBefore(mi, ss, vreg, trc); - SlotIndex start = loadInstIdx.getDefIndex(), - end = lis->getInstructionIndex(mi).getUseIndex(); - - VNInfo *vni = - li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator()); - vni->addKill(lis->getInstructionIndex(mi)); - DEBUG(errs() << " Intserting load range: [" << start - << ", " << end << ")\n"); - LiveRange lr(start, end, vni); - - li->addRange(lr); - } - - - /// Add spill ranges for every use/def of the live interval, inserting loads - /// immediately before each use, and stores after each def. No folding is - /// attempted. + /// immediately before each use, and stores after each def. No folding or + /// remat is attempted. std::vector<LiveInterval*> trivialSpillEverywhere(LiveInterval *li) { DEBUG(errs() << "Spilling everywhere " << *li << "\n"); @@ -212,56 +82,77 @@ protected: const TargetRegisterClass *trc = mri->getRegClass(li->reg); unsigned ss = vrm->assignVirt2StackSlot(li->reg); + // Iterate over reg uses/defs. for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) { + // Grab the use/def instr. MachineInstr *mi = &*regItr; DEBUG(errs() << " Processing " << *mi); + // Step regItr to the next use/def instr. do { ++regItr; } while (regItr != mri->reg_end() && (&*regItr == mi)); + // Collect uses & defs for this instr. SmallVector<unsigned, 2> indices; bool hasUse = false; bool hasDef = false; - for (unsigned i = 0; i != mi->getNumOperands(); ++i) { MachineOperand &op = mi->getOperand(i); - if (!op.isReg() || op.getReg() != li->reg) continue; - hasUse |= mi->getOperand(i).isUse(); hasDef |= mi->getOperand(i).isDef(); - indices.push_back(i); } + // Create a new vreg & interval for this instr. unsigned newVReg = mri->createVirtualRegister(trc); vrm->grow(); vrm->assignVirt2StackSlot(newVReg, ss); - LiveInterval *newLI = &lis->getOrCreateInterval(newVReg); newLI->weight = HUGE_VALF; + // Update the reg operands & kill flags. for (unsigned i = 0; i < indices.size(); ++i) { - mi->getOperand(indices[i]).setReg(newVReg); - - if (mi->getOperand(indices[i]).isUse()) { - mi->getOperand(indices[i]).setIsKill(true); + unsigned mopIdx = indices[i]; + MachineOperand &mop = mi->getOperand(mopIdx); + mop.setReg(newVReg); + if (mop.isUse() && !mi->isRegTiedToDefOperand(mopIdx)) { + mop.setIsKill(true); } } - assert(hasUse || hasDef); + // Insert reload if necessary. + MachineBasicBlock::iterator miItr(mi); if (hasUse) { - insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc); + tii->loadRegFromStackSlot(*mi->getParent(), miItr, newVReg, ss, trc); + MachineInstr *loadInstr(prior(miItr)); + SlotIndex loadIndex = + lis->InsertMachineInstrInMaps(loadInstr).getDefIndex(); + SlotIndex endIndex = loadIndex.getNextIndex(); + VNInfo *loadVNI = + newLI->getNextValue(loadIndex, 0, true, lis->getVNInfoAllocator()); + loadVNI->addKill(endIndex); + newLI->addRange(LiveRange(loadIndex, endIndex, loadVNI)); } + // Insert store if necessary. if (hasDef) { - insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc); + tii->storeRegToStackSlot(*mi->getParent(), next(miItr), newVReg, true, + ss, trc); + MachineInstr *storeInstr(next(miItr)); + SlotIndex storeIndex = + lis->InsertMachineInstrInMaps(storeInstr).getDefIndex(); + SlotIndex beginIndex = storeIndex.getPrevIndex(); + VNInfo *storeVNI = + newLI->getNextValue(beginIndex, 0, true, lis->getVNInfoAllocator()); + storeVNI->addKill(storeIndex); + newLI->addRange(LiveRange(beginIndex, storeIndex, storeVNI)); } added.push_back(newLI); @@ -279,60 +170,32 @@ class TrivialSpiller : public SpillerBase { public: TrivialSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, - VirtRegMap *vrm) : - SpillerBase(mf, lis, ls, vrm) {} + VirtRegMap *vrm) + : SpillerBase(mf, lis, ls, vrm) {} - std::vector<LiveInterval*> spill(LiveInterval *li) { + std::vector<LiveInterval*> spill(LiveInterval *li, + SmallVectorImpl<LiveInterval*> &spillIs) { + // Ignore spillIs - we don't use it. return trivialSpillEverywhere(li); } - std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) { - std::vector<LiveInterval*> spillIntervals; - - if (!valno->isDefAccurate() && !valno->isPHIDef()) { - // Early out for values which have no well defined def point. - return spillIntervals; - } - - // Ok.. we should be able to proceed... - const TargetRegisterClass *trc = mri->getRegClass(li->reg); - unsigned ss = vrm->assignVirt2StackSlot(li->reg); - vrm->grow(); - vrm->assignVirt2StackSlot(li->reg, ss); - - MachineInstr *mi = 0; - SlotIndex storeIdx = SlotIndex(); - - if (valno->isDefAccurate()) { - // If we have an accurate def we can just grab an iterator to the instr - // after the def. - mi = lis->getInstructionFromIndex(valno->def); - storeIdx = insertStoreAfter(mi, ss, li->reg, trc).getDefIndex(); - } else { - // if we get here we have a PHI def. - mi = &lis->getMBBFromIndex(valno->def)->front(); - storeIdx = insertStoreBefore(mi, ss, li->reg, trc).getDefIndex(); - } - - MachineBasicBlock *defBlock = mi->getParent(); - SlotIndex loadIdx = SlotIndex(); - - // Now we need to find the load... - MachineBasicBlock::iterator useItr(mi); - for (; !useItr->readsRegister(li->reg); ++useItr) {} - - if (useItr != defBlock->end()) { - MachineInstr *loadInst = useItr; - loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc).getUseIndex(); - } - else { - MachineInstr *loadInst = &defBlock->back(); - loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc).getUseIndex(); - } - - li->removeRange(storeIdx, loadIdx, true); +}; - return spillIntervals; +/// Falls back on LiveIntervals::addIntervalsForSpills. +class StandardSpiller : public Spiller { +private: + LiveIntervals *lis; + const MachineLoopInfo *loopInfo; + VirtRegMap *vrm; +public: + StandardSpiller(MachineFunction *mf, LiveIntervals *lis, LiveStacks *ls, + const MachineLoopInfo *loopInfo, VirtRegMap *vrm) + : lis(lis), loopInfo(loopInfo), vrm(vrm) {} + + /// Falls back on LiveIntervals::addIntervalsForSpills. + std::vector<LiveInterval*> spill(LiveInterval *li, + SmallVectorImpl<LiveInterval*> &spillIs) { + return lis->addIntervalsForSpills(*li, spillIs, loopInfo, *vrm); } }; @@ -340,6 +203,12 @@ public: } llvm::Spiller* llvm::createSpiller(MachineFunction *mf, LiveIntervals *lis, - LiveStacks *ls, VirtRegMap *vrm) { - return new TrivialSpiller(mf, lis, ls, vrm); + LiveStacks *ls, + const MachineLoopInfo *loopInfo, + VirtRegMap *vrm) { + switch (spillerOpt) { + case trivial: return new TrivialSpiller(mf, lis, ls, vrm); break; + case standard: return new StandardSpiller(mf, lis, ls, loopInfo, vrm); break; + default: llvm_unreachable("Unreachable!"); break; + } } diff --git a/lib/CodeGen/Spiller.h b/lib/CodeGen/Spiller.h index 9c3900d..7ec8e6d 100644 --- a/lib/CodeGen/Spiller.h +++ b/lib/CodeGen/Spiller.h @@ -10,6 +10,7 @@ #ifndef LLVM_CODEGEN_SPILLER_H #define LLVM_CODEGEN_SPILLER_H +#include "llvm/ADT/SmallVector.h" #include <vector> namespace llvm { @@ -19,6 +20,7 @@ namespace llvm { class LiveStacks; class MachineFunction; class MachineInstr; + class MachineLoopInfo; class VirtRegMap; class VNInfo; @@ -32,17 +34,15 @@ namespace llvm { /// Spill the given live range. The method used will depend on the Spiller /// implementation selected. - virtual std::vector<LiveInterval*> spill(LiveInterval *li) = 0; - - /// Intra-block split. - virtual std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, - VNInfo *valno) = 0; + virtual std::vector<LiveInterval*> spill(LiveInterval *li, + SmallVectorImpl<LiveInterval*> &spillIs) = 0; }; /// Create and return a spiller object, as specified on the command line. Spiller* createSpiller(MachineFunction *mf, LiveIntervals *li, - LiveStacks *ls, VirtRegMap *vrm); + LiveStacks *ls, const MachineLoopInfo *loopInfo, + VirtRegMap *vrm); } #endif diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp index 84467ed..5fa690b 100644 --- a/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -112,8 +112,7 @@ namespace { MachineBasicBlock *MBB, unsigned Dist); bool DeleteUnusedInstr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, - MachineFunction::iterator &mbbi, - unsigned regB, unsigned regBIdx, unsigned Dist); + MachineFunction::iterator &mbbi, unsigned Dist); bool TryInstructionTransform(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, @@ -730,7 +729,7 @@ void TwoAddressInstructionPass::ProcessCopy(MachineInstr *MI, /// isSafeToDelete - If the specified instruction does not produce any side /// effects and all of its defs are dead, then it's safe to delete. -static bool isSafeToDelete(MachineInstr *MI, unsigned Reg, +static bool isSafeToDelete(MachineInstr *MI, const TargetInstrInfo *TII, SmallVector<unsigned, 4> &Kills) { const TargetInstrDesc &TID = MI->getDesc(); @@ -745,10 +744,9 @@ static bool isSafeToDelete(MachineInstr *MI, unsigned Reg, continue; if (MO.isDef() && !MO.isDead()) return false; - if (MO.isUse() && MO.getReg() != Reg && MO.isKill()) + if (MO.isUse() && MO.isKill()) Kills.push_back(MO.getReg()); } - return true; } @@ -783,11 +781,10 @@ bool TwoAddressInstructionPass::DeleteUnusedInstr(MachineBasicBlock::iterator &mi, MachineBasicBlock::iterator &nmi, MachineFunction::iterator &mbbi, - unsigned regB, unsigned regBIdx, unsigned Dist) { // Check if the instruction has no side effects and if all its defs are dead. SmallVector<unsigned, 4> Kills; - if (!isSafeToDelete(mi, regB, TII, Kills)) + if (!isSafeToDelete(mi, TII, Kills)) return false; // If this instruction kills some virtual registers, we need to @@ -810,10 +807,6 @@ TwoAddressInstructionPass::DeleteUnusedInstr(MachineBasicBlock::iterator &mi, LV->addVirtualRegisterKilled(Kill, NewKill); } } - - // If regB was marked as a kill, update its Kills list. - if (mi->getOperand(regBIdx).isKill()) - LV->removeVirtualRegisterKilled(regB, mi); } mbbi->erase(mi); // Nuke the old inst. @@ -842,7 +835,7 @@ TryInstructionTransform(MachineBasicBlock::iterator &mi, // it so it doesn't clobber regB. bool regBKilled = isKilled(*mi, regB, MRI, TII); if (!regBKilled && mi->getOperand(DstIdx).isDead() && - DeleteUnusedInstr(mi, nmi, mbbi, regB, SrcIdx, Dist)) { + DeleteUnusedInstr(mi, nmi, mbbi, Dist)) { ++NumDeletes; return true; // Done with this instruction. } diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp index ec0abd1..c836286 100644 --- a/lib/CodeGen/VirtRegRewriter.cpp +++ b/lib/CodeGen/VirtRegRewriter.cpp @@ -77,27 +77,38 @@ struct TrivialRewriter : public VirtRegRewriter { DEBUG(MF.dump()); MachineRegisterInfo *mri = &MF.getRegInfo(); + const TargetRegisterInfo *tri = MF.getTarget().getRegisterInfo(); bool changed = false; for (LiveIntervals::iterator liItr = LIs->begin(), liEnd = LIs->end(); liItr != liEnd; ++liItr) { - if (TargetRegisterInfo::isVirtualRegister(liItr->first)) { - if (VRM.hasPhys(liItr->first)) { - unsigned preg = VRM.getPhys(liItr->first); - mri->replaceRegWith(liItr->first, preg); - mri->setPhysRegUsed(preg); - changed = true; - } + const LiveInterval *li = liItr->second; + unsigned reg = li->reg; + + if (TargetRegisterInfo::isPhysicalRegister(reg)) { + if (!li->empty()) + mri->setPhysRegUsed(reg); } else { - if (!liItr->second->empty()) { - mri->setPhysRegUsed(liItr->first); + if (!VRM.hasPhys(reg)) + continue; + unsigned pReg = VRM.getPhys(reg); + mri->setPhysRegUsed(pReg); + for (MachineRegisterInfo::reg_iterator regItr = mri->reg_begin(reg), + regEnd = mri->reg_end(); regItr != regEnd;) { + MachineOperand &mop = regItr.getOperand(); + assert(mop.isReg() && mop.getReg() == reg && "reg_iterator broken?"); + ++regItr; + unsigned subRegIdx = mop.getSubReg(); + unsigned pRegOp = subRegIdx ? tri->getSubReg(pReg, subRegIdx) : pReg; + mop.setReg(pRegOp); + mop.setSubReg(0); + changed = true; } } } - DEBUG(errs() << "**** Post Machine Instrs ****\n"); DEBUG(MF.dump()); |