// the verifier errors.
//===----------------------------------------------------------------------===//
+#include "llvm/Instructions.h"
#include "llvm/Function.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
raw_ostream *OS;
const MachineFunction *MF;
const TargetMachine *TM;
+ const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const MachineRegisterInfo *MRI;
typedef DenseSet<unsigned> RegSet;
typedef DenseMap<unsigned, const MachineInstr*> RegMap;
+ const MachineInstr *FirstTerminator;
+
BitVector regsReserved;
RegSet regsLive;
RegVector regsDefined, regsDead, regsKilled;
this->MF = &MF;
TM = &MF.getTarget();
+ TII = TM->getInstrInfo();
TRI = TM->getRegisterInfo();
MRI = &MF.getRegInfo();
void
MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
- const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+ FirstTerminator = 0;
// Count the number of landing pad successors.
SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs;
if ((*I)->isLandingPad())
LandingPadSuccs.insert(*I);
}
- if (LandingPadSuccs.size() > 1)
+
+ const MCAsmInfo *AsmInfo = TM->getMCAsmInfo();
+ const BasicBlock *BB = MBB->getBasicBlock();
+ if (LandingPadSuccs.size() > 1 &&
+ !(AsmInfo &&
+ AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
+ BB && isa<SwitchInst>(BB->getTerminator())))
report("MBB has more than one landing pad successor", MBB);
// Call AnalyzeBranch. If it succeeds, there several more conditions to check.
SmallVector<MachineOperand, 4> Cond;
if (!TII->AnalyzeBranch(*const_cast<MachineBasicBlock *>(MBB),
TBB, FBB, Cond)) {
- // If the block branches directly to a landing pad successor, pretend that
- // the landing pad is a normal block.
- LandingPadSuccs.erase(TBB);
- LandingPadSuccs.erase(FBB);
-
// Ok, AnalyzeBranch thinks it knows what's going on with this block. Let's
// check whether its answers match up with reality.
if (!TBB && !FBB) {
}
void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
- const TargetInstrDesc &TI = MI->getDesc();
- if (MI->getNumOperands() < TI.getNumOperands()) {
+ const MCInstrDesc &MCID = MI->getDesc();
+ if (MI->getNumOperands() < MCID.getNumOperands()) {
report("Too few operands", MI);
- *OS << TI.getNumOperands() << " operands expected, but "
+ *OS << MCID.getNumOperands() << " operands expected, but "
<< MI->getNumExplicitOperands() << " given.\n";
}
// Check the MachineMemOperands for basic consistency.
for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
E = MI->memoperands_end(); I != E; ++I) {
- if ((*I)->isLoad() && !TI.mayLoad())
+ if ((*I)->isLoad() && !MCID.mayLoad())
report("Missing mayLoad flag", MI);
- if ((*I)->isStore() && !TI.mayStore())
+ if ((*I)->isStore() && !MCID.mayStore())
report("Missing mayStore flag", MI);
}
}
}
+ // Ensure non-terminators don't follow terminators.
+ if (MCID.isTerminator()) {
+ if (!FirstTerminator)
+ FirstTerminator = MI;
+ } else if (FirstTerminator) {
+ report("Non-terminator instruction after the first terminator", MI);
+ *OS << "First terminator was:\t" << *FirstTerminator;
+ }
+
+ StringRef ErrorInfo;
+ if (!TII->verifyInstruction(MI, ErrorInfo))
+ report(ErrorInfo.data(), MI);
}
void
MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
- const TargetInstrDesc &TI = MI->getDesc();
- const TargetOperandInfo &TOI = TI.OpInfo[MONum];
+ const MCInstrDesc &MCID = MI->getDesc();
+ const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
- // The first TI.NumDefs operands must be explicit register defines
- if (MONum < TI.getNumDefs()) {
+ // The first MCID.NumDefs operands must be explicit register defines
+ if (MONum < MCID.getNumDefs()) {
if (!MO->isReg())
report("Explicit definition must be a register", MO, MONum);
else if (!MO->isDef())
report("Explicit definition marked as use", MO, MONum);
else if (MO->isImplicit())
report("Explicit definition marked as implicit", MO, MONum);
- } else if (MONum < TI.getNumOperands()) {
+ } else if (MONum < MCID.getNumOperands()) {
// Don't check if it's the last operand in a variadic instruction. See,
// e.g., LDM_RET in the arm back end.
- if (MO->isReg() && !(TI.isVariadic() && MONum == TI.getNumOperands()-1)) {
- if (MO->isDef() && !TOI.isOptionalDef())
+ if (MO->isReg() &&
+ !(MCID.isVariadic() && MONum == MCID.getNumOperands()-1)) {
+ if (MO->isDef() && !MCOI.isOptionalDef())
report("Explicit operand marked as def", MO, MONum);
if (MO->isImplicit())
report("Explicit operand marked as implicit", MO, MONum);
}
} else {
// ARM adds %reg0 operands to indicate predicates. We'll allow that.
- if (MO->isReg() && !MO->isImplicit() && !TI.isVariadic() && MO->getReg())
+ if (MO->isReg() && !MO->isImplicit() && !MCID.isVariadic() && MO->getReg())
report("Extra explicit operand on non-variadic instruction", MO, MONum);
}
else
addRegWithSubRegs(regsDefined, Reg);
+ // Verify SSA form.
+ if (MRI->isSSA() && TargetRegisterInfo::isVirtualRegister(Reg) &&
+ llvm::next(MRI->def_begin(Reg)) != MRI->def_end())
+ report("Multiple virtual register defs in SSA form", MO, MONum);
+
// Check LiveInts for a live range, but only for virtual registers.
if (LiveInts && TargetRegisterInfo::isVirtualRegister(Reg) &&
!LiveInts->isNotInMIMap(MI)) {
}
// Check register classes.
- if (MONum < TI.getNumOperands() && !MO->isImplicit()) {
+ if (MONum < MCID.getNumOperands() && !MO->isImplicit()) {
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;
+ report("Illegal subregister index for physical register", MO, MONum);
+ return;
}
- if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
- if (!DRC->contains(sr)) {
+ if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) {
+ if (!DRC->contains(Reg)) {
report("Illegal physical register for instruction", MO, MONum);
- *OS << TRI->getName(sr) << " is not a "
+ *OS << TRI->getName(Reg) << " is not a "
<< DRC->getName() << " register.\n";
}
}
// Virtual register.
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
if (SubIdx) {
- const TargetRegisterClass *SRC = RC->getSubRegisterRegClass(SubIdx);
+ const TargetRegisterClass *SRC =
+ TRI->getSubClassWithSubReg(RC, SubIdx);
if (!SRC) {
report("Invalid subregister index for virtual register", MO, MONum);
*OS << "Register class " << RC->getName()
<< " does not support subreg index " << SubIdx << "\n";
return;
}
- RC = SRC;
+ if (RC != SRC) {
+ report("Invalid register class for subregister index", MO, MONum);
+ *OS << "Register class " << RC->getName()
+ << " does not fully support subreg index " << SubIdx << "\n";
+ return;
+ }
}
- if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
- if (RC != DRC && !RC->hasSuperClass(DRC)) {
+ if (const TargetRegisterClass *DRC = TII->getRegClass(MCID,MONum,TRI)) {
+ if (SubIdx) {
+ const TargetRegisterClass *SuperRC =
+ TRI->getLargestLegalSuperClass(RC);
+ if (!SuperRC) {
+ report("No largest legal super class exists.", MO, MONum);
+ return;
+ }
+ DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx);
+ if (!DRC) {
+ report("No matching super-reg register class.", MO, MONum);
+ return;
+ }
+ }
+ if (!RC->hasSuperClassEq(DRC)) {
report("Illegal virtual register for instruction", MO, MONum);
*OS << "Expected a " << DRC->getName() << " register, but got a "
<< RC->getName() << " register\n";
LiveInts && !LiveInts->isNotInMIMap(MI)) {
LiveInterval &LI = LiveStks->getInterval(MO->getIndex());
SlotIndex Idx = LiveInts->getInstructionIndex(MI);
- if (TI.mayLoad() && !LI.liveAt(Idx.getUseIndex())) {
+ if (MCID.mayLoad() && !LI.liveAt(Idx.getUseIndex())) {
report("Instruction loads from dead spill slot", MO, MONum);
*OS << "Live stack: " << LI << '\n';
}
- if (TI.mayStore() && !LI.liveAt(Idx.getDefIndex())) {
+ if (MCID.mayStore() && !LI.liveAt(Idx.getDefIndex())) {
report("Instruction stores to dead spill slot", MO, MONum);
*OS << "Live stack: " << LI << '\n';
}
SlotIndex PEnd = LiveInts->getMBBEndIdx(*PI).getPrevSlot();
const VNInfo *PVNI = LI.getVNInfoAt(PEnd);
- if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI)) {
- if (PVNI && !PVNI->hasPHIKill()) {
- report("Value live out of predecessor doesn't have PHIKill", MF);
- *OS << "Valno #" << PVNI->id << " live out of BB#"
- << (*PI)->getNumber() << '@' << PEnd
- << " doesn't have PHIKill, but Valno #" << VNI->id
- << " is PHIDef and defined at the beginning of BB#"
- << MFI->getNumber() << '@' << LiveInts->getMBBStartIdx(MFI)
- << " in " << LI << '\n';
- }
+ if (VNI->isPHIDef() && VNI->def == LiveInts->getMBBStartIdx(MFI))
continue;
- }
if (!PVNI) {
report("Register not marked live out of predecessor", *PI);