diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/MachineVerifier.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/MachineVerifier.cpp | 436 |
1 files changed, 260 insertions, 176 deletions
diff --git a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp index c50a95a06505..c9fe7681e280 100644 --- a/contrib/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/contrib/llvm/lib/CodeGen/MachineVerifier.cpp @@ -1,4 +1,4 @@ -//===-- MachineVerifier.cpp - Machine Code Verifier -----------------------===// +//===- MachineVerifier.cpp - Machine Code Verifier ------------------------===// // // The LLVM Compiler Infrastructure // @@ -23,41 +23,68 @@ // the verifier errors. //===----------------------------------------------------------------------===// +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/DepthFirstIterator.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetOperations.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include "llvm/Analysis/EHPersonalities.h" -#include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/GlobalISel/RegisterBank.h" +#include "llvm/CodeGen/LiveInterval.h" +#include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LiveStackAnalysis.h" #include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBundle.h" #include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/CodeGen/SlotIndexes.h" #include "llvm/CodeGen/StackMaps.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetOpcodes.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/Instructions.h" +#include "llvm/MC/LaneBitmask.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/Support/Debug.h" +#include "llvm/MC/MCInstrDesc.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCTargetOptions.h" +#include "llvm/Pass.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/Support/LowLevelTypeImpl.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> + using namespace llvm; namespace { - struct MachineVerifier { - MachineVerifier(Pass *pass, const char *b) : - PASS(pass), - Banner(b) - {} + struct MachineVerifier { + MachineVerifier(Pass *pass, const char *b) : PASS(pass), Banner(b) {} unsigned verify(MachineFunction &MF); @@ -75,11 +102,11 @@ namespace { bool isFunctionRegBankSelected; bool isFunctionSelected; - typedef SmallVector<unsigned, 16> RegVector; - typedef SmallVector<const uint32_t*, 4> RegMaskVector; - typedef DenseSet<unsigned> RegSet; - typedef DenseMap<unsigned, const MachineInstr*> RegMap; - typedef SmallPtrSet<const MachineBasicBlock*, 8> BlockSet; + using RegVector = SmallVector<unsigned, 16>; + using RegMaskVector = SmallVector<const uint32_t *, 4>; + using RegSet = DenseSet<unsigned>; + using RegMap = DenseMap<unsigned, const MachineInstr *>; + using BlockSet = SmallPtrSet<const MachineBasicBlock *, 8>; const MachineInstr *FirstTerminator; BlockSet FunctionBlocks; @@ -101,7 +128,7 @@ namespace { struct BBInfo { // Is this MBB reachable from the MF entry point? - bool reachable; + bool reachable = false; // Vregs that must be live in because they are used without being // defined. Map value is the user. @@ -126,7 +153,7 @@ namespace { // Set versions of block's predecessor and successor lists. BlockSet Preds, Succs; - BBInfo() : reachable(false) {} + BBInfo() = default; // Add register to vregsPassed if it belongs there. Return true if // anything changed. @@ -237,7 +264,7 @@ namespace { void markReachable(const MachineBasicBlock *MBB); void calcRegsPassed(); - void checkPHIOps(const MachineBasicBlock *MBB); + void checkPHIOps(const MachineBasicBlock &MBB); void calcRegsRequired(); void verifyLiveVariables(); @@ -259,6 +286,7 @@ namespace { struct MachineVerifierPass : public MachineFunctionPass { static char ID; // Pass ID, replacement for typeid + const std::string Banner; MachineVerifierPass(std::string banner = std::string()) @@ -279,9 +307,10 @@ namespace { } }; -} +} // end anonymous namespace char MachineVerifierPass::ID = 0; + INITIALIZE_PASS(MachineVerifierPass, "machineverifier", "Verify generated machine code", false, false) @@ -442,9 +471,8 @@ void MachineVerifier::report(const char *msg, const MachineFunction *MF) { void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) { assert(MBB); report(msg, MBB->getParent()); - errs() << "- basic block: BB#" << MBB->getNumber() - << ' ' << MBB->getName() - << " (" << (const void*)MBB << ')'; + errs() << "- basic block: " << printMBBReference(*MBB) << ' ' + << MBB->getName() << " (" << (const void *)MBB << ')'; if (Indexes) errs() << " [" << Indexes->getMBBStartIdx(MBB) << ';' << Indexes->getMBBEndIdx(MBB) << ')'; @@ -499,14 +527,14 @@ void MachineVerifier::report_context_liverange(const LiveRange &LR) const { } void MachineVerifier::report_context_vreg(unsigned VReg) const { - errs() << "- v. register: " << PrintReg(VReg, TRI) << '\n'; + errs() << "- v. register: " << printReg(VReg, TRI) << '\n'; } void MachineVerifier::report_context_vreg_regunit(unsigned VRegOrUnit) const { if (TargetRegisterInfo::isVirtualRegister(VRegOrUnit)) { report_context_vreg(VRegOrUnit); } else { - errs() << "- regunit: " << PrintRegUnit(VRegOrUnit, TRI) << '\n'; + errs() << "- regunit: " << printRegUnit(VRegOrUnit, TRI) << '\n'; } } @@ -590,8 +618,8 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { report("MBB has successor that isn't part of the function.", MBB); if (!MBBInfoMap[*I].Preds.count(MBB)) { report("Inconsistent CFG", MBB); - errs() << "MBB is not in the predecessor list of the successor BB#" - << (*I)->getNumber() << ".\n"; + errs() << "MBB is not in the predecessor list of the successor " + << printMBBReference(*(*I)) << ".\n"; } } @@ -602,19 +630,19 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) { report("MBB has predecessor that isn't part of the function.", MBB); if (!MBBInfoMap[*I].Succs.count(MBB)) { report("Inconsistent CFG", MBB); - errs() << "MBB is not in the successor list of the predecessor BB#" - << (*I)->getNumber() << ".\n"; + errs() << "MBB is not in the successor list of the predecessor " + << printMBBReference(*(*I)) << ".\n"; } } const MCAsmInfo *AsmInfo = TM->getMCAsmInfo(); const BasicBlock *BB = MBB->getBasicBlock(); - const Function *Fn = MF->getFunction(); + const Function &F = MF->getFunction(); if (LandingPadSuccs.size() > 1 && !(AsmInfo && AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj && BB && isa<SwitchInst>(BB->getTerminator())) && - !isFuncletEHPersonality(classifyEHPersonality(Fn->getPersonalityFn()))) + !isFuncletEHPersonality(classifyEHPersonality(F.getPersonalityFn()))) report("MBB has more than one landing pad successor", MBB); // Call AnalyzeBranch. If it succeeds, there several more conditions to check. @@ -926,6 +954,23 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { report("Generic instruction accessing memory must have one mem operand", MI); break; + case TargetOpcode::G_PHI: { + LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); + if (!DstTy.isValid() || + !std::all_of(MI->operands_begin() + 1, MI->operands_end(), + [this, &DstTy](const MachineOperand &MO) { + if (!MO.isReg()) + return true; + LLT Ty = MRI->getType(MO.getReg()); + if (!Ty.isValid() || (Ty != DstTy)) + return false; + return true; + })) + report("Generic Instruction G_PHI has operands with incompatible/missing " + "types", + MI); + break; + } case TargetOpcode::STATEPOINT: if (!MI->getOperand(StatepointOpers::IDPos).isImm() || !MI->getOperand(StatepointOpers::NBytesPos).isImm() || @@ -1039,101 +1084,112 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) { report("Two-address instruction operands must be identical", MO, MONum); // Check register classes. - if (MONum < MCID.getNumOperands() && !MO->isImplicit()) { - unsigned SubIdx = MO->getSubReg(); + unsigned SubIdx = MO->getSubReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg)) { - if (SubIdx) { - report("Illegal subregister index for physical register", MO, MONum); - return; - } + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + if (SubIdx) { + report("Illegal subregister index for physical register", MO, MONum); + return; + } + if (MONum < MCID.getNumOperands()) { if (const TargetRegisterClass *DRC = TII->getRegClass(MCID, MONum, TRI, *MF)) { if (!DRC->contains(Reg)) { report("Illegal physical register for instruction", MO, MONum); - errs() << TRI->getName(Reg) << " is not a " - << TRI->getRegClassName(DRC) << " register.\n"; + errs() << printReg(Reg, TRI) << " is not a " + << TRI->getRegClassName(DRC) << " register.\n"; } } - } else { - // Virtual register. - const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg); - if (!RC) { - // This is a generic virtual register. - - // If we're post-Select, we can't have gvregs anymore. - if (isFunctionSelected) { - report("Generic virtual register invalid in a Selected function", - MO, MONum); - return; - } + } + if (MO->isRenamable() && + ((MO->isDef() && MI->hasExtraDefRegAllocReq()) || + (MO->isUse() && MI->hasExtraSrcRegAllocReq()))) { + report("Illegal isRenamable setting for opcode with extra regalloc " + "requirements", + MO, MONum); + return; + } + } else { + // Virtual register. + const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg); + if (!RC) { + // This is a generic virtual register. + + // If we're post-Select, we can't have gvregs anymore. + if (isFunctionSelected) { + report("Generic virtual register invalid in a Selected function", + MO, MONum); + return; + } - // The gvreg must have a type and it must not have a SubIdx. - LLT Ty = MRI->getType(Reg); - if (!Ty.isValid()) { - report("Generic virtual register must have a valid type", MO, - MONum); - return; - } + // The gvreg must have a type and it must not have a SubIdx. + LLT Ty = MRI->getType(Reg); + if (!Ty.isValid()) { + report("Generic virtual register must have a valid type", MO, + MONum); + return; + } - const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg); + const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg); - // If we're post-RegBankSelect, the gvreg must have a bank. - if (!RegBank && isFunctionRegBankSelected) { - report("Generic virtual register must have a bank in a " - "RegBankSelected function", - MO, MONum); - return; - } + // If we're post-RegBankSelect, the gvreg must have a bank. + if (!RegBank && isFunctionRegBankSelected) { + report("Generic virtual register must have a bank in a " + "RegBankSelected function", + MO, MONum); + return; + } - // Make sure the register fits into its register bank if any. - if (RegBank && Ty.isValid() && - RegBank->getSize() < Ty.getSizeInBits()) { - report("Register bank is too small for virtual register", MO, - MONum); - errs() << "Register bank " << RegBank->getName() << " too small(" - << RegBank->getSize() << ") to fit " << Ty.getSizeInBits() - << "-bits\n"; - return; - } - if (SubIdx) { - report("Generic virtual register does not subregister index", MO, - MONum); - return; - } + // Make sure the register fits into its register bank if any. + if (RegBank && Ty.isValid() && + RegBank->getSize() < Ty.getSizeInBits()) { + report("Register bank is too small for virtual register", MO, + MONum); + errs() << "Register bank " << RegBank->getName() << " too small(" + << RegBank->getSize() << ") to fit " << Ty.getSizeInBits() + << "-bits\n"; + return; + } + if (SubIdx) { + report("Generic virtual register does not subregister index", MO, + MONum); + return; + } - // If this is a target specific instruction and this operand - // has register class constraint, the virtual register must - // comply to it. - if (!isPreISelGenericOpcode(MCID.getOpcode()) && - TII->getRegClass(MCID, MONum, TRI, *MF)) { - report("Virtual register does not match instruction constraint", MO, - MONum); - errs() << "Expect register class " - << TRI->getRegClassName( - TII->getRegClass(MCID, MONum, TRI, *MF)) - << " but got nothing\n"; - return; - } + // If this is a target specific instruction and this operand + // has register class constraint, the virtual register must + // comply to it. + if (!isPreISelGenericOpcode(MCID.getOpcode()) && + MONum < MCID.getNumOperands() && + TII->getRegClass(MCID, MONum, TRI, *MF)) { + report("Virtual register does not match instruction constraint", MO, + MONum); + errs() << "Expect register class " + << TRI->getRegClassName( + TII->getRegClass(MCID, MONum, TRI, *MF)) + << " but got nothing\n"; + return; + } - break; + break; + } + if (SubIdx) { + const TargetRegisterClass *SRC = + TRI->getSubClassWithSubReg(RC, SubIdx); + if (!SRC) { + report("Invalid subregister index for virtual register", MO, MONum); + errs() << "Register class " << TRI->getRegClassName(RC) + << " does not support subreg index " << SubIdx << "\n"; + return; } - if (SubIdx) { - const TargetRegisterClass *SRC = - TRI->getSubClassWithSubReg(RC, SubIdx); - if (!SRC) { - report("Invalid subregister index for virtual register", MO, MONum); - errs() << "Register class " << TRI->getRegClassName(RC) - << " does not support subreg index " << SubIdx << "\n"; - return; - } - if (RC != SRC) { - report("Invalid register class for subregister index", MO, MONum); - errs() << "Register class " << TRI->getRegClassName(RC) - << " does not fully support subreg index " << SubIdx << "\n"; - return; - } + if (RC != SRC) { + report("Invalid register class for subregister index", MO, MONum); + errs() << "Register class " << TRI->getRegClassName(RC) + << " does not fully support subreg index " << SubIdx << "\n"; + return; } + } + if (MONum < MCID.getNumOperands()) { if (const TargetRegisterClass *DRC = TII->getRegClass(MCID, MONum, TRI, *MF)) { if (SubIdx) { @@ -1449,8 +1505,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) { } } -void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) { -} +void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) {} // This function gets called after visiting all instructions in a bundle. The // argument points to the bundle header. @@ -1559,32 +1614,66 @@ void MachineVerifier::calcRegsRequired() { // Check PHI instructions at the beginning of MBB. It is assumed that // calcRegsPassed has been run so BBInfo::isLiveOut is valid. -void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) { +void MachineVerifier::checkPHIOps(const MachineBasicBlock &MBB) { + BBInfo &MInfo = MBBInfoMap[&MBB]; + SmallPtrSet<const MachineBasicBlock*, 8> seen; - for (const auto &BBI : *MBB) { - if (!BBI.isPHI()) + for (const MachineInstr &Phi : MBB) { + if (!Phi.isPHI()) break; seen.clear(); - for (unsigned i = 1, e = BBI.getNumOperands(); i != e; i += 2) { - unsigned Reg = BBI.getOperand(i).getReg(); - const MachineBasicBlock *Pre = BBI.getOperand(i + 1).getMBB(); - if (!Pre->isSuccessor(MBB)) + const MachineOperand &MODef = Phi.getOperand(0); + if (!MODef.isReg() || !MODef.isDef()) { + report("Expected first PHI operand to be a register def", &MODef, 0); + continue; + } + if (MODef.isTied() || MODef.isImplicit() || MODef.isInternalRead() || + MODef.isEarlyClobber() || MODef.isDebug()) + report("Unexpected flag on PHI operand", &MODef, 0); + unsigned DefReg = MODef.getReg(); + if (!TargetRegisterInfo::isVirtualRegister(DefReg)) + report("Expected first PHI operand to be a virtual register", &MODef, 0); + + for (unsigned I = 1, E = Phi.getNumOperands(); I != E; I += 2) { + const MachineOperand &MO0 = Phi.getOperand(I); + if (!MO0.isReg()) { + report("Expected PHI operand to be a register", &MO0, I); + continue; + } + if (MO0.isImplicit() || MO0.isInternalRead() || MO0.isEarlyClobber() || + MO0.isDebug() || MO0.isTied()) + report("Unexpected flag on PHI operand", &MO0, I); + + const MachineOperand &MO1 = Phi.getOperand(I + 1); + if (!MO1.isMBB()) { + report("Expected PHI operand to be a basic block", &MO1, I + 1); + continue; + } + + const MachineBasicBlock &Pre = *MO1.getMBB(); + if (!Pre.isSuccessor(&MBB)) { + report("PHI input is not a predecessor block", &MO1, I + 1); continue; - seen.insert(Pre); - BBInfo &PrInfo = MBBInfoMap[Pre]; - if (PrInfo.reachable && !PrInfo.isLiveOut(Reg)) - report("PHI operand is not live-out from predecessor", - &BBI.getOperand(i), i); + } + + if (MInfo.reachable) { + seen.insert(&Pre); + BBInfo &PrInfo = MBBInfoMap[&Pre]; + if (!MO0.isUndef() && PrInfo.reachable && + !PrInfo.isLiveOut(MO0.getReg())) + report("PHI operand is not live-out from predecessor", &MO0, I); + } } // Did we see all predecessors? - for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(), - PrE = MBB->pred_end(); PrI != PrE; ++PrI) { - if (!seen.count(*PrI)) { - report("Missing PHI operand", &BBI); - errs() << "BB#" << (*PrI)->getNumber() - << " is a predecessor according to the CFG.\n"; + if (MInfo.reachable) { + for (MachineBasicBlock *Pred : MBB.predecessors()) { + if (!seen.count(Pred)) { + report("Missing PHI operand", &Phi); + errs() << printMBBReference(*Pred) + << " is a predecessor according to the CFG.\n"; + } } } } @@ -1593,15 +1682,8 @@ void MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) { void MachineVerifier::visitMachineFunctionAfter() { calcRegsPassed(); - for (const auto &MBB : *MF) { - BBInfo &MInfo = MBBInfoMap[&MBB]; - - // Skip unreachable MBBs. - if (!MInfo.reachable) - continue; - - checkPHIOps(&MBB); - } + for (const MachineBasicBlock &MBB : *MF) + checkPHIOps(MBB); // Now check liveness info if available calcRegsRequired(); @@ -1614,8 +1696,8 @@ void MachineVerifier::visitMachineFunctionAfter() { ++I) if (MInfo.regsKilled.count(*I)) { report("Virtual register killed in block, but needed live out.", &MBB); - errs() << "Virtual register " << PrintReg(*I) - << " is used after the block.\n"; + errs() << "Virtual register " << printReg(*I) + << " is used after the block.\n"; } } @@ -1647,14 +1729,14 @@ void MachineVerifier::verifyLiveVariables() { if (MInfo.vregsRequired.count(Reg)) { if (!VI.AliveBlocks.test(MBB.getNumber())) { report("LiveVariables: Block missing from AliveBlocks", &MBB); - errs() << "Virtual register " << PrintReg(Reg) - << " must be live through the block.\n"; + errs() << "Virtual register " << printReg(Reg) + << " must be live through the block.\n"; } } else { if (VI.AliveBlocks.test(MBB.getNumber())) { report("LiveVariables: Block should not be in AliveBlocks", &MBB); - errs() << "Virtual register " << PrintReg(Reg) - << " is not needed live through the block.\n"; + errs() << "Virtual register " << printReg(Reg) + << " is not needed live through the block.\n"; } } } @@ -1672,7 +1754,7 @@ void MachineVerifier::verifyLiveIntervals() { if (!LiveInts->hasInterval(Reg)) { report("Missing live interval for virtual register", MF); - errs() << PrintReg(Reg, TRI) << " still has defs or uses\n"; + errs() << printReg(Reg, TRI) << " still has defs or uses\n"; continue; } @@ -1887,7 +1969,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, if (MOI->isDef()) { if (Sub != 0) { hasSubRegDef = true; - // An operand vreg0:sub0<def> reads vreg0:sub1..n. Invert the lane + // An operand %0:sub0 reads %0:sub1..n. Invert the lane // mask for subregister defs. Read-undef defs will be handled by // readsReg below. SLM = ~SLM; @@ -1935,7 +2017,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, // Skip this block. ++MFI; } - for (;;) { + while (true) { assert(LiveInts->isLiveInToMBB(LR, &*MFI)); // We don't know how to track physregs into a landing pad. if (!TargetRegisterInfo::isVirtualRegister(Reg) && @@ -1964,8 +2046,8 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, 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 " + errs() << " live into " << printMBBReference(*MFI) << '@' + << LiveInts->getMBBStartIdx(&*MFI) << ", not live before " << PEnd << '\n'; continue; } @@ -1974,9 +2056,9 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR, if (!IsPHI && PVNI != VNI) { 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() << '@' + errs() << "Valno #" << PVNI->id << " live out of " + << printMBBReference(*(*PI)) << '@' << PEnd << "\nValno #" + << VNI->id << " live into " << printMBBReference(*MFI) << '@' << LiveInts->getMBBStartIdx(&*MFI) << '\n'; } } @@ -2041,23 +2123,25 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) { } namespace { + // FrameSetup and FrameDestroy can have zero adjustment, so using a single // integer, we can't tell whether it is a FrameSetup or FrameDestroy if the // value is zero. // We use a bool plus an integer to capture the stack state. struct StackStateOfBB { - StackStateOfBB() : EntryValue(0), ExitValue(0), EntryIsSetup(false), - ExitIsSetup(false) { } + StackStateOfBB() = default; StackStateOfBB(int EntryVal, int ExitVal, bool EntrySetup, bool ExitSetup) : EntryValue(EntryVal), ExitValue(ExitVal), EntryIsSetup(EntrySetup), - ExitIsSetup(ExitSetup) { } + ExitIsSetup(ExitSetup) {} + // Can be negative, which means we are setting up a frame. - int EntryValue; - int ExitValue; - bool EntryIsSetup; - bool ExitIsSetup; + int EntryValue = 0; + int ExitValue = 0; + bool EntryIsSetup = false; + bool ExitIsSetup = false; }; -} + +} // end anonymous namespace /// Make sure on every path through the CFG, a FrameSetup <n> is always followed /// by a FrameDestroy <n>, stack adjustments are identical on all @@ -2073,8 +2157,8 @@ void MachineVerifier::verifyStackFrame() { df_iterator_default_set<const MachineBasicBlock*> Reachable; // Visit the MBBs in DFS order. - for (df_ext_iterator<const MachineFunction*, - df_iterator_default_set<const MachineBasicBlock*> > + for (df_ext_iterator<const MachineFunction *, + df_iterator_default_set<const MachineBasicBlock *>> DFI = df_ext_begin(MF, Reachable), DFE = df_ext_end(MF, Reachable); DFI != DFE; ++DFI) { const MachineBasicBlock *MBB = *DFI; @@ -2125,11 +2209,11 @@ void MachineVerifier::verifyStackFrame() { (SPState[(*I)->getNumber()].ExitValue != BBState.EntryValue || SPState[(*I)->getNumber()].ExitIsSetup != BBState.EntryIsSetup)) { report("The exit stack state of a predecessor is inconsistent.", MBB); - errs() << "Predecessor BB#" << (*I)->getNumber() << " has exit state (" - << SPState[(*I)->getNumber()].ExitValue << ", " - << SPState[(*I)->getNumber()].ExitIsSetup - << "), while BB#" << MBB->getNumber() << " has entry state (" - << BBState.EntryValue << ", " << BBState.EntryIsSetup << ").\n"; + errs() << "Predecessor " << printMBBReference(*(*I)) + << " has exit state (" << SPState[(*I)->getNumber()].ExitValue + << ", " << SPState[(*I)->getNumber()].ExitIsSetup << "), while " + << printMBBReference(*MBB) << " has entry state (" + << BBState.EntryValue << ", " << BBState.EntryIsSetup << ").\n"; } } @@ -2141,11 +2225,11 @@ void MachineVerifier::verifyStackFrame() { (SPState[(*I)->getNumber()].EntryValue != BBState.ExitValue || SPState[(*I)->getNumber()].EntryIsSetup != BBState.ExitIsSetup)) { report("The entry stack state of a successor is inconsistent.", MBB); - errs() << "Successor BB#" << (*I)->getNumber() << " has entry state (" - << SPState[(*I)->getNumber()].EntryValue << ", " - << SPState[(*I)->getNumber()].EntryIsSetup - << "), while BB#" << MBB->getNumber() << " has exit state (" - << BBState.ExitValue << ", " << BBState.ExitIsSetup << ").\n"; + errs() << "Successor " << printMBBReference(*(*I)) + << " has entry state (" << SPState[(*I)->getNumber()].EntryValue + << ", " << SPState[(*I)->getNumber()].EntryIsSetup << "), while " + << printMBBReference(*MBB) << " has exit state (" + << BBState.ExitValue << ", " << BBState.ExitIsSetup << ").\n"; } } |