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 // Iteration support for live in sets. These sets are kept in sorted
// order by their register number. // order by their register number.
typedef LiveInVector::const_iterator livein_iterator; 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(); } livein_iterator livein_end() const { return LiveIns.end(); }
bool livein_empty() const { return LiveIns.empty(); } bool livein_empty() const { return LiveIns.empty(); }
iterator_range<livein_iterator> liveins() const { iterator_range<livein_iterator> liveins() const {

View File

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

View File

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

View File

@ -286,7 +286,7 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
if (!livein_empty()) { if (!livein_empty()) {
if (Indexes) OS << '\t'; if (Indexes) OS << '\t';
OS << " Live Ins:"; OS << " Live Ins:";
for (const auto &LI : make_range(livein_begin(), livein_end())) { for (const auto &LI : LiveIns) {
OS << ' ' << PrintReg(LI.PhysReg, TRI); OS << ' ' << PrintReg(LI.PhysReg, TRI);
if (!LI.LaneMask.all()) if (!LI.LaneMask.all())
OS << ':' << PrintLaneMask(LI.LaneMask); OS << ':' << PrintLaneMask(LI.LaneMask);
@ -1292,3 +1292,10 @@ MachineBasicBlock::getEndClobberMask(const TargetRegisterInfo *TRI) const {
void MachineBasicBlock::clearLiveIns() { void MachineBasicBlock::clearLiveIns() {
LiveIns.clear(); 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; FirstTerminator = nullptr;
if (!MF->getProperties().hasProperty( if (!MF->getProperties().hasProperty(
MachineFunctionProperties::Property::NoPHIs)) { MachineFunctionProperties::Property::NoPHIs) && MRI->tracksLiveness()) {
// If this block has allocatable physical registers live-in, check that // If this block has allocatable physical registers live-in, check that
// it is an entry block or landing pad. // it is an entry block or landing pad.
for (const auto &LI : MBB->liveins()) { for (const auto &LI : MBB->liveins()) {
@ -741,14 +741,16 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
} }
regsLive.clear(); regsLive.clear();
for (const auto &LI : MBB->liveins()) { if (MRI->tracksLiveness()) {
if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) { for (const auto &LI : MBB->liveins()) {
report("MBB live-in list contains non-physical register", MBB); if (!TargetRegisterInfo::isPhysicalRegister(LI.PhysReg)) {
continue; 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; regsLiveInButUnused = regsLive;

View File

@ -48,11 +48,6 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) && assert((NumRegUnits == 0 || NumRegUnits == TRI->getNumRegUnits()) &&
"Target changed?"); "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. // Self-initialize.
if (!this->MBB) { if (!this->MBB) {
NumRegUnits = TRI->getNumRegUnits(); NumRegUnits = TRI->getNumRegUnits();

View File

@ -21,8 +21,9 @@
# CHECK: LDRWui %x0, 0 # CHECK: LDRWui %x0, 0
# CHECK: LDRWui %x0, 1 # CHECK: LDRWui %x0, 1
# CHECK: STRWui %w1, %x0, 2 # CHECK: STRWui %w1, %x0, 2
name: load_imp-def name: load_imp-def
body: | tracksRegLiveness: true
body: |
bb.0.entry: bb.0.entry:
liveins: %w1, %x0 liveins: %w1, %x0
%w8 = LDRWui %x0, 1, implicit-def %x8 :: (load 4 from %ir.0) %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: | body: |
; CHECK-LABEL: bb.0.body: ; CHECK-LABEL: bb.0.body:
; CHECK-NEXT: liveins: %edi, %esi ; CHECK-NEXT: liveins: %edi, %esi
@ -33,7 +34,8 @@ body: |
RETQ %eax RETQ %eax
... ...
--- ---
name: test2 name: test2
tracksRegLiveness: true
body: | body: |
; CHECK-LABEL: name: test2 ; CHECK-LABEL: name: test2
; Verify that we can have multiple lists of liveins that will be merged into ; Verify that we can have multiple lists of liveins that will be merged into
@ -48,7 +50,8 @@ body: |
RETQ %eax RETQ %eax
... ...
--- ---
name: test3 name: test3
tracksRegLiveness: true
body: | body: |
; Verify that we can have an empty list of liveins. ; Verify that we can have an empty list of liveins.
; CHECK-LABEL: name: test3 ; CHECK-LABEL: name: test3

View File

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

View File

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