summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--contrib/llvm/lib/CodeGen/MachineVerifier.cpp328
1 files changed, 193 insertions, 135 deletions
diff --git a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
index ca35ec5..428295e 100644
--- a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -28,6 +28,7 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveStackAnalysis.h"
#include "llvm/CodeGen/LiveVariables.h"
@@ -42,7 +43,6 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
@@ -204,18 +204,19 @@ namespace {
void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB);
void visitMachineFunctionAfter();
+ template <typename T> void report(const char *msg, ilist_iterator<T> I) {
+ report(msg, &*I);
+ }
void report(const char *msg, const MachineFunction *MF);
void report(const char *msg, const MachineBasicBlock *MBB);
void report(const char *msg, const MachineInstr *MI);
void report(const char *msg, const MachineOperand *MO, unsigned MONum);
- void report(const char *msg, const MachineFunction *MF,
- const LiveInterval &LI);
- void report(const char *msg, const MachineBasicBlock *MBB,
- const LiveInterval &LI);
- void report(const char *msg, const MachineFunction *MF,
- const LiveRange &LR, unsigned Reg, unsigned LaneMask);
- void report(const char *msg, const MachineBasicBlock *MBB,
- const LiveRange &LR, unsigned Reg, unsigned LaneMask);
+
+ void report_context(const LiveInterval &LI) const;
+ void report_context(const LiveRange &LR, unsigned Reg,
+ LaneBitmask LaneMask) const;
+ void report_context(const LiveRange::Segment &S) const;
+ void report_context(const VNInfo &VNI) const;
void verifyInlineAsm(const MachineInstr *MI);
@@ -233,9 +234,11 @@ namespace {
void verifyLiveRangeSegment(const LiveRange&,
const LiveRange::const_iterator I, unsigned,
unsigned);
- void verifyLiveRange(const LiveRange&, unsigned, unsigned LaneMask = 0);
+ void verifyLiveRange(const LiveRange&, unsigned, LaneBitmask LaneMask = 0);
void verifyStackFrame();
+
+ void verifySlotIndexes() const;
};
struct MachineVerifierPass : public MachineFunctionPass {
@@ -273,6 +276,19 @@ void MachineFunction::verify(Pass *p, const char *Banner) const {
.runOnMachineFunction(const_cast<MachineFunction&>(*this));
}
+void MachineVerifier::verifySlotIndexes() const {
+ if (Indexes == nullptr)
+ return;
+
+ // Ensure the IdxMBB list is sorted by slot indexes.
+ SlotIndex Last;
+ for (SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin(),
+ E = Indexes->MBBIndexEnd(); I != E; ++I) {
+ assert(!Last.isValid() || I->first > Last);
+ Last = I->first;
+ }
+}
+
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
foundErrors = 0;
@@ -295,10 +311,12 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
Indexes = PASS->getAnalysisIfAvailable<SlotIndexes>();
}
+ verifySlotIndexes();
+
visitMachineFunctionBefore();
for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
MFI!=MFE; ++MFI) {
- visitMachineBasicBlockBefore(MFI);
+ visitMachineBasicBlockBefore(&*MFI);
// Keep track of the current bundle header.
const MachineInstr *CurBundle = nullptr;
// Do we expect the next instruction to be part of the same bundle?
@@ -306,7 +324,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(),
MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) {
- if (MBBI->getParent() != MFI) {
+ if (MBBI->getParent() != &*MFI) {
report("Bad instruction parent pointer", MFI);
errs() << "Instruction: " << *MBBI;
continue;
@@ -315,20 +333,22 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
// Check for consistent bundle flags.
if (InBundle && !MBBI->isBundledWithPred())
report("Missing BundledPred flag, "
- "BundledSucc was set on predecessor", MBBI);
+ "BundledSucc was set on predecessor",
+ &*MBBI);
if (!InBundle && MBBI->isBundledWithPred())
report("BundledPred flag is set, "
- "but BundledSucc not set on predecessor", MBBI);
+ "but BundledSucc not set on predecessor",
+ &*MBBI);
// Is this a bundle header?
if (!MBBI->isInsideBundle()) {
if (CurBundle)
visitMachineBundleAfter(CurBundle);
- CurBundle = MBBI;
+ CurBundle = &*MBBI;
visitMachineBundleBefore(CurBundle);
} else if (!CurBundle)
report("No bundle header", MBBI);
- visitMachineInstrBefore(MBBI);
+ visitMachineInstrBefore(&*MBBI);
for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) {
const MachineInstr &MI = *MBBI;
const MachineOperand &Op = MI.getOperand(I);
@@ -341,7 +361,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
visitMachineOperand(&Op, I);
}
- visitMachineInstrAfter(MBBI);
+ visitMachineInstrAfter(&*MBBI);
// Was this the last bundled instruction?
InBundle = MBBI->isBundledWithSucc();
@@ -350,7 +370,7 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
visitMachineBundleAfter(CurBundle);
if (InBundle)
report("BundledSucc flag set on last instruction in block", &MFI->back());
- visitMachineBasicBlockAfter(MFI);
+ visitMachineBasicBlockAfter(&*MFI);
}
visitMachineFunctionAfter();
@@ -375,7 +395,10 @@ void MachineVerifier::report(const char *msg, const MachineFunction *MF) {
if (!foundErrors++) {
if (Banner)
errs() << "# " << Banner << '\n';
- MF->print(errs(), Indexes);
+ if (LiveInts != nullptr)
+ LiveInts->print(errs());
+ else
+ MF->print(errs(), Indexes);
}
errs() << "*** Bad machine code: " << msg << " ***\n"
<< "- function: " << MF->getName() << "\n";
@@ -399,7 +422,8 @@ void MachineVerifier::report(const char *msg, const MachineInstr *MI) {
errs() << "- instruction: ";
if (Indexes && Indexes->hasIndex(MI))
errs() << Indexes->getInstructionIndex(MI) << '\t';
- MI->print(errs(), TM);
+ MI->print(errs(), /*SkipOpers=*/true);
+ errs() << '\n';
}
void MachineVerifier::report(const char *msg,
@@ -411,36 +435,24 @@ void MachineVerifier::report(const char *msg,
errs() << "\n";
}
-void MachineVerifier::report(const char *msg, const MachineFunction *MF,
- const LiveInterval &LI) {
- report(msg, MF);
- errs() << "- interval: " << LI << '\n';
-}
-
-void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
- const LiveInterval &LI) {
- report(msg, MBB);
+void MachineVerifier::report_context(const LiveInterval &LI) const {
errs() << "- interval: " << LI << '\n';
}
-void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
- const LiveRange &LR, unsigned Reg,
- unsigned LaneMask) {
- report(msg, MBB);
- errs() << "- liverange: " << LR << '\n';
+void MachineVerifier::report_context(const LiveRange &LR, unsigned Reg,
+ LaneBitmask LaneMask) const {
errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
if (LaneMask != 0)
- errs() << "- lanemask: " << format("%04X\n", LaneMask);
+ errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n';
+ errs() << "- liverange: " << LR << '\n';
}
-void MachineVerifier::report(const char *msg, const MachineFunction *MF,
- const LiveRange &LR, unsigned Reg,
- unsigned LaneMask) {
- report(msg, MF);
- errs() << "- liverange: " << LR << '\n';
- errs() << "- register: " << PrintReg(Reg, TRI) << '\n';
- if (LaneMask != 0)
- errs() << "- lanemask: " << format("%04X\n", LaneMask);
+void MachineVerifier::report_context(const LiveRange::Segment &S) const {
+ errs() << "- segment: " << S << '\n';
+}
+
+void MachineVerifier::report_context(const VNInfo &VNI) const {
+ errs() << "- ValNo: " << VNI.id << " (def " << VNI.def << ")\n";
}
void MachineVerifier::markReachable(const MachineBasicBlock *MBB) {
@@ -507,11 +519,8 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
if (MRI->isSSA()) {
// If this block has allocatable physical registers live-in, check that
// it is an entry block or landing pad.
- for (MachineBasicBlock::livein_iterator LI = MBB->livein_begin(),
- LE = MBB->livein_end();
- LI != LE; ++LI) {
- unsigned reg = *LI;
- if (isAllocatable(reg) && !MBB->isLandingPad() &&
+ for (const auto &LI : MBB->liveins()) {
+ if (isAllocatable(LI.PhysReg) && !MBB->isEHPad() &&
MBB != MBB->getParent()->begin()) {
report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB);
}
@@ -522,7 +531,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs;
for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
E = MBB->succ_end(); I != E; ++I) {
- if ((*I)->isLandingPad())
+ if ((*I)->isEHPad())
LandingPadSuccs.insert(*I);
if (!FunctionBlocks.count(*I))
report("MBB has successor that isn't part of the function.", MBB);
@@ -547,10 +556,12 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
const MCAsmInfo *AsmInfo = TM->getMCAsmInfo();
const BasicBlock *BB = MBB->getBasicBlock();
+ const Function *Fn = MF->getFunction();
if (LandingPadSuccs.size() > 1 &&
!(AsmInfo &&
AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
- BB && isa<SwitchInst>(BB->getTerminator())))
+ BB && isa<SwitchInst>(BB->getTerminator())) &&
+ !isFuncletEHPersonality(classifyEHPersonality(Fn->getPersonalityFn())))
report("MBB has more than one landing pad successor", MBB);
// Call AnalyzeBranch. If it succeeds, there several more conditions to check.
@@ -562,7 +573,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
// check whether its answers match up with reality.
if (!TBB && !FBB) {
// Block falls through to its successor.
- MachineFunction::const_iterator MBBI = MBB;
+ MachineFunction::const_iterator MBBI = MBB->getIterator();
++MBBI;
if (MBBI == MF->end()) {
// It's possible that the block legitimately ends with a noreturn
@@ -575,7 +586,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
} else if (MBB->succ_size() != 1+LandingPadSuccs.size()) {
report("MBB exits via unconditional fall-through but doesn't have "
"exactly one CFG successor!", MBB);
- } else if (!MBB->isSuccessor(MBBI)) {
+ } else if (!MBB->isSuccessor(&*MBBI)) {
report("MBB exits via unconditional fall-through but its successor "
"differs from its CFG successor!", MBB);
}
@@ -613,7 +624,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
}
} else if (TBB && !FBB && !Cond.empty()) {
// Block conditionally branches somewhere, otherwise falls through.
- MachineFunction::const_iterator MBBI = MBB;
+ MachineFunction::const_iterator MBBI = MBB->getIterator();
++MBBI;
if (MBBI == MF->end()) {
report("MBB conditionally falls through out of function!", MBB);
@@ -628,7 +639,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
} else if (MBB->succ_size() != 2) {
report("MBB exits via conditional branch/fall-through but doesn't have "
"exactly two CFG successors!", MBB);
- } else if (!matchPair(MBB->succ_begin(), TBB, MBBI)) {
+ } else if (!matchPair(MBB->succ_begin(), TBB, &*MBBI)) {
report("MBB exits via conditional branch/fall-through but the CFG "
"successors don't match the actual successors!", MBB);
}
@@ -680,13 +691,12 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
}
regsLive.clear();
- for (MachineBasicBlock::livein_iterator I = MBB->livein_begin(),
- E = MBB->livein_end(); I != E; ++I) {
- if (!TargetRegisterInfo::isPhysicalRegister(*I)) {
+ 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(*I, TRI, /*IncludeSelf=*/true);
+ for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
}
@@ -822,9 +832,12 @@ void
MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
const MCInstrDesc &MCID = MI->getDesc();
+ unsigned NumDefs = MCID.getNumDefs();
+ if (MCID.getOpcode() == TargetOpcode::PATCHPOINT)
+ NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0;
// The first MCID.NumDefs operands must be explicit register defines
- if (MONum < MCID.getNumDefs()) {
+ if (MONum < NumDefs) {
const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
if (!MO->isReg())
report("Explicit definition must be a register", MO, MONum);
@@ -972,13 +985,38 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
case MachineOperand::MO_FrameIndex:
if (LiveStks && LiveStks->hasInterval(MO->getIndex()) &&
LiveInts && !LiveInts->isNotInMIMap(MI)) {
- LiveInterval &LI = LiveStks->getInterval(MO->getIndex());
+ int FI = MO->getIndex();
+ LiveInterval &LI = LiveStks->getInterval(FI);
SlotIndex Idx = LiveInts->getInstructionIndex(MI);
- if (MI->mayLoad() && !LI.liveAt(Idx.getRegSlot(true))) {
+
+ bool stores = MI->mayStore();
+ bool loads = MI->mayLoad();
+ // For a memory-to-memory move, we need to check if the frame
+ // index is used for storing or loading, by inspecting the
+ // memory operands.
+ if (stores && loads) {
+ for (auto *MMO : MI->memoperands()) {
+ const PseudoSourceValue *PSV = MMO->getPseudoValue();
+ if (PSV == nullptr) continue;
+ const FixedStackPseudoSourceValue *Value =
+ dyn_cast<FixedStackPseudoSourceValue>(PSV);
+ if (Value == nullptr) continue;
+ if (Value->getFrameIndex() != FI) continue;
+
+ if (MMO->isStore())
+ loads = false;
+ else
+ stores = false;
+ break;
+ }
+ if (loads == stores)
+ report("Missing fixed stack memoperand.", MI);
+ }
+ if (loads && !LI.liveAt(Idx.getRegSlot(true))) {
report("Instruction loads from dead spill slot", MO, MONum);
errs() << "Live stack: " << LI << '\n';
}
- if (MI->mayStore() && !LI.liveAt(Idx.getRegSlot())) {
+ if (stores && !LI.liveAt(Idx.getRegSlot())) {
report("Instruction stores to dead spill slot", MO, MONum);
errs() << "Live stack: " << LI << '\n';
}
@@ -1387,40 +1425,39 @@ void MachineVerifier::verifyLiveIntervals() {
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const VNInfo *VNI, unsigned Reg,
- unsigned LaneMask) {
+ LaneBitmask LaneMask) {
if (VNI->isUnused())
return;
const VNInfo *DefVNI = LR.getVNInfoAt(VNI->def);
if (!DefVNI) {
- report("Valno not live at def and not marked unused", MF, LR, Reg,
- LaneMask);
- errs() << "Valno #" << VNI->id << '\n';
+ report("Value not live at VNInfo def and not marked unused", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
return;
}
if (DefVNI != VNI) {
- report("Live segment at def has different valno", MF, LR, Reg, LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def
- << " where valno #" << DefVNI->id << " is live\n";
+ report("Live segment at def has different VNInfo", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
return;
}
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def);
if (!MBB) {
- report("Invalid definition index", MF, LR, Reg, LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def
- << " in " << LR << '\n';
+ report("Invalid VNInfo definition index", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
return;
}
if (VNI->isPHIDef()) {
if (VNI->def != LiveInts->getMBBStartIdx(MBB)) {
- report("PHIDef value is not defined at MBB start", MBB, LR, Reg,
- LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def
- << ", not at the beginning of BB#" << MBB->getNumber() << '\n';
+ report("PHIDef VNInfo is not defined at MBB start", MBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
}
return;
}
@@ -1428,8 +1465,9 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
// Non-PHI def.
const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def);
if (!MI) {
- report("No instruction at def index", MBB, LR, Reg, LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n';
+ report("No instruction at VNInfo def index", MBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
return;
}
@@ -1457,60 +1495,67 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (!hasDef) {
report("Defining instruction does not modify register", MI);
- errs() << "Valno #" << VNI->id << " in " << LR << '\n';
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
}
// Early clobber defs begin at USE slots, but other defs must begin at
// DEF slots.
if (isEarlyClobber) {
if (!VNI->def.isEarlyClobber()) {
- report("Early clobber def must be at an early-clobber slot", MBB, LR,
- Reg, LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n';
+ report("Early clobber def must be at an early-clobber slot", MBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
}
} else if (!VNI->def.isRegister()) {
- report("Non-PHI, non-early clobber def must be at a register slot",
- MBB, LR, Reg, LaneMask);
- errs() << "Valno #" << VNI->id << " is defined at " << VNI->def << '\n';
+ report("Non-PHI, non-early clobber def must be at a register slot", MBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
}
}
}
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const LiveRange::const_iterator I,
- unsigned Reg, unsigned LaneMask) {
+ unsigned Reg, LaneBitmask LaneMask)
+{
const LiveRange::Segment &S = *I;
const VNInfo *VNI = S.valno;
assert(VNI && "Live segment has no valno");
if (VNI->id >= LR.getNumValNums() || VNI != LR.getValNumInfo(VNI->id)) {
- report("Foreign valno in live segment", MF, LR, Reg, LaneMask);
- errs() << S << " has a bad valno\n";
+ report("Foreign valno in live segment", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
+ report_context(*VNI);
}
if (VNI->isUnused()) {
- report("Live segment valno is marked unused", MF, LR, Reg, LaneMask);
- errs() << S << '\n';
+ report("Live segment valno is marked unused", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(S.start);
if (!MBB) {
- report("Bad start of live segment, no basic block", MF, LR, Reg, LaneMask);
- errs() << S << '\n';
+ report("Bad start of live segment, no basic block", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
return;
}
SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB);
if (S.start != MBBStartIdx && S.start != VNI->def) {
- report("Live segment must begin at MBB entry or valno def", MBB, LR, Reg,
- LaneMask);
- errs() << S << '\n';
+ report("Live segment must begin at MBB entry or valno def", MBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
const MachineBasicBlock *EndMBB =
LiveInts->getMBBFromIndex(S.end.getPrevSlot());
if (!EndMBB) {
- report("Bad end of live segment, no basic block", MF, LR, Reg, LaneMask);
- errs() << S << '\n';
+ report("Bad end of live segment, no basic block", MF);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
return;
}
@@ -1527,26 +1572,26 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const MachineInstr *MI =
LiveInts->getInstructionFromIndex(S.end.getPrevSlot());
if (!MI) {
- report("Live segment doesn't end at a valid instruction", EndMBB, LR, Reg,
- LaneMask);
- errs() << S << '\n';
+ report("Live segment doesn't end at a valid instruction", EndMBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
return;
}
// The block slot must refer to a basic block boundary.
if (S.end.isBlock()) {
- report("Live segment ends at B slot of an instruction", EndMBB, LR, Reg,
- LaneMask);
- errs() << S << '\n';
+ report("Live segment ends at B slot of an instruction", EndMBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
if (S.end.isDead()) {
// Segment ends on the dead slot.
// That means there must be a dead def.
if (!SlotIndex::isSameInstr(S.start, S.end)) {
- report("Live segment ending at dead slot spans instructions", EndMBB, LR,
- Reg, LaneMask);
- errs() << S << '\n';
+ report("Live segment ending at dead slot spans instructions", EndMBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
}
@@ -1555,9 +1600,9 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
if (S.end.isEarlyClobber()) {
if (I+1 == LR.end() || (I+1)->start != S.end) {
report("Live segment ending at early clobber slot must be "
- "redefined by an EC def in the same instruction", EndMBB, LR, Reg,
- LaneMask);
- errs() << S << '\n';
+ "redefined by an EC def in the same instruction", EndMBB);
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
}
@@ -1587,14 +1632,15 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
!hasSubRegDef) {
report("Instruction ending live segment doesn't read the register",
MI);
- errs() << S << " in " << LR << '\n';
+ report_context(LR, Reg, LaneMask);
+ report_context(S);
}
}
}
}
// Now check all the basic blocks in this live segment.
- MachineFunction::const_iterator MFI = MBB;
+ MachineFunction::const_iterator MFI = MBB->getIterator();
// Is this live segment the beginning of a non-PHIDef VN?
if (S.start == VNI->def && !VNI->isPHIDef()) {
// Not live-in to any blocks.
@@ -1604,10 +1650,10 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
++MFI;
}
for (;;) {
- assert(LiveInts->isLiveInToMBB(LR, MFI));
+ assert(LiveInts->isLiveInToMBB(LR, &*MFI));
// We don't know how to track physregs into a landing pad.
if (!TargetRegisterInfo::isVirtualRegister(Reg) &&
- MFI->isLandingPad()) {
+ MFI->isEHPad()) {
if (&*MFI == EndMBB)
break;
++MFI;
@@ -1616,7 +1662,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Is VNI a PHI-def in the current block?
bool IsPHI = VNI->isPHIDef() &&
- VNI->def == LiveInts->getMBBStartIdx(MFI);
+ VNI->def == LiveInts->getMBBStartIdx(&*MFI);
// Check that VNI is live-out of all predecessors.
for (MachineBasicBlock::const_pred_iterator PI = MFI->pred_begin(),
@@ -1626,22 +1672,23 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// All predecessors must have a live-out value.
if (!PVNI) {
- report("Register not marked live out of predecessor", *PI, LR, Reg,
- LaneMask);
- errs() << "Valno #" << VNI->id << " live into BB#" << MFI->getNumber()
- << '@' << LiveInts->getMBBStartIdx(MFI) << ", not live before "
- << PEnd << '\n';
+ report("Register not marked live out of predecessor", *PI);
+ report_context(LR, Reg, LaneMask);
+ report_context(*VNI);
+ errs() << " live into BB#" << MFI->getNumber()
+ << '@' << LiveInts->getMBBStartIdx(&*MFI) << ", not live before "
+ << PEnd << '\n';
continue;
}
// Only PHI-defs can take different predecessor values.
if (!IsPHI && PVNI != VNI) {
- report("Different value live out of predecessor", *PI, LR, Reg,
- LaneMask);
+ report("Different value live out of predecessor", *PI);
+ report_context(LR, Reg, LaneMask);
errs() << "Valno #" << PVNI->id << " live out of BB#"
- << (*PI)->getNumber() << '@' << PEnd
- << "\nValno #" << VNI->id << " live into BB#" << MFI->getNumber()
- << '@' << LiveInts->getMBBStartIdx(MFI) << '\n';
+ << (*PI)->getNumber() << '@' << PEnd << "\nValno #" << VNI->id
+ << " live into BB#" << MFI->getNumber() << '@'
+ << LiveInts->getMBBStartIdx(&*MFI) << '\n';
}
}
if (&*MFI == EndMBB)
@@ -1651,7 +1698,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
}
void MachineVerifier::verifyLiveRange(const LiveRange &LR, unsigned Reg,
- unsigned LaneMask) {
+ LaneBitmask LaneMask) {
for (const VNInfo *VNI : LR.valnos)
verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
@@ -1664,24 +1711,35 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
assert(TargetRegisterInfo::isVirtualRegister(Reg));
verifyLiveRange(LI, Reg);
- unsigned Mask = 0;
- unsigned MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
+ LaneBitmask Mask = 0;
+ LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
for (const LiveInterval::SubRange &SR : LI.subranges()) {
- if ((Mask & SR.LaneMask) != 0)
- report("Lane masks of sub ranges overlap in live interval", MF, LI);
- if ((SR.LaneMask & ~MaxMask) != 0)
- report("Subrange lanemask is invalid", MF, LI);
+ if ((Mask & SR.LaneMask) != 0) {
+ report("Lane masks of sub ranges overlap in live interval", MF);
+ report_context(LI);
+ }
+ if ((SR.LaneMask & ~MaxMask) != 0) {
+ report("Subrange lanemask is invalid", MF);
+ report_context(LI);
+ }
+ if (SR.empty()) {
+ report("Subrange must not be empty", MF);
+ report_context(SR, LI.reg, SR.LaneMask);
+ }
Mask |= SR.LaneMask;
verifyLiveRange(SR, LI.reg, SR.LaneMask);
- if (!LI.covers(SR))
- report("A Subrange is not covered by the main range", MF, LI);
+ if (!LI.covers(SR)) {
+ report("A Subrange is not covered by the main range", MF);
+ report_context(LI);
+ }
}
// Check the LI only has one connected component.
ConnectedVNInfoEqClasses ConEQ(*LiveInts);
- unsigned NumComp = ConEQ.Classify(&LI);
+ unsigned NumComp = ConEQ.Classify(LI);
if (NumComp > 1) {
- report("Multiple connected components in live interval", MF, LI);
+ report("Multiple connected components in live interval", MF);
+ report_context(LI);
for (unsigned comp = 0; comp != NumComp; ++comp) {
errs() << comp << ": valnos";
for (LiveInterval::const_vni_iterator I = LI.vni_begin(),
OpenPOWER on IntegriCloud