summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveIntervals.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/LiveIntervals.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveIntervals.cpp98
1 files changed, 61 insertions, 37 deletions
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index a32b486240c8..23036c2b115f 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -38,6 +38,7 @@
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Statepoint.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
@@ -47,6 +48,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/CodeGen/StackMaps.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
@@ -473,7 +475,7 @@ bool LiveIntervals::shrinkToUses(LiveInterval *li,
// Visit all instructions reading li->reg().
Register Reg = li->reg();
for (MachineInstr &UseMI : MRI->reg_instructions(Reg)) {
- if (UseMI.isDebugValue() || !UseMI.readsVirtualRegister(Reg))
+ if (UseMI.isDebugInstr() || !UseMI.readsVirtualRegister(Reg))
continue;
SlotIndex Idx = getInstructionIndex(UseMI).getRegSlot();
LiveQueryResult LRQ = li->Query(Idx);
@@ -702,9 +704,6 @@ void LiveIntervals::pruneValue(LiveRange &LR, SlotIndex Kill,
void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
// Keep track of regunit ranges.
SmallVector<std::pair<const LiveRange*, LiveRange::const_iterator>, 8> RU;
- // Keep track of subregister ranges.
- SmallVector<std::pair<const LiveInterval::SubRange*,
- LiveRange::const_iterator>, 4> SRs;
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
Register Reg = Register::index2VirtReg(i);
@@ -714,24 +713,21 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
if (LI.empty())
continue;
+ // Target may have not allocated this yet.
+ Register PhysReg = VRM->getPhys(Reg);
+ if (!PhysReg)
+ continue;
+
// Find the regunit intervals for the assigned register. They may overlap
// the virtual register live range, cancelling any kills.
RU.clear();
- for (MCRegUnitIterator Unit(VRM->getPhys(Reg), TRI); Unit.isValid();
+ for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid();
++Unit) {
const LiveRange &RURange = getRegUnit(*Unit);
if (RURange.empty())
continue;
RU.push_back(std::make_pair(&RURange, RURange.find(LI.begin()->end)));
}
-
- if (MRI->subRegLivenessEnabled()) {
- SRs.clear();
- for (const LiveInterval::SubRange &SR : LI.subranges()) {
- SRs.push_back(std::make_pair(&SR, SR.find(LI.begin()->end)));
- }
- }
-
// Every instruction that kills Reg corresponds to a segment range end
// point.
for (LiveInterval::const_iterator RI = LI.begin(), RE = LI.end(); RI != RE;
@@ -776,20 +772,18 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
// are actually never written by %2. After assignment the <kill>
// flag at the read instruction is invalid.
LaneBitmask DefinedLanesMask;
- if (!SRs.empty()) {
+ if (LI.hasSubRanges()) {
// Compute a mask of lanes that are defined.
DefinedLanesMask = LaneBitmask::getNone();
- for (auto &SRP : SRs) {
- const LiveInterval::SubRange &SR = *SRP.first;
- LiveRange::const_iterator &I = SRP.second;
- if (I == SR.end())
- continue;
- I = SR.advanceTo(I, RI->end);
- if (I == SR.end() || I->start >= RI->end)
- continue;
- // I is overlapping RI
- DefinedLanesMask |= SR.LaneMask;
- }
+ for (const LiveInterval::SubRange &SR : LI.subranges())
+ for (const LiveRange::Segment &Segment : SR.segments) {
+ if (Segment.start >= RI->end)
+ break;
+ if (Segment.end == RI->end) {
+ DefinedLanesMask |= SR.LaneMask;
+ break;
+ }
+ }
} else
DefinedLanesMask = LaneBitmask::getAll();
@@ -799,7 +793,9 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
continue;
if (MO.isUse()) {
// Reading any undefined lanes?
- LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
+ unsigned SubReg = MO.getSubReg();
+ LaneBitmask UseMask = SubReg ? TRI->getSubRegIndexLaneMask(SubReg)
+ : MRI->getMaxLaneMaskForVReg(Reg);
if ((UseMask & ~DefinedLanesMask).any())
goto CancelKill;
} else if (MO.getSubReg() == 0) {
@@ -897,6 +893,23 @@ LiveIntervals::addSegmentToEndOfBlock(Register Reg, MachineInstr &startInst) {
//===----------------------------------------------------------------------===//
// Register mask functions
//===----------------------------------------------------------------------===//
+/// Check whether use of reg in MI is live-through. Live-through means that
+/// the value is alive on exit from Machine instruction. The example of such
+/// use is a deopt value in statepoint instruction.
+static bool hasLiveThroughUse(const MachineInstr *MI, Register Reg) {
+ if (MI->getOpcode() != TargetOpcode::STATEPOINT)
+ return false;
+ StatepointOpers SO(MI);
+ if (SO.getFlags() & (uint64_t)StatepointFlags::DeoptLiveIn)
+ return false;
+ for (unsigned Idx = SO.getNumDeoptArgsIdx(), E = SO.getNumGCPtrIdx(); Idx < E;
+ ++Idx) {
+ const MachineOperand &MO = MI->getOperand(Idx);
+ if (MO.isReg() && MO.getReg() == Reg)
+ return true;
+ }
+ return false;
+}
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
BitVector &UsableRegs) {
@@ -925,11 +938,8 @@ bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
return false;
bool Found = false;
- while (true) {
- assert(*SlotI >= LiveI->start);
- // Loop over all slots overlapping this segment.
- while (*SlotI < LiveI->end) {
- // *SlotI overlaps LI. Collect mask bits.
+ // Utility to union regmasks.
+ auto unionBitMask = [&](unsigned Idx) {
if (!Found) {
// This is the first overlap. Initialize UsableRegs to all ones.
UsableRegs.clear();
@@ -937,14 +947,28 @@ bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
Found = true;
}
// Remove usable registers clobbered by this mask.
- UsableRegs.clearBitsNotInMask(Bits[SlotI-Slots.begin()]);
+ UsableRegs.clearBitsNotInMask(Bits[Idx]);
+ };
+ while (true) {
+ assert(*SlotI >= LiveI->start);
+ // Loop over all slots overlapping this segment.
+ while (*SlotI < LiveI->end) {
+ // *SlotI overlaps LI. Collect mask bits.
+ unionBitMask(SlotI - Slots.begin());
if (++SlotI == SlotE)
return Found;
}
+ // If segment ends with live-through use we need to collect its regmask.
+ if (*SlotI == LiveI->end)
+ if (MachineInstr *MI = getInstructionFromIndex(*SlotI))
+ if (hasLiveThroughUse(MI, LI.reg()))
+ unionBitMask(SlotI++ - Slots.begin());
// *SlotI is beyond the current LI segment.
- LiveI = LI.advanceTo(LiveI, *SlotI);
- if (LiveI == LiveE)
+ // Special advance implementation to not miss next LiveI->end.
+ if (++LiveI == LiveE || SlotI == SlotE || *SlotI > LI.endIndex())
return Found;
+ while (LiveI->end < *SlotI)
+ ++LiveI;
// Advance SlotI until it overlaps.
while (*SlotI < LiveI->start)
if (++SlotI == SlotE)
@@ -1465,7 +1489,7 @@ private:
MachineBasicBlock::iterator Begin = MBB->begin();
while (MII != Begin) {
- if ((--MII)->isDebugInstr())
+ if ((--MII)->isDebugOrPseudoInstr())
continue;
SlotIndex Idx = Indexes->getInstructionIndex(*MII);
@@ -1560,7 +1584,7 @@ void LiveIntervals::repairOldRegInRange(const MachineBasicBlock::iterator Begin,
for (MachineBasicBlock::iterator I = End; I != Begin;) {
--I;
MachineInstr &MI = *I;
- if (MI.isDebugInstr())
+ if (MI.isDebugOrPseudoInstr())
continue;
SlotIndex instrIdx = getInstructionIndex(MI);
@@ -1657,7 +1681,7 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
for (MachineBasicBlock::iterator I = End; I != Begin;) {
--I;
MachineInstr &MI = *I;
- if (MI.isDebugInstr())
+ if (MI.isDebugOrPseudoInstr())
continue;
for (MachineInstr::const_mop_iterator MOI = MI.operands_begin(),
MOE = MI.operands_end();