diff options
-rw-r--r-- | include/llvm/CodeGen/Passes.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 53 | ||||
-rw-r--r-- | lib/CodeGen/MachineVerifier.cpp | 677 |
4 files changed, 711 insertions, 27 deletions
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index ff80dba..a7657b2 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -196,6 +196,13 @@ namespace llvm { /// createStackProtectorPass - This pass adds stack protectors to functions. FunctionPass *createStackProtectorPass(const TargetLowering *tli); + /// createMachineVerifierPass - This pass verifies cenerated machine code + /// instructions for correctness. + /// + /// @param allowPhysDoubleDefs ignore double definitions of + /// registers. Useful before LiveVariables has run. + FunctionPass *createMachineVerifierPass(bool allowDoubleDefs); + } // End llvm namespace #endif diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index 9be7cf3..2866e0e 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/lib/CodeGen/CMakeLists.txt @@ -26,6 +26,7 @@ add_llvm_library(LLVMCodeGen MachinePassRegistry.cpp MachineRegisterInfo.cpp MachineSink.cpp + MachineVerifier.cpp OcamlGC.cpp PBQP.cpp PHIElimination.cpp diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index cf16a65..580f5f9 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -37,6 +37,9 @@ static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden, cl::desc("Dump emitter generated instructions as assembly")); static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, cl::desc("Dump garbage collector data")); +static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, + cl::desc("Verify generated machine code"), + cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); // When this works it will be on by default. static cl::opt<bool> @@ -132,6 +135,15 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, return false; // success! } +static void printAndVerify(PassManagerBase &PM, + bool allowDoubleDefs = false) { + if (PrintMachineCode) + PM.add(createMachineFunctionPrinterPass(cerr)); + + if (VerifyMachineCode) + PM.add(createMachineVerifierPass(allowDoubleDefs)); +} + /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both /// emitting to assembly files or machine code output. /// @@ -176,17 +188,17 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, return true; // Print the instruction selected machine code... - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM, /* allowDoubleDefs= */ true); if (OptLevel != CodeGenOpt::None) { PM.add(createMachineLICMPass()); PM.add(createMachineSinkingPass()); + printAndVerify(PM, /* allowDoubleDefs= */ true); } // Run pre-ra passes. - if (addPreRegAlloc(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + if (addPreRegAlloc(PM, OptLevel)) + printAndVerify(PM); // Perform register allocation. PM.add(createRegisterAllocator()); @@ -195,46 +207,33 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (OptLevel != CodeGenOpt::None) PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive)); - if (PrintMachineCode) // Print the register-allocated code - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Print the register-allocated code // Run post-ra passes. - if (addPostRegAlloc(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + if (addPostRegAlloc(PM, OptLevel)) + printAndVerify(PM); PM.add(createLowerSubregsPass()); - - if (PrintMachineCode) // Print the subreg lowered code - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); // Second pass scheduler. if (OptLevel != CodeGenOpt::None && !DisablePostRAScheduler) { PM.add(createPostRAScheduler()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); } // Branch folding must be run after regalloc and prolog/epilog insertion. - if (OptLevel != CodeGenOpt::None) + if (OptLevel != CodeGenOpt::None) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); + } PM.add(createGCMachineCodeAnalysisPass()); - - if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + printAndVerify(PM); if (PrintGCInfo) PM.add(createGCInfoPrinter(*cerr)); diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp new file mode 100644 index 0000000..22866c6 --- /dev/null +++ b/lib/CodeGen/MachineVerifier.cpp @@ -0,0 +1,677 @@ +//===-- MachineVerifier.cpp - Machine Code Verifier -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Pass to verify generated machine code. The following is checked: +// +// Operand counts: All explicit operands must be present. +// +// Register classes: All physical and virtual register operands must be +// compatible with the register class required by the instruction descriptor. +// +// Register live intervals: Registers must be defined only once, and must be +// defined before use. +// +// The machine code verifier is enabled from LLVMTargetMachine.cpp with the +// command-line option -verify-machineinstrs, or by defining the environment +// variable LLVM_VERIFY_MACHINEINSTRS to the name of a file that will receive +// the verifier errors. +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SetOperations.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/LiveVariables.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" +#include <fstream> + +using namespace llvm; + +namespace { + struct VISIBILITY_HIDDEN MachineVerifier : public MachineFunctionPass { + static char ID; // Pass ID, replacement for typeid + + MachineVerifier(bool allowDoubleDefs = false) : + MachineFunctionPass(&ID), + allowVirtDoubleDefs(allowDoubleDefs), + allowPhysDoubleDefs(allowDoubleDefs), + OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS")) + {} + + void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesAll(); + } + + bool runOnMachineFunction(MachineFunction &MF); + + const bool allowVirtDoubleDefs; + const bool allowPhysDoubleDefs; + + const char *const OutFileName; + std::ostream *OS; + const MachineFunction *MF; + const TargetMachine *TM; + const TargetRegisterInfo *TRI; + const MachineRegisterInfo *MRI; + + unsigned foundErrors; + + typedef SmallVector<unsigned, 16> RegVector; + typedef DenseSet<unsigned> RegSet; + typedef DenseMap<unsigned, const MachineInstr*> RegMap; + + BitVector regsReserved; + RegSet regsLive; + RegVector regsDefined, regsImpDefined, regsDead, regsKilled; + + // Add Reg and any sub-registers to RV + void addRegWithSubRegs(RegVector &RV, unsigned Reg) { + RV.push_back(Reg); + if (TargetRegisterInfo::isPhysicalRegister(Reg)) + for (const unsigned *R = TRI->getSubRegisters(Reg); *R; R++) + RV.push_back(*R); + } + + // Does RS contain any super-registers of Reg? + bool anySuperRegisters(const RegSet &RS, unsigned Reg) { + for (const unsigned *R = TRI->getSuperRegisters(Reg); *R; R++) + if (RS.count(*R)) + return true; + return false; + } + + struct BBInfo { + // Is this MBB reachable from the MF entry point? + bool reachable; + + // Vregs that must be live in because they are used without being + // defined. Map value is the user. + RegMap vregsLiveIn; + + // Vregs that must be dead in because they are defined without being + // killed first. Map value is the defining instruction. + RegMap vregsDeadIn; + + // Regs killed in MBB. They may be defined again, and will then be in both + // regsKilled and regsLiveOut. + RegSet regsKilled; + + // Regs defined in MBB and live out. Note that vregs passing through may + // be live out without being mentioned here. + RegSet regsLiveOut; + + // Vregs that pass through MBB untouched. This set is disjoint from + // regsKilled and regsLiveOut. + RegSet vregsPassed; + + BBInfo() : reachable(false) {} + + // Add register to vregsPassed if it belongs there. Return true if + // anything changed. + bool addPassed(unsigned Reg) { + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + return false; + if (regsKilled.count(Reg) || regsLiveOut.count(Reg)) + return false; + return vregsPassed.insert(Reg).second; + } + + // Same for a full set. + bool addPassed(const RegSet &RS) { + bool changed = false; + for (RegSet::const_iterator I = RS.begin(), E = RS.end(); I != E; ++I) + if (addPassed(*I)) + changed = true; + return changed; + } + + // Live-out registers are either in regsLiveOut or vregsPassed. + bool isLiveOut(unsigned Reg) const { + return regsLiveOut.count(Reg) || vregsPassed.count(Reg); + } + }; + + // Extra register info per MBB. + DenseMap<const MachineBasicBlock*, BBInfo> MBBInfoMap; + + bool isReserved(unsigned Reg) { + return Reg < regsReserved.size() && regsReserved[Reg]; + } + + void visitMachineFunctionBefore(); + void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB); + void visitMachineInstrBefore(const MachineInstr *MI); + void visitMachineOperand(const MachineOperand *MO, unsigned MONum); + void visitMachineInstrAfter(const MachineInstr *MI); + void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB); + void visitMachineFunctionAfter(); + + 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 markReachable(const MachineBasicBlock *MBB); + void calcMaxRegsPassed(); + void calcMinRegsPassed(); + void checkPHIOps(const MachineBasicBlock *MBB); + }; +} + +char MachineVerifier::ID = 0; +static RegisterPass<MachineVerifier> +MachineVer("verify-machineinstrs", "Verify generated machine code"); +static const PassInfo *const MachineVerifyID = &MachineVer; + +FunctionPass * +llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) +{ + return new MachineVerifier(allowPhysDoubleDefs); +} + +bool +MachineVerifier::runOnMachineFunction(MachineFunction &MF) +{ + std::ofstream OutFile; + if (OutFileName) { + OutFile.open(OutFileName, std::ios::out | std::ios::app); + OS = &OutFile; + } else { + OS = cerr.stream(); + } + + foundErrors = 0; + + this->MF = &MF; + TM = &MF.getTarget(); + TRI = TM->getRegisterInfo(); + MRI = &MF.getRegInfo(); + + visitMachineFunctionBefore(); + for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end(); + MFI!=MFE; ++MFI) { + visitMachineBasicBlockBefore(MFI); + for (MachineBasicBlock::const_iterator MBBI = MFI->begin(), + MBBE = MFI->end(); MBBI != MBBE; ++MBBI) { + visitMachineInstrBefore(MBBI); + for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) + visitMachineOperand(&MBBI->getOperand(I), I); + visitMachineInstrAfter(MBBI); + } + visitMachineBasicBlockAfter(MFI); + } + visitMachineFunctionAfter(); + + if (OutFileName) + OutFile.close(); + + if (foundErrors) { + cerr << "\nStopping with " << foundErrors << " machine code errors.\n"; + exit(1); + } + + return false; // no changes +} + +void +MachineVerifier::report(const char *msg, const MachineFunction *MF) +{ + assert(MF); + *OS << "\n"; + if (!foundErrors++) + MF->print(OS); + *OS << "*** Bad machine code: " << msg << " ***\n" + << "- function: " << MF->getFunction()->getName() << "\n"; +} + +void +MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) +{ + assert(MBB); + report(msg, MBB->getParent()); + *OS << "- basic block: " << MBB->getBasicBlock()->getName() + << " " << (void*)MBB + << " (#" << MBB->getNumber() << ")\n"; +} + +void +MachineVerifier::report(const char *msg, const MachineInstr *MI) +{ + assert(MI); + report(msg, MI->getParent()); + *OS << "- instruction: "; + MI->print(OS, TM); +} + +void +MachineVerifier::report(const char *msg, + const MachineOperand *MO, unsigned MONum) +{ + assert(MO); + report(msg, MO->getParent()); + *OS << "- operand " << MONum << ": "; + MO->print(*OS, TM); + *OS << "\n"; +} + +void +MachineVerifier::markReachable(const MachineBasicBlock *MBB) +{ + BBInfo &MInfo = MBBInfoMap[MBB]; + if (!MInfo.reachable) { + MInfo.reachable = true; + for (MachineBasicBlock::const_succ_iterator SuI = MBB->succ_begin(), + SuE = MBB->succ_end(); SuI != SuE; ++SuI) + markReachable(*SuI); + } +} + +void +MachineVerifier::visitMachineFunctionBefore() +{ + regsReserved = TRI->getReservedRegs(*MF); + markReachable(&MF->front()); +} + +void +MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) +{ + regsLive.clear(); + for (MachineBasicBlock::const_livein_iterator I = MBB->livein_begin(), + E = MBB->livein_end(); I != E; ++I) { + if (!TargetRegisterInfo::isPhysicalRegister(*I)) { + report("MBB live-in list contains non-physical register", MBB); + continue; + } + regsLive.insert(*I); + for (const unsigned *R = TRI->getSubRegisters(*I); *R; R++) + regsLive.insert(*R); + } + regsKilled.clear(); + regsDefined.clear(); + regsImpDefined.clear(); +} + +void +MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) +{ + const TargetInstrDesc &TI = MI->getDesc(); + if (MI->getNumExplicitOperands() < TI.getNumOperands()) { + report("Too few operands", MI); + *OS << TI.getNumOperands() << " operands expected, but " + << MI->getNumExplicitOperands() << " given.\n"; + } + if (!TI.isVariadic()) { + if (MI->getNumExplicitOperands() > TI.getNumOperands()) { + report("Too many operands", MI); + *OS << TI.getNumOperands() << " operands expected, but " + << MI->getNumExplicitOperands() << " given.\n"; + } + } +} + +void +MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) +{ + const MachineInstr *MI = MO->getParent(); + switch (MO->getType()) { + case MachineOperand::MO_Register: { + const unsigned Reg = MO->getReg(); + if (!Reg) + return; + + // Check Live Variables. + if (MO->isUse()) { + if (MO->isKill()) { + addRegWithSubRegs(regsKilled, Reg); + } else { + // TwoAddress instr modyfying a reg is treated as kill+def. + unsigned defIdx; + if (MI->isRegTiedToDefOperand(MONum, &defIdx) && + MI->getOperand(defIdx).getReg() == Reg) + addRegWithSubRegs(regsKilled, Reg); + } + // Explicit use of a dead register. + if (!MO->isImplicit() && !regsLive.count(Reg)) + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + // Reserved registers may be used even when 'dead'. + if (!isReserved(Reg)) + report("Using an undefined physical register", MO, MONum); + } else { + BBInfo &MInfo = MBBInfoMap[MI->getParent()]; + // We don't know which virtual registers are live in, so only complain + // if vreg was killed in this MBB. Otherwise keep track of vregs that + // must be live in. PHI instructions are handled separately. + if (MInfo.regsKilled.count(Reg)) + report("Using a killed virtual register", MO, MONum); + else if (MI->getOpcode() != TargetInstrInfo::PHI) + MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI)); + } + } else { + // Register defined. + // TODO: verify that earlyclobber ops are not used. + if (MO->isImplicit()) + addRegWithSubRegs(regsImpDefined, Reg); + else + addRegWithSubRegs(regsDefined, Reg); + + if (MO->isDead()) + addRegWithSubRegs(regsDead, Reg); + } + + // Check register classes. + const TargetInstrDesc &TI = MI->getDesc(); + if (MONum < TI.getNumOperands() && !MO->isImplicit()) { + const TargetOperandInfo &TOI = TI.OpInfo[MONum]; + unsigned SubIdx = MO->getSubReg(); + + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + unsigned sr = Reg; + if (SubIdx) { + unsigned s = TRI->getSubReg(Reg, SubIdx); + if (!s) { + report("Invalid subregister index for physical register", + MO, MONum); + return; + } + sr = s; + } + if (TOI.RegClass) { + const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass); + if (!DRC->contains(sr)) { + report("Illegal physical register for instruction", MO, MONum); + *OS << TRI->getName(sr) << " is not a " + << DRC->getName() << " register.\n"; + } + } + } else { + // Virtual register. + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + if (SubIdx) { + if (RC->subregclasses_begin()+SubIdx >= RC->subregclasses_end()) { + report("Invalid subregister index for virtual register", MO, MONum); + return; + } + RC = *(RC->subregclasses_begin()+SubIdx); + } + if (TOI.RegClass) { + const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass); + if (RC != DRC && !RC->hasSuperClass(DRC)) { + report("Illegal virtual register for instruction", MO, MONum); + *OS << "Expected a " << DRC->getName() << " register, but got a " + << RC->getName() << " register\n"; + } + } + } + } + break; + } + // Can PHI instrs refer to MBBs not in the CFG? X86 and ARM do. + // case MachineOperand::MO_MachineBasicBlock: + // if (MI->getOpcode() == TargetInstrInfo::PHI) { + // if (!MO->getMBB()->isSuccessor(MI->getParent())) + // report("PHI operand is not in the CFG", MO, MONum); + // } + // break; + default: + break; + } +} + +void +MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) +{ + BBInfo &MInfo = MBBInfoMap[MI->getParent()]; + set_union(MInfo.regsKilled, regsKilled); + set_subtract(regsLive, regsKilled); + regsKilled.clear(); + + for (RegVector::const_iterator I = regsDefined.begin(), + E = regsDefined.end(); I != E; ++I) { + if (regsLive.count(*I)) { + if (TargetRegisterInfo::isPhysicalRegister(*I)) { + // We allow double defines to physical registers with live + // super-registers. + if (!allowPhysDoubleDefs && !anySuperRegisters(regsLive, *I)) { + report("Redefining a live physical register", MI); + *OS << "Register " << TRI->getName(*I) + << " was defined but already live.\n"; + } + } else { + if (!allowVirtDoubleDefs) { + report("Redefining a live virtual register", MI); + *OS << "Virtual register %reg" << *I + << " was defined but already live.\n"; + } + } + } else if (TargetRegisterInfo::isVirtualRegister(*I) && + !MInfo.regsKilled.count(*I)) { + // Virtual register defined without being killed first must be dead on + // entry. + MInfo.vregsDeadIn.insert(std::make_pair(*I, MI)); + } + } + + set_union(regsLive, regsDefined); regsDefined.clear(); + set_union(regsLive, regsImpDefined); regsImpDefined.clear(); + set_subtract(regsLive, regsDead); regsDead.clear(); +} + +void +MachineVerifier::visitMachineBasicBlockAfter(const MachineBasicBlock *MBB) +{ + MBBInfoMap[MBB].regsLiveOut = regsLive; + regsLive.clear(); +} + +// Calculate the largest possible vregsPassed sets. These are the registers that +// can pass through an MBB live, but may not be live every time. It is assumed +// that all vregsPassed sets are empty before the call. +void +MachineVerifier::calcMaxRegsPassed() +{ + // First push live-out regs to successors' vregsPassed. Remember the MBBs that + // have any vregsPassed. + DenseSet<const MachineBasicBlock*> todo; + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) { + const MachineBasicBlock &MBB(*MFI); + BBInfo &MInfo = MBBInfoMap[&MBB]; + if (!MInfo.reachable) + continue; + for (MachineBasicBlock::const_succ_iterator SuI = MBB.succ_begin(), + SuE = MBB.succ_end(); SuI != SuE; ++SuI) { + BBInfo &SInfo = MBBInfoMap[*SuI]; + if (SInfo.addPassed(MInfo.regsLiveOut)) + todo.insert(*SuI); + } + } + + // Iteratively push vregsPassed to successors. This will converge to the same + // final state regardless of DenseSet iteration order. + while (!todo.empty()) { + const MachineBasicBlock *MBB = *todo.begin(); + todo.erase(MBB); + BBInfo &MInfo = MBBInfoMap[MBB]; + for (MachineBasicBlock::const_succ_iterator SuI = MBB->succ_begin(), + SuE = MBB->succ_end(); SuI != SuE; ++SuI) { + if (*SuI == MBB) + continue; + BBInfo &SInfo = MBBInfoMap[*SuI]; + if (SInfo.addPassed(MInfo.vregsPassed)) + todo.insert(*SuI); + } + } +} + +// Calculate the minimum vregsPassed set. These are the registers that always +// pass live through an MBB. The calculation assumes that calcMaxRegsPassed has +// been called earlier. +void +MachineVerifier::calcMinRegsPassed() +{ + DenseSet<const MachineBasicBlock*> todo; + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) + todo.insert(MFI); + + while (!todo.empty()) { + const MachineBasicBlock *MBB = *todo.begin(); + todo.erase(MBB); + BBInfo &MInfo = MBBInfoMap[MBB]; + + // Remove entries from vRegsPassed that are not live out from all + // reachable predecessors. + RegSet dead; + for (RegSet::iterator I = MInfo.vregsPassed.begin(), + E = MInfo.vregsPassed.end(); I != E; ++I) { + for (MachineBasicBlock::const_pred_iterator PrI = MBB->pred_begin(), + PrE = MBB->pred_end(); PrI != PrE; ++PrI) { + BBInfo &PrInfo = MBBInfoMap[*PrI]; + if (PrInfo.reachable && !PrInfo.isLiveOut(*I)) { + dead.insert(*I); + break; + } + } + } + // If any regs removed, we need to recheck successors. + if (!dead.empty()) { + set_subtract(MInfo.vregsPassed, dead); + todo.insert(MBB->succ_begin(), MBB->succ_end()); + } + } +} + +// Check PHI instructions at the beginning of MBB. It is assumed that +// calcMinRegsPassed has been run so BBInfo::isLiveOut is valid. +void +MachineVerifier::checkPHIOps(const MachineBasicBlock *MBB) +{ + for (MachineBasicBlock::const_iterator BBI = MBB->begin(), BBE = MBB->end(); + BBI != BBE && BBI->getOpcode() == TargetInstrInfo::PHI; ++BBI) { + DenseSet<const MachineBasicBlock*> seen; + + 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)) + 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); + } + + // 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); + *OS << "MBB #" << (*PrI)->getNumber() + << " is a predecessor according to the CFG.\n"; + } + } + } +} + +void +MachineVerifier::visitMachineFunctionAfter() +{ + calcMaxRegsPassed(); + + // With the maximal set of vregsPassed we can verify dead-in registers. + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) { + BBInfo &MInfo = MBBInfoMap[MFI]; + + // Skip unreachable MBBs. + if (!MInfo.reachable) + continue; + + for (MachineBasicBlock::const_pred_iterator PrI = MFI->pred_begin(), + PrE = MFI->pred_end(); PrI != PrE; ++PrI) { + BBInfo &PrInfo = MBBInfoMap[*PrI]; + if (!PrInfo.reachable) + continue; + + // Verify physical live-ins. EH landing pads have magic live-ins so we + // ignore them. + if (!MFI->isLandingPad()) { + for (MachineBasicBlock::const_livein_iterator I = MFI->livein_begin(), + E = MFI->livein_end(); I != E; ++I) { + if (TargetRegisterInfo::isPhysicalRegister(*I) && + !PrInfo.isLiveOut(*I)) { + report("Live-in physical register is not live-out from predecessor", + MFI); + *OS << "Register " << TRI->getName(*I) + << " is not live-out from MBB #" << (*PrI)->getNumber() + << ".\n"; + } + } + } + + + // Verify dead-in virtual registers. + if (!allowVirtDoubleDefs) { + for (RegMap::iterator I = MInfo.vregsDeadIn.begin(), + E = MInfo.vregsDeadIn.end(); I != E; ++I) { + // DeadIn register must be in neither regsLiveOut or vregsPassed of + // any predecessor. + if (PrInfo.isLiveOut(I->first)) { + report("Live-in virtual register redefined", I->second); + *OS << "Register %reg" << I->first + << " was live-out from predecessor MBB #" + << (*PrI)->getNumber() << ".\n"; + } + } + } + } + } + + calcMinRegsPassed(); + + // With the minimal set of vregsPassed we can verify live-in virtual + // registers, including PHI instructions. + for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end(); + MFI != MFE; ++MFI) { + BBInfo &MInfo = MBBInfoMap[MFI]; + + // Skip unreachable MBBs. + if (!MInfo.reachable) + continue; + + checkPHIOps(MFI); + + for (MachineBasicBlock::const_pred_iterator PrI = MFI->pred_begin(), + PrE = MFI->pred_end(); PrI != PrE; ++PrI) { + BBInfo &PrInfo = MBBInfoMap[*PrI]; + if (!PrInfo.reachable) + continue; + + for (RegMap::iterator I = MInfo.vregsLiveIn.begin(), + E = MInfo.vregsLiveIn.end(); I != E; ++I) { + if (!PrInfo.isLiveOut(I->first)) { + report("Used virtual register is not live-in", I->second); + *OS << "Register %reg" << I->first + << " is not live-out from predecessor MBB #" + << (*PrI)->getNumber() + << ".\n"; + } + } + } + } +} |