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:
parent
e8e11eb726
commit
1172332203
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -10,7 +10,8 @@
|
||||||
|
|
||||||
...
|
...
|
||||||
---
|
---
|
||||||
name: inc
|
name: inc
|
||||||
|
tracksRegLiveness: true
|
||||||
body: |
|
body: |
|
||||||
bb.0.entry:
|
bb.0.entry:
|
||||||
liveins: %edi
|
liveins: %edi
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
...
|
...
|
||||||
---
|
---
|
||||||
name: test
|
name: test
|
||||||
|
tracksRegLiveness: true
|
||||||
liveins:
|
liveins:
|
||||||
- { reg: '%rdi' }
|
- { reg: '%rdi' }
|
||||||
- { reg: '%rsi' }
|
- { reg: '%rsi' }
|
||||||
|
|
Loading…
Reference in New Issue