#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
void LiveIntervals::computeVirtRegInterval(LiveInterval &LI) {
assert(LRCalc && "LRCalc not initialized.");
assert(LI.empty() && "Should only compute empty intervals.");
+ bool ShouldTrackSubRegLiveness = MRI->shouldTrackSubRegLiveness(LI.reg);
LRCalc->reset(MF, getSlotIndexes(), DomTree, &getVNInfoAllocator());
- LRCalc->calculate(LI, MRI->shouldTrackSubRegLiveness(LI.reg));
- computeDeadValues(LI, nullptr);
+ LRCalc->calculate(LI, ShouldTrackSubRegLiveness);
+ bool SeparatedComponents = computeDeadValues(LI, nullptr);
+ if (SeparatedComponents) {
+ assert(ShouldTrackSubRegLiveness
+ && "Separated components should only occur for unused subreg defs");
+ SmallVector<LiveInterval*, 8> SplitLIs;
+ splitSeparateComponents(LI, SplitLIs);
+ }
}
void LiveIntervals::computeVirtRegs() {
RegMaskBlocks.resize(MF->getNumBlockIDs());
// Find all instructions with regmask operands.
- for (MachineFunction::iterator MBBI = MF->begin(), E = MF->end();
- MBBI != E; ++MBBI) {
- MachineBasicBlock *MBB = MBBI;
- std::pair<unsigned, unsigned> &RMB = RegMaskBlocks[MBB->getNumber()];
+ for (MachineBasicBlock &MBB : *MF) {
+ std::pair<unsigned, unsigned> &RMB = RegMaskBlocks[MBB.getNumber()];
RMB.first = RegMaskSlots.size();
- for (MachineBasicBlock::iterator MI = MBB->begin(), ME = MBB->end();
- MI != ME; ++MI)
- for (const MachineOperand &MO : MI->operands()) {
+
+ // Some block starts, such as EH funclets, create masks.
+ if (const uint32_t *Mask = MBB.getBeginClobberMask(TRI)) {
+ RegMaskSlots.push_back(Indexes->getMBBStartIdx(&MBB));
+ RegMaskBits.push_back(Mask);
+ }
+
+ for (MachineInstr &MI : MBB) {
+ for (const MachineOperand &MO : MI.operands()) {
if (!MO.isRegMask())
continue;
- RegMaskSlots.push_back(Indexes->getInstructionIndex(MI).getRegSlot());
- RegMaskBits.push_back(MO.getRegMask());
+ RegMaskSlots.push_back(Indexes->getInstructionIndex(&MI).getRegSlot());
+ RegMaskBits.push_back(MO.getRegMask());
}
+ }
+
+ // Some block ends, such as funclet returns, create masks.
+ if (const uint32_t *Mask = MBB.getEndClobberMask(TRI)) {
+ RegMaskSlots.push_back(Indexes->getMBBEndIdx(&MBB));
+ RegMaskBits.push_back(Mask);
+ }
+
// Compute the number of register mask instructions in this block.
RMB.second = RegMaskSlots.size() - RMB.first;
}
// Check all basic blocks for live-ins.
for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
MFI != MFE; ++MFI) {
- const MachineBasicBlock *MBB = MFI;
+ const MachineBasicBlock *MBB = &*MFI;
// We only care about ABI blocks: Entry + landing pads.
if ((MFI != MF->begin() && !MBB->isEHPad()) || MBB->livein_empty())
bool LiveIntervals::computeDeadValues(LiveInterval &LI,
SmallVectorImpl<MachineInstr*> *dead) {
- bool PHIRemoved = false;
+ bool MayHaveSplitComponents = false;
for (auto VNI : LI.valnos) {
if (VNI->isUnused())
continue;
// Is the register live before? Otherwise we may have to add a read-undef
// flag for subregister defs.
- if (MRI->shouldTrackSubRegLiveness(LI.reg)) {
+ bool DeadBeforeDef = false;
+ unsigned VReg = LI.reg;
+ if (MRI->shouldTrackSubRegLiveness(VReg)) {
if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) {
MachineInstr *MI = getInstructionFromIndex(Def);
- MI->addRegisterDefReadUndef(LI.reg);
+ MI->setRegisterDefReadUndef(VReg);
+ DeadBeforeDef = true;
}
}
VNI->markUnused();
LI.removeSegment(I);
DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n");
- PHIRemoved = true;
+ MayHaveSplitComponents = true;
} else {
// This is a dead def. Make sure the instruction knows.
MachineInstr *MI = getInstructionFromIndex(Def);
assert(MI && "No instruction defining live value");
- MI->addRegisterDead(LI.reg, TRI);
+ MI->addRegisterDead(VReg, TRI);
+
+ // If we have a dead def that is completely separate from the rest of
+ // the liverange then we rewrite it to use a different VReg to not violate
+ // the rule that the liveness of a virtual register forms a connected
+ // component. This should only happen if subregister liveness is tracked.
+ if (DeadBeforeDef)
+ MayHaveSplitComponents = true;
+
if (dead && MI->allDefsAreDead()) {
DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI);
dead->push_back(MI);
}
}
}
- return PHIRemoved;
+ return MayHaveSplitComponents;
}
void LiveIntervals::shrinkToUses(LiveInterval::SubRange &SR, unsigned Reg)
// Maybe the operand is for a subregister we don't care about.
unsigned SubReg = MO.getSubReg();
if (SubReg != 0) {
- unsigned SubRegMask = TRI->getSubRegIndexLaneMask(SubReg);
- if ((SubRegMask & SR.LaneMask) == 0)
+ LaneBitmask LaneMask = TRI->getSubRegIndexLaneMask(SubReg);
+ if ((LaneMask & SR.LaneMask) == 0)
continue;
}
// We only need to visit each instruction once.
// assign R0L to %vreg1, and R0 to %vreg2 because the low 32bits of R0
// are actually never written by %vreg2. After assignment the <kill>
// flag at the read instruction is invalid.
- unsigned DefinedLanesMask;
+ LaneBitmask DefinedLanesMask;
if (!SRs.empty()) {
// Compute a mask of lanes that are defined.
DefinedLanesMask = 0;
continue;
if (MO.isUse()) {
// Reading any undefined lanes?
- unsigned UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
+ LaneBitmask UseMask = TRI->getSubRegIndexLaneMask(MO.getSubReg());
if ((UseMask & ~DefinedLanesMask) != 0)
goto CancelKill;
} else if (MO.getSubReg() == 0) {
LiveInterval &LI = LIS.getInterval(Reg);
if (LI.hasSubRanges()) {
unsigned SubReg = MO.getSubReg();
- unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
+ LaneBitmask LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
for (LiveInterval::SubRange &S : LI.subranges()) {
if ((S.LaneMask & LaneMask) == 0)
continue;
private:
/// Update a single live range, assuming an instruction has been moved from
/// OldIdx to NewIdx.
- void updateRange(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
+ void updateRange(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask) {
if (!Updated.insert(&LR).second)
return;
DEBUG({
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
dbgs() << PrintReg(Reg);
if (LaneMask != 0)
- dbgs() << format(" L%04X", LaneMask);
+ dbgs() << " L" << PrintLaneMask(LaneMask);
} else {
dbgs() << PrintRegUnit(Reg, &TRI);
}
/// Hoist kill to NewIdx, then scan for last kill between NewIdx and
/// OldIdx.
///
- void handleMoveUp(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
+ void handleMoveUp(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask) {
// First look for a kill at OldIdx.
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
LiveRange::iterator E = LR.end();
}
// Return the last use of reg between NewIdx and OldIdx.
- SlotIndex findLastUseBefore(unsigned Reg, unsigned LaneMask) {
+ SlotIndex findLastUseBefore(unsigned Reg, LaneBitmask LaneMask) {
if (TargetRegisterInfo::isVirtualRegister(Reg)) {
SlotIndex LastUse = NewIdx;
const MachineBasicBlock::iterator End,
const SlotIndex endIdx,
LiveRange &LR, const unsigned Reg,
- const unsigned LaneMask) {
+ LaneBitmask LaneMask) {
LiveInterval::iterator LII = LR.find(endIdx);
SlotIndex lastUseIdx;
if (LII != LR.end() && LII->start < endIdx)
continue;
unsigned SubReg = MO.getSubReg();
- unsigned Mask = TRI->getSubRegIndexLaneMask(SubReg);
+ LaneBitmask Mask = TRI->getSubRegIndexLaneMask(SubReg);
if ((Mask & LaneMask) == 0)
continue;
}
LI.removeEmptySubRanges();
}
+
+void LiveIntervals::splitSeparateComponents(LiveInterval &LI,
+ SmallVectorImpl<LiveInterval*> &SplitLIs) {
+ ConnectedVNInfoEqClasses ConEQ(*this);
+ unsigned NumComp = ConEQ.Classify(LI);
+ if (NumComp <= 1)
+ return;
+ DEBUG(dbgs() << " Split " << NumComp << " components: " << LI << '\n');
+ unsigned Reg = LI.reg;
+ const TargetRegisterClass *RegClass = MRI->getRegClass(Reg);
+ for (unsigned I = 1; I < NumComp; ++I) {
+ unsigned NewVReg = MRI->createVirtualRegister(RegClass);
+ LiveInterval &NewLI = createEmptyInterval(NewVReg);
+ SplitLIs.push_back(&NewLI);
+ }
+ ConEQ.Distribute(LI, SplitLIs.data(), *MRI);
+}