CodeGen: Assert that liveness is up to date when reading block live-ins.

Add an assert that checks whether liveins are up to date before they are
used.

- Do not print liveins into .mir files anymore in situations where they
  are out of date anyway.
- The assert in the RegisterScavenger is superseded by the new one in
  livein_begin().
- Skip parts of the liveness updating logic in IfConversion.cpp when
  liveness isn't tracked anymore (just enough to avoid hitting the new
  assert()).

Differential Revision: https://reviews.llvm.org/D27562

llvm-svn: 291169
This commit is contained in:
Matthias Braun 2017-01-05 20:01:19 +00:00
parent e8e11eb726
commit 1172332203
10 changed files with 61 additions and 43 deletions

View File

@ -308,7 +308,7 @@ public:
// Iteration support for live in sets. These sets are kept in sorted
// order by their register number.
typedef LiveInVector::const_iterator livein_iterator;
livein_iterator livein_begin() const { return LiveIns.begin(); }
livein_iterator livein_begin() const;
livein_iterator livein_end() const { return LiveIns.end(); }
bool livein_empty() const { return LiveIns.empty(); }
iterator_range<livein_iterator> liveins() const {

View File

@ -1495,16 +1495,18 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
if (TII->reverseBranchCondition(Cond))
llvm_unreachable("Unable to reverse branch condition!");
// Initialize liveins to the first BB. These are potentiall redefined by
// predicated instructions.
Redefs.init(*TRI);
Redefs.addLiveIns(CvtMBB);
Redefs.addLiveIns(NextMBB);
// Compute a set of registers which must not be killed by instructions in
// BB1: This is everything live-in to BB2.
DontKill.init(*TRI);
DontKill.addLiveIns(NextMBB);
if (MRI->tracksLiveness()) {
// Initialize liveins to the first BB. These are potentiall redefined by
// predicated instructions.
Redefs.addLiveIns(CvtMBB);
Redefs.addLiveIns(NextMBB);
// Compute a set of registers which must not be killed by instructions in
// BB1: This is everything live-in to BB2.
DontKill.addLiveIns(NextMBB);
}
if (CvtMBB.pred_size() > 1) {
BBI.NonPredSize -= TII->removeBranch(*BBI.BB);
@ -1602,8 +1604,10 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
// Initialize liveins to the first BB. These are potentially redefined by
// predicated instructions.
Redefs.init(*TRI);
Redefs.addLiveIns(CvtMBB);
Redefs.addLiveIns(NextMBB);
if (MRI->tracksLiveness()) {
Redefs.addLiveIns(CvtMBB);
Redefs.addLiveIns(NextMBB);
}
DontKill.clear();
@ -1766,8 +1770,10 @@ bool IfConverter::IfConvertDiamondCommon(
// instructions. We start with BB1 live-ins so we have the live-out regs
// after tracking the BB1 instructions.
Redefs.init(*TRI);
Redefs.addLiveIns(MBB1);
Redefs.addLiveIns(MBB2);
if (MRI->tracksLiveness()) {
Redefs.addLiveIns(MBB1);
Redefs.addLiveIns(MBB2);
}
// Remove the duplicated instructions at the beginnings of both paths.
// Skip dbg_value instructions
@ -1792,12 +1798,14 @@ bool IfConverter::IfConvertDiamondCommon(
// This is everything used+live in BB2 after the duplicated instructions. We
// can compute this set by simulating liveness backwards from the end of BB2.
DontKill.init(*TRI);
for (const MachineInstr &MI : make_range(MBB2.rbegin(), ++DI2.getReverse()))
DontKill.stepBackward(MI);
if (MRI->tracksLiveness()) {
for (const MachineInstr &MI : make_range(MBB2.rbegin(), ++DI2.getReverse()))
DontKill.stepBackward(MI);
for (const MachineInstr &MI : make_range(MBB1.begin(), DI1)) {
SmallVector<std::pair<unsigned, const MachineOperand*>, 4> IgnoredClobbers;
Redefs.stepForward(MI, IgnoredClobbers);
for (const MachineInstr &MI : make_range(MBB1.begin(), DI1)) {
SmallVector<std::pair<unsigned, const MachineOperand*>, 4> Dummy;
Redefs.stepForward(MI, Dummy);
}
}
BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.begin(), DI1);
MBB2.erase(MBB2.begin(), DI2);

View File

@ -488,16 +488,16 @@ void MIPrinter::print(const MachineBasicBlock &MBB) {
}
// Print the live in registers.
const auto *TRI = MBB.getParent()->getSubtarget().getRegisterInfo();
assert(TRI && "Expected target register info");
if (!MBB.livein_empty()) {
const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
if (MRI.tracksLiveness() && !MBB.livein_empty()) {
const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
OS.indent(2) << "liveins: ";
bool First = true;
for (const auto &LI : MBB.liveins()) {
if (!First)
OS << ", ";
First = false;
printReg(LI.PhysReg, OS, TRI);
printReg(LI.PhysReg, OS, &TRI);
if (!LI.LaneMask.all())
OS << ":0x" << PrintLaneMask(LI.LaneMask);
}

View File

@ -286,7 +286,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (!livein_empty()) {
if (Indexes) OS << '\t';
OS << " Live Ins:";
for (const auto &LI : make_range(livein_begin(), livein_end())) {
for (const auto &LI : LiveIns) {
OS << ' ' << PrintReg(LI.PhysReg, TRI);
if (!LI.LaneMask.all())
OS << ':' << PrintLaneMask(LI.LaneMask);
@ -1292,3 +1292,10 @@ MachineBasicBlock::getEndClobberMask(const TargetRegisterInfo *TRI) const {
void MachineBasicBlock::clearLiveIns() {
LiveIns.clear();
}
MachineBasicBlock::livein_iterator MachineBasicBlock::livein_begin() const {
assert(getParent()->getProperties().hasProperty(
MachineFunctionProperties::Property::TracksLiveness) &&
"Liveness information is accurate");
return LiveIns.begin();
}

View File

@ -566,7 +566,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
FirstTerminator = nullptr;
if (!MF->getProperties().hasProperty(
MachineFunctionProperties::Property::NoPHIs)) {
MachineFunctionProperties::Property::NoPHIs) && MRI->tracksLiveness()) {
// If this block has allocatable physical registers live-in, check that
// it is an entry block or landing pad.
for (const auto &LI : MBB->liveins()) {
@ -741,14 +741,16 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
}
regsLive.clear();
for (const auto &LI : MBB->liveins()) {
if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) {
report("MBB live-in list contains non-physical register", MBB);
continue;
if (MRI->tracksLiveness()) {
for (const auto &LI : MBB->liveins()) {
if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) {
report("MBB live-in list contains non-physical register", MBB);
continue;
}
for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
}
for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
}
regsLiveInButUnused = regsLive;

View File

@ -48,11 +48,6 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) &&
"Target changed?");
// It is not possible to use the register scavenger after late optimization
// passes that don't preserve accurate liveness information.
assert(MRI->tracksLiveness() &&
"Cannot use register scavenger with inaccurate liveness");
// Self-initialize.
if (!this->MBB) {
NumRegUnits = TRI->getNumRegUnits();

View File

@ -21,8 +21,9 @@
# CHECK: LDRWui %x0, 0
# CHECK: LDRWui %x0, 1
# CHECK: STRWui %w1, %x0, 2
name: load_imp-def
body: |
name: load_imp-def
tracksRegLiveness: true
body: |
bb.0.entry:
liveins: %w1, %x0
%w8 = LDRWui %x0, 1, implicit-def %x8 :: (load 4 from %ir.0)

View File

@ -22,7 +22,8 @@
...
---
name: test
name: test
tracksRegLiveness: true
body: |
; CHECK-LABEL: bb.0.body:
; CHECK-NEXT: liveins: %edi, %esi
@ -33,7 +34,8 @@ body: |
RETQ %eax
...
---
name: test2
name: test2
tracksRegLiveness: true
body: |
; CHECK-LABEL: name: test2
; Verify that we can have multiple lists of liveins that will be merged into
@ -48,7 +50,8 @@ body: |
RETQ %eax
...
---
name: test3
name: test3
tracksRegLiveness: true
body: |
; Verify that we can have an empty list of liveins.
; CHECK-LABEL: name: test3

View File

@ -10,7 +10,8 @@
...
---
name: inc
name: inc
tracksRegLiveness: true
body: |
bb.0.entry:
liveins: %edi

View File

@ -26,7 +26,8 @@
...
---
name: test
name: test
tracksRegLiveness: true
liveins:
- { reg: '%rdi' }
- { reg: '%rsi' }