diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/LiveInterval.cpp | 64 | ||||
-rw-r--r-- | llvm/lib/CodeGen/LiveIntervalAnalysis.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/MachineScheduler.cpp | 9 |
3 files changed, 60 insertions, 15 deletions
diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp index 16c036d0667..fc5a149d803 100644 --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -19,13 +19,17 @@ //===----------------------------------------------------------------------===// #include "llvm/CodeGen/LiveInterval.h" + +#include "PHIEliminationUtils.h" #include "RegisterCoalescer.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include <algorithm> using namespace llvm; @@ -1654,19 +1658,65 @@ void ConnectedSubRegClasses::distribute(const IntEqClasses &Classes, } } +static bool subRangeLiveAt(const LiveInterval &LI, SlotIndex Pos) { + for (const LiveInterval::SubRange &SR : LI.subranges()) { + if (SR.liveAt(Pos)) + return true; + } + return false; +} + void ConnectedSubRegClasses::computeMainRangesFixFlags( const IntEqClasses &Classes, const SmallVectorImpl<SubRangeInfo> &SubRangeInfos, const SmallVectorImpl<LiveInterval*> &Intervals) const { BumpPtrAllocator &Allocator = LIS.getVNInfoAllocator(); + const SlotIndexes &Indexes = *LIS.getSlotIndexes(); for (size_t I = 0, E = Intervals.size(); I < E; ++I) { - LiveInterval *LI = Intervals[I]; - LI->removeEmptySubRanges(); + LiveInterval &LI = *Intervals[I]; + unsigned Reg = LI.reg; + + // There must be a def (or live-in) before every use. Splitting vregs may + // violate this principle as the splitted vreg may not have a definition on + // every path. Fix this by creating IMPLICIT_DEF instruction as necessary. + VNInfo::Allocator &VNInfoAllocator = LIS.getVNInfoAllocator(); + for (const LiveInterval::SubRange &SR : LI.subranges()) { + // Search for "PHI" value numbers in the subranges. We must find a live + // value in each predecessor block, add an IMPLICIT_DEF where it is + // missing. + for (unsigned I = 0; I < SR.valnos.size(); ++I) { + const VNInfo &VNI = *SR.valnos[I]; + if (VNI.isUnused() || !VNI.isPHIDef()) + continue; + + SlotIndex Def = VNI.def; + MachineBasicBlock &MBB = *Indexes.getMBBFromIndex(Def); + for (MachineBasicBlock *PredMBB : MBB.predecessors()) { + SlotIndex PredEnd = Indexes.getMBBEndIdx(PredMBB); + if (subRangeLiveAt(LI, PredEnd.getPrevSlot())) + continue; + + MachineBasicBlock::iterator InsertPos = + llvm::findPHICopyInsertPoint(PredMBB, &MBB, Reg); + const MCInstrDesc &MCDesc = TII.get(TargetOpcode::IMPLICIT_DEF); + MachineInstrBuilder ImpDef = BuildMI(*PredMBB, InsertPos, + DebugLoc(), MCDesc, Reg); + SlotIndex DefIdx = LIS.InsertMachineInstrInMaps(*ImpDef); + SlotIndex RegDefIdx = DefIdx.getRegSlot(); + for (LiveInterval::SubRange &SR : LI.subranges()) { + VNInfo *SRVNI = SR.getNextValue(RegDefIdx, VNInfoAllocator); + SR.addSegment(LiveRange::Segment(RegDefIdx, PredEnd, SRVNI)); + } + } + } + } + + LI.removeEmptySubRanges(); if (I == 0) - LI->clear(); - LI->constructMainRangeFromSubranges(*LIS.getSlotIndexes(), Allocator); + LI.clear(); + LI.constructMainRangeFromSubranges(*LIS.getSlotIndexes(), Allocator); - for (MachineOperand &MO : MRI.reg_nodbg_operands(LI->reg)) { + for (MachineOperand &MO : MRI.reg_nodbg_operands(Reg)) { if (!MO.isDef()) continue; unsigned SubRegIdx = MO.getSubReg(); @@ -1677,12 +1727,12 @@ void ConnectedSubRegClasses::computeMainRangesFixFlags( // flags in these cases. if (!MO.isUndef()) { SlotIndex Pos = LIS.getInstructionIndex(*MO.getParent()); - if (!LI->liveAt(Pos.getBaseIndex())) + if (!LI.liveAt(Pos.getBaseIndex())) MO.setIsUndef(); } if (!MO.isDead()) { SlotIndex Pos = LIS.getInstructionIndex(*MO.getParent()); - if (!LI->liveAt(Pos.getDeadSlot())) + if (!LI.liveAt(Pos.getDeadSlot())) MO.setIsDead(); } } diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp index 3d22f709a45..2a7989d2ef1 100644 --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -1571,7 +1571,7 @@ void LiveIntervals::splitSeparateComponents(LiveInterval &LI, } void LiveIntervals::renameDisconnectedComponents() { - ConnectedSubRegClasses SubRegClasses(*this, *MRI); + ConnectedSubRegClasses SubRegClasses(*this, *MRI, *TII); // Iterate over all vregs. Note that we query getNumVirtRegs() the newly // created vregs end up with higher numbers but do not need to be visited as diff --git a/llvm/lib/CodeGen/MachineScheduler.cpp b/llvm/lib/CodeGen/MachineScheduler.cpp index 686abbf031f..d2b1b8fa6b3 100644 --- a/llvm/lib/CodeGen/MachineScheduler.cpp +++ b/llvm/lib/CodeGen/MachineScheduler.cpp @@ -444,7 +444,6 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler, // // MBB::size() uses instr_iterator to count. Here we need a bundle to count // as a single instruction. - unsigned RemainingInstrs = std::distance(MBB->begin(), MBB->end()); for(MachineBasicBlock::iterator RegionEnd = MBB->end(); RegionEnd != MBB->begin(); RegionEnd = Scheduler.begin()) { @@ -452,15 +451,13 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler, if (RegionEnd != MBB->end() || isSchedBoundary(&*std::prev(RegionEnd), &*MBB, MF, TII)) { --RegionEnd; - // Count the boundary instruction. - --RemainingInstrs; } // The next region starts above the previous region. Look backward in the // instruction stream until we find the nearest boundary. unsigned NumRegionInstrs = 0; MachineBasicBlock::iterator I = RegionEnd; - for(;I != MBB->begin(); --I, --RemainingInstrs) { + for (;I != MBB->begin(); --I) { if (isSchedBoundary(&*std::prev(I), &*MBB, MF, TII)) break; if (!I->isDebugValue()) @@ -483,8 +480,7 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler, << "\n From: " << *I << " To: "; if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; else dbgs() << "End"; - dbgs() << " RegionInstrs: " << NumRegionInstrs - << " Remaining: " << RemainingInstrs << "\n"); + dbgs() << " RegionInstrs: " << NumRegionInstrs << '\n'); if (DumpCriticalPathLength) { errs() << MF->getName(); errs() << ":BB# " << MBB->getNumber(); @@ -502,7 +498,6 @@ void MachineSchedulerBase::scheduleRegions(ScheduleDAGInstrs &Scheduler, // scheduler for the top of it's scheduled region. RegionEnd = Scheduler.begin(); } - assert(RemainingInstrs == 0 && "Instruction count mismatch!"); Scheduler.finishBlock(); // FIXME: Ideally, no further passes should rely on kill flags. However, // thumb2 size reduction is currently an exception, so the PostMIScheduler |