diff options
author | Matthias Braun <matze@braunis.de> | 2016-05-20 19:46:13 +0000 |
---|---|---|
committer | Matthias Braun <matze@braunis.de> | 2016-05-20 19:46:13 +0000 |
commit | 858d1df246e914a715622aea11966a12ed48abb3 (patch) | |
tree | 473dab14783e5772da5ac42d321abe1a4e11b4d4 /llvm/lib/CodeGen/LiveInterval.cpp | |
parent | 5973bc8a82dc585b1f08190e4baba389a17a880f (diff) | |
download | bcm5719-llvm-858d1df246e914a715622aea11966a12ed48abb3.tar.gz bcm5719-llvm-858d1df246e914a715622aea11966a12ed48abb3.zip |
LiveIntervalAnalysis: Fix missing defs in renameDisconnectedComponents().
Fix renameDisconnectedComponents() creating vreg uses that can be
reached from function begin withouthaving a definition (or explicit
live-in). Fix this by inserting IMPLICIT_DEF instruction before
control-flow joins as necessary.
Removes an assert from MachineScheduler because we may now get
additional IMPLICIT_DEF when preparing the scheduling policy.
This fixes the underlying problem of http://llvm.org/PR27705
llvm-svn: 270259
Diffstat (limited to 'llvm/lib/CodeGen/LiveInterval.cpp')
-rw-r--r-- | llvm/lib/CodeGen/LiveInterval.cpp | 64 |
1 files changed, 57 insertions, 7 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(); } } |