Newer
Older
//===-- MachineVerifier.cpp - Machine Code Verifier -----------------------===//
//
// 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/CodeGen/Passes.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveStackAnalysis.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
Bill Wendling
committed
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
namespace {
struct MachineVerifier {
MachineVerifier(Pass *pass, const char *b) :
PASS(pass),
Banner(b),
OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS"))
bool runOnMachineFunction(MachineFunction &MF);
Pass *const PASS;
const char *Banner;
const char *const OutFileName;
raw_ostream *OS;
const MachineFunction *MF;
const TargetMachine *TM;
const TargetInstrInfo *TII;
const TargetRegisterInfo *TRI;
const MachineRegisterInfo *MRI;
unsigned foundErrors;
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;
const MachineInstr *FirstTerminator;
BitVector regsReserved;
RegSet regsLive;
RegVector regsDefined, regsDead, regsKilled;
RegMaskVector regMasks;
RegSet regsLiveInButUnused;
// Add Reg and any sub-registers to RV
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
RV.push_back(Reg);
if (TargetRegisterInfo::isPhysicalRegister(Reg))
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
RV.push_back(*SubRegs);
}
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;
// 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;
// Vregs that must pass through MBB because they are needed by a successor
// block. This set is disjoint from regsLiveOut.
RegSet vregsRequired;
// Set versions of block's predecessor and successor lists.
BlockSet Preds, Succs;
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;
}
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Add register to vregsRequired if it belongs there. Return true if
// anything changed.
bool addRequired(unsigned Reg) {
if (!TargetRegisterInfo::isVirtualRegister(Reg))
return false;
if (regsLiveOut.count(Reg))
return false;
return vregsRequired.insert(Reg).second;
}
// Same for a full set.
bool addRequired(const RegSet &RS) {
bool changed = false;
for (RegSet::const_iterator I = RS.begin(), E = RS.end(); I != E; ++I)
if (addRequired(*I))
changed = true;
return changed;
}
// Same for a full map.
bool addRequired(const RegMap &RM) {
bool changed = false;
for (RegMap::const_iterator I = RM.begin(), E = RM.end(); I != E; ++I)
if (addRequired(I->first))
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.test(Reg);
bool isAllocatable(unsigned Reg) {
return Reg < TRI->getNumRegs() && MRI->isAllocatable(Reg);
// Analysis information if available
LiveVariables *LiveVars;
Jakob Stoklund Olesen
committed
LiveIntervals *LiveInts;
Jakob Stoklund Olesen
committed
SlotIndexes *Indexes;
void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineBundleBefore(const MachineInstr *MI);
void visitMachineInstrBefore(const MachineInstr *MI);
void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
void visitMachineInstrAfter(const MachineInstr *MI);
void visitMachineBundleAfter(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 report(const char *msg, const MachineFunction *MF,
const LiveInterval &LI);
void report(const char *msg, const MachineBasicBlock *MBB,
const LiveInterval &LI);
void verifyInlineAsm(const MachineInstr *MI);
void checkLiveness(const MachineOperand *MO, unsigned MONum);
void markReachable(const MachineBasicBlock *MBB);
void calcRegsPassed();
void checkPHIOps(const MachineBasicBlock *MBB);
void calcRegsRequired();
void verifyLiveVariables();
void verifyLiveIntervals();
void verifyLiveInterval(const LiveInterval&);
void verifyLiveIntervalValue(const LiveInterval&, VNInfo*);
void verifyLiveIntervalSegment(const LiveInterval&,
LiveInterval::const_iterator);
};
struct MachineVerifierPass : public MachineFunctionPass {
static char ID; // Pass ID, replacement for typeid
const char *const Banner;
MachineVerifierPass(const char *b = 0)
: MachineFunctionPass(ID), Banner(b) {
Owen Anderson
committed
initializeMachineVerifierPassPass(*PassRegistry::getPassRegistry());
}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF) {
MF.verify(this, Banner);
return false;
}
char MachineVerifierPass::ID = 0;
INITIALIZE_PASS(MachineVerifierPass, "machineverifier",
"Verify generated machine code", false, false)
FunctionPass *llvm::createMachineVerifierPass(const char *Banner) {
return new MachineVerifierPass(Banner);
void MachineFunction::verify(Pass *p, const char *Banner) const {
MachineVerifier(p, Banner)
.runOnMachineFunction(const_cast<MachineFunction&>(*this));
Jakob Stoklund Olesen
committed
}
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
raw_ostream *OutFile = 0;
std::string ErrorInfo;
OutFile = new raw_fd_ostream(OutFileName, ErrorInfo,
raw_fd_ostream::F_Append);
if (!ErrorInfo.empty()) {
errs() << "Error opening '" << OutFileName << "': " << ErrorInfo << '\n';
exit(1);
}
OS = OutFile;
OS = &errs();
}
foundErrors = 0;
this->MF = &MF;
TM = &MF.getTarget();
TII = TM->getInstrInfo();
TRI = TM->getRegisterInfo();
MRI = &MF.getRegInfo();
LiveVars = NULL;
LiveInts = NULL;
Jakob Stoklund Olesen
committed
Indexes = NULL;
if (PASS) {
LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>();
// We don't want to verify LiveVariables if LiveIntervals is available.
if (!LiveInts)
LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
LiveStks = PASS->getAnalysisIfAvailable<LiveStacks>();
Jakob Stoklund Olesen
committed
Indexes = PASS->getAnalysisIfAvailable<SlotIndexes>();
}
visitMachineFunctionBefore();
for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
MFI!=MFE; ++MFI) {
visitMachineBasicBlockBefore(MFI);
// Keep track of the current bundle header.
const MachineInstr *CurBundle = 0;
// Do we expect the next instruction to be part of the same bundle?
bool InBundle = false;
Evan Cheng
committed
for (MachineBasicBlock::const_instr_iterator MBBI = MFI->instr_begin(),
MBBE = MFI->instr_end(); MBBI != MBBE; ++MBBI) {
if (MBBI->getParent() != MFI) {
report("Bad instruction parent pointer", MFI);
*OS << "Instruction: " << *MBBI;
continue;
}
// Check for consistent bundle flags.
if (InBundle && !MBBI->isBundledWithPred())
report("Missing BundledPred flag, "
"BundledSucc was set on predecessor", MBBI);
if (!InBundle && MBBI->isBundledWithPred())
report("BundledPred flag is set, "
"but BundledSucc not set on predecessor", MBBI);
// Is this a bundle header?
if (!MBBI->isInsideBundle()) {
if (CurBundle)
visitMachineBundleAfter(CurBundle);
CurBundle = MBBI;
visitMachineBundleBefore(CurBundle);
} else if (!CurBundle)
report("No bundle header", MBBI);
visitMachineInstrBefore(MBBI);
for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I)
visitMachineOperand(&MBBI->getOperand(I), I);
visitMachineInstrAfter(MBBI);
// Was this the last bundled instruction?
InBundle = MBBI->isBundledWithSucc();
if (CurBundle)
visitMachineBundleAfter(CurBundle);
if (InBundle)
report("BundledSucc flag set on last instruction in block", &MFI->back());
visitMachineBasicBlockAfter(MFI);
}
visitMachineFunctionAfter();
if (OutFile)
delete OutFile;
else if (foundErrors)
report_fatal_error("Found "+Twine(foundErrors)+" machine code errors.");
Jakob Stoklund Olesen
committed
// Clean up.
regsLive.clear();
regsDefined.clear();
regsDead.clear();
regsKilled.clear();
Jakob Stoklund Olesen
committed
regsLiveInButUnused.clear();
MBBInfoMap.clear();
return false; // no changes
}
void MachineVerifier::report(const char *msg, const MachineFunction *MF) {
if (!foundErrors++) {
if (Banner)
*OS << "# " << Banner << '\n';
Jakob Stoklund Olesen
committed
MF->print(*OS, Indexes);
*OS << "*** Bad machine code: " << msg << " ***\n"
Craig Topper
committed
<< "- function: " << MF->getName() << "\n";
void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) {
assert(MBB);
report(msg, MBB->getParent());
*OS << "- basic block: BB#" << MBB->getNumber()
<< ' ' << MBB->getName()
<< " (" << (const void*)MBB << ')';
Jakob Stoklund Olesen
committed
if (Indexes)
*OS << " [" << Indexes->getMBBStartIdx(MBB)
<< ';' << Indexes->getMBBEndIdx(MBB) << ')';
*OS << '\n';
void MachineVerifier::report(const char *msg, const MachineInstr *MI) {
assert(MI);
report(msg, MI->getParent());
*OS << "- instruction: ";
Jakob Stoklund Olesen
committed
if (Indexes && Indexes->hasIndex(MI))
*OS << Indexes->getInstructionIndex(MI) << '\t';
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::report(const char *msg, const MachineFunction *MF,
const LiveInterval &LI) {
report(msg, MF);
*OS << "- interval: ";
if (TargetRegisterInfo::isVirtualRegister(LI.reg))
*OS << PrintReg(LI.reg, TRI);
else
*OS << PrintRegUnit(LI.reg, TRI);
*OS << ' ' << LI << '\n';
}
void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB,
const LiveInterval &LI) {
report(msg, MBB);
*OS << "- interval: ";
if (TargetRegisterInfo::isVirtualRegister(LI.reg))
*OS << PrintReg(LI.reg, TRI);
else
*OS << PrintRegUnit(LI.reg, TRI);
*OS << ' ' << LI << '\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 = MRI->getReservedRegs();
// A sub-register of a reserved register is also reserved
for (int Reg = regsReserved.find_first(); Reg>=0;
Reg = regsReserved.find_next(Reg)) {
for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs) {
// FIXME: This should probably be:
// assert(regsReserved.test(*SubRegs) && "Non-reserved sub-register");
regsReserved.set(*SubRegs);
markReachable(&MF->front());
// Build a set of the basic blocks in the function.
FunctionBlocks.clear();
for (MachineFunction::const_iterator
I = MF->begin(), E = MF->end(); I != E; ++I) {
FunctionBlocks.insert(I);
BBInfo &MInfo = MBBInfoMap[I];
MInfo.Preds.insert(I->pred_begin(), I->pred_end());
if (MInfo.Preds.size() != I->pred_size())
report("MBB has duplicate entries in its predecessor list.", I);
MInfo.Succs.insert(I->succ_begin(), I->succ_end());
if (MInfo.Succs.size() != I->succ_size())
report("MBB has duplicate entries in its successor list.", I);
}
// Check that the register use lists are sane.
MRI->verifyUseLists();
// Does iterator point to a and b as the first two elements?
static bool matchPair(MachineBasicBlock::const_succ_iterator i,
const MachineBasicBlock *a, const MachineBasicBlock *b) {
if (*i == a)
return *++i == b;
if (*i == b)
return *++i == a;
return false;
}
void
MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
FirstTerminator = 0;
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() &&
MBB != MBB->getParent()->begin()) {
report("MBB has allocable live-in, but isn't entry or landing-pad.", MBB);
}
}
}
Jakob Stoklund Olesen
committed
// Count the number of landing pad successors.
Cameron Zwarich
committed
SmallPtrSet<MachineBasicBlock*, 4> LandingPadSuccs;
Jakob Stoklund Olesen
committed
for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
Cameron Zwarich
committed
E = MBB->succ_end(); I != E; ++I) {
if ((*I)->isLandingPad())
LandingPadSuccs.insert(*I);
if (!FunctionBlocks.count(*I))
report("MBB has successor that isn't part of the function.", MBB);
if (!MBBInfoMap[*I].Preds.count(MBB)) {
report("Inconsistent CFG", MBB);
*OS << "MBB is not in the predecessor list of the successor BB#"
<< (*I)->getNumber() << ".\n";
}
}
// Check the predecessor list.
for (MachineBasicBlock::const_pred_iterator I = MBB->pred_begin(),
E = MBB->pred_end(); I != E; ++I) {
if (!FunctionBlocks.count(*I))
report("MBB has predecessor that isn't part of the function.", MBB);
if (!MBBInfoMap[*I].Succs.count(MBB)) {
report("Inconsistent CFG", MBB);
*OS << "MBB is not in the successor list of the predecessor BB#"
<< (*I)->getNumber() << ".\n";
}
Cameron Zwarich
committed
}
Bill Wendling
committed
const MCAsmInfo *AsmInfo = TM->getMCAsmInfo();
const BasicBlock *BB = MBB->getBasicBlock();
if (LandingPadSuccs.size() > 1 &&
!(AsmInfo &&
AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
BB && isa<SwitchInst>(BB->getTerminator())))
Jakob Stoklund Olesen
committed
report("MBB has more than one landing pad successor", MBB);
// Call AnalyzeBranch. If it succeeds, there several more conditions to check.
MachineBasicBlock *TBB = 0, *FBB = 0;
SmallVector<MachineOperand, 4> Cond;
if (!TII->AnalyzeBranch(*const_cast<MachineBasicBlock *>(MBB),
TBB, FBB, Cond)) {
// 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) {
// Block falls through to its successor.
MachineFunction::const_iterator MBBI = MBB;
++MBBI;
if (MBBI == MF->end()) {
// It's possible that the block legitimately ends with a noreturn
// call or an unreachable, in which case it won't actually fall
// out the bottom of the function.
Cameron Zwarich
committed
} else if (MBB->succ_size() == LandingPadSuccs.size()) {
// It's possible that the block legitimately ends with a noreturn
// call or an unreachable, in which case it won't actuall fall
// out of the block.
Cameron Zwarich
committed
} else if (MBB->succ_size() != 1+LandingPadSuccs.size()) {
report("MBB exits via unconditional fall-through but doesn't have "
"exactly one CFG successor!", MBB);
Jakob Stoklund Olesen
committed
} else if (!MBB->isSuccessor(MBBI)) {
report("MBB exits via unconditional fall-through but its successor "
"differs from its CFG successor!", MBB);
}
Akira Hatanaka
committed
if (!MBB->empty() && getBundleStart(&MBB->back())->isBarrier() &&
!TII->isPredicated(getBundleStart(&MBB->back()))) {
report("MBB exits via unconditional fall-through but ends with a "
"barrier instruction!", MBB);
}
if (!Cond.empty()) {
report("MBB exits via unconditional fall-through but has a condition!",
MBB);
}
} else if (TBB && !FBB && Cond.empty()) {
// Block unconditionally branches somewhere.
Cameron Zwarich
committed
if (MBB->succ_size() != 1+LandingPadSuccs.size()) {
report("MBB exits via unconditional branch but doesn't have "
"exactly one CFG successor!", MBB);
Jakob Stoklund Olesen
committed
} else if (!MBB->isSuccessor(TBB)) {
report("MBB exits via unconditional branch but the CFG "
"successor doesn't match the actual successor!", MBB);
}
if (MBB->empty()) {
report("MBB exits via unconditional branch but doesn't contain "
"any instructions!", MBB);
Akira Hatanaka
committed
} else if (!getBundleStart(&MBB->back())->isBarrier()) {
report("MBB exits via unconditional branch but doesn't end with a "
"barrier instruction!", MBB);
Akira Hatanaka
committed
} else if (!getBundleStart(&MBB->back())->isTerminator()) {
report("MBB exits via unconditional branch but the branch isn't a "
"terminator instruction!", MBB);
}
} else if (TBB && !FBB && !Cond.empty()) {
// Block conditionally branches somewhere, otherwise falls through.
MachineFunction::const_iterator MBBI = MBB;
++MBBI;
if (MBBI == MF->end()) {
report("MBB conditionally falls through out of function!", MBB);
} else if (MBB->succ_size() == 1) {
// A conditional branch with only one successor is weird, but allowed.
if (&*MBBI != TBB)
report("MBB exits via conditional branch/fall-through but only has "
"one CFG successor!", MBB);
else if (TBB != *MBB->succ_begin())
report("MBB exits via conditional branch/fall-through but the CFG "
"successor don't match the actual successor!", 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)) {
report("MBB exits via conditional branch/fall-through but the CFG "
"successors don't match the actual successors!", MBB);
}
if (MBB->empty()) {
report("MBB exits via conditional branch/fall-through but doesn't "
"contain any instructions!", MBB);
Akira Hatanaka
committed
} else if (getBundleStart(&MBB->back())->isBarrier()) {
report("MBB exits via conditional branch/fall-through but ends with a "
"barrier instruction!", MBB);
Akira Hatanaka
committed
} else if (!getBundleStart(&MBB->back())->isTerminator()) {
report("MBB exits via conditional branch/fall-through but the branch "
"isn't a terminator instruction!", MBB);
}
} else if (TBB && FBB) {
// Block conditionally branches somewhere, otherwise branches
// somewhere else.
if (MBB->succ_size() == 1) {
// A conditional branch with only one successor is weird, but allowed.
if (FBB != TBB)
report("MBB exits via conditional branch/branch through but only has "
"one CFG successor!", MBB);
else if (TBB != *MBB->succ_begin())
report("MBB exits via conditional branch/branch through but the CFG "
"successor don't match the actual successor!", MBB);
} else if (MBB->succ_size() != 2) {
report("MBB exits via conditional branch/branch but doesn't have "
"exactly two CFG successors!", MBB);
} else if (!matchPair(MBB->succ_begin(), TBB, FBB)) {
report("MBB exits via conditional branch/branch but the CFG "
"successors don't match the actual successors!", MBB);
}
if (MBB->empty()) {
report("MBB exits via conditional branch/branch but doesn't "
"contain any instructions!", MBB);
Akira Hatanaka
committed
} else if (!getBundleStart(&MBB->back())->isBarrier()) {
report("MBB exits via conditional branch/branch but doesn't end with a "
"barrier instruction!", MBB);
Akira Hatanaka
committed
} else if (!getBundleStart(&MBB->back())->isTerminator()) {
report("MBB exits via conditional branch/branch but the branch "
"isn't a terminator instruction!", MBB);
}
if (Cond.empty()) {
report("MBB exits via conditinal branch/branch but there's no "
"condition!", MBB);
}
} else {
report("AnalyzeBranch returned invalid data!", MBB);
}
}
for (MachineBasicBlock::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;
}
for (MCSubRegIterator SubRegs(*I, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
regsLiveInButUnused = regsLive;
const MachineFrameInfo *MFI = MF->getFrameInfo();
assert(MFI && "Function has no frame info");
BitVector PR = MFI->getPristineRegs(MBB);
for (int I = PR.find_first(); I>0; I = PR.find_next(I)) {
for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
regsLive.insert(*SubRegs);
regsKilled.clear();
regsDefined.clear();
if (Indexes)
lastIndex = Indexes->getMBBStartIdx(MBB);
// This function gets called for all bundle headers, including normal
// stand-alone unbundled instructions.
void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
if (Indexes && Indexes->hasIndex(MI)) {
SlotIndex idx = Indexes->getInstructionIndex(MI);
if (!(idx > lastIndex)) {
report("Instruction index out of order", MI);
*OS << "Last instruction was at " << lastIndex << '\n';
}
lastIndex = idx;
}
// Ensure non-terminators don't follow terminators.
// Ignore predicated terminators formed by if conversion.
// FIXME: If conversion shouldn't need to violate this rule.
if (MI->isTerminator() && !TII->isPredicated(MI)) {
if (!FirstTerminator)
FirstTerminator = MI;
} else if (FirstTerminator) {
report("Non-terminator instruction after the first terminator", MI);
*OS << "First terminator was:\t" << *FirstTerminator;
}
}
// The operands on an INLINEASM instruction must follow a template.
// Verify that the flag operands make sense.
void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
// The first two operands on INLINEASM are the asm string and global flags.
if (MI->getNumOperands() < 2) {
report("Too few operands on inline asm", MI);
return;
}
if (!MI->getOperand(0).isSymbol())
report("Asm string must be an external symbol", MI);
if (!MI->getOperand(1).isImm())
report("Asm flags must be an immediate", MI);
// Allowed flags are Extra_HasSideEffects = 1, Extra_IsAlignStack = 2,
// Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16.
if (!isUInt<5>(MI->getOperand(1).getImm()))
report("Unknown asm flags", &MI->getOperand(1), 1);
assert(InlineAsm::MIOp_FirstOperand == 2 && "Asm format changed");
unsigned OpNo = InlineAsm::MIOp_FirstOperand;
unsigned NumOps;
for (unsigned e = MI->getNumOperands(); OpNo < e; OpNo += NumOps) {
const MachineOperand &MO = MI->getOperand(OpNo);
// There may be implicit ops after the fixed operands.
if (!MO.isImm())
break;
NumOps = 1 + InlineAsm::getNumOperandRegisters(MO.getImm());
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
if (OpNo > MI->getNumOperands())
report("Missing operands in last group", MI);
// An optional MDNode follows the groups.
if (OpNo < MI->getNumOperands() && MI->getOperand(OpNo).isMetadata())
++OpNo;
// All trailing operands must be implicit registers.
for (unsigned e = MI->getNumOperands(); OpNo < e; ++OpNo) {
const MachineOperand &MO = MI->getOperand(OpNo);
if (!MO.isReg() || !MO.isImplicit())
report("Expected implicit register after groups", &MO, OpNo);
}
}
void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
const MCInstrDesc &MCID = MI->getDesc();
if (MI->getNumOperands() < MCID.getNumOperands()) {
report("Too few operands", MI);
*OS << MCID.getNumOperands() << " operands expected, but "
<< MI->getNumExplicitOperands() << " given.\n";
}
// Check the tied operands.
if (MI->isInlineAsm())
verifyInlineAsm(MI);
// Check the MachineMemOperands for basic consistency.
for (MachineInstr::mmo_iterator I = MI->memoperands_begin(),
E = MI->memoperands_end(); I != E; ++I) {
if ((*I)->isLoad() && !MI->mayLoad())
report("Missing mayLoad flag", MI);
if ((*I)->isStore() && !MI->mayStore())
report("Missing mayStore flag", MI);
}
// Debug values must not have a slot index.
// Other instructions must have one, unless they are inside a bundle.
if (LiveInts) {
bool mapped = !LiveInts->isNotInMIMap(MI);
if (MI->isDebugValue()) {
if (mapped)
report("Debug instruction has a slot index", MI);
} else if (MI->isInsideBundle()) {
if (mapped)
report("Instruction inside bundle has a slot index", MI);
} else {
if (!mapped)
report("Missing slot index", MI);
}
}
StringRef ErrorInfo;
if (!TII->verifyInstruction(MI, ErrorInfo))
report(ErrorInfo.data(), MI);
MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
Evan Cheng
committed
const MCInstrDesc &MCID = MI->getDesc();
Jakob Stoklund Olesen
committed
Evan Cheng
committed
// The first MCID.NumDefs operands must be explicit register defines
if (MONum < MCID.getNumDefs()) {
Richard Smith
committed
const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
Jakob Stoklund Olesen
committed
if (!MO->isReg())
report("Explicit definition must be a register", MO, MONum);
else if (!MO->isDef() && !MCOI.isOptionalDef())
Jakob Stoklund Olesen
committed
report("Explicit definition marked as use", MO, MONum);
else if (MO->isImplicit())
report("Explicit definition marked as implicit", MO, MONum);
Evan Cheng
committed
} else if (MONum < MCID.getNumOperands()) {
Richard Smith
committed
const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
// Don't check if it's the last operand in a variadic instruction. See,
// e.g., LDM_RET in the arm back end.
Evan Cheng
committed
if (MO->isReg() &&
!(MI->isVariadic() && MONum == MCID.getNumOperands()-1)) {
Evan Cheng
committed
if (MO->isDef() && !MCOI.isOptionalDef())
report("Explicit operand marked as def", MO, MONum);
if (MO->isImplicit())
report("Explicit operand marked as implicit", MO, MONum);
}
int TiedTo = MCID.getOperandConstraint(MONum, MCOI::TIED_TO);
if (TiedTo != -1) {
if (!MO->isReg())
report("Tied use must be a register", MO, MONum);
else if (!MO->isTied())
report("Operand should be tied", MO, MONum);
else if (unsigned(TiedTo) != MI->findTiedOperandIdx(MONum))
report("Tied def doesn't match MCInstrDesc", MO, MONum);
} else if (MO->isReg() && MO->isTied())
report("Explicit operand should not be tied", MO, MONum);
// ARM adds %reg0 operands to indicate predicates. We'll allow that.
if (MO->isReg() && !MO->isImplicit() && !MI->isVariadic() && MO->getReg())
report("Extra explicit operand on non-variadic instruction", MO, MONum);
Jakob Stoklund Olesen
committed
}
switch (MO->getType()) {
case MachineOperand::MO_Register: {
const unsigned Reg = MO->getReg();
if (!Reg)
return;
if (MRI->tracksLiveness() && !MI->isDebugValue())
checkLiveness(MO, MONum);
// Verify the consistency of tied operands.
if (MO->isTied()) {
unsigned OtherIdx = MI->findTiedOperandIdx(MONum);
const MachineOperand &OtherMO = MI->getOperand(OtherIdx);
if (!OtherMO.isReg())
report("Must be tied to a register", MO, MONum);
if (!OtherMO.isTied())
report("Missing tie flags on tied operand", MO, MONum);
if (MI->findTiedOperandIdx(OtherIdx) != MONum)
report("Inconsistent tie links", MO, MONum);
if (MONum < MCID.getNumDefs()) {
if (OtherIdx < MCID.getNumOperands()) {
if (-1 == MCID.getOperandConstraint(OtherIdx, MCOI::TIED_TO))
report("Explicit def tied to explicit use without tie constraint",
MO, MONum);
} else {
if (!OtherMO.isImplicit())
report("Explicit def should be tied to implicit use", MO, MONum);
}
}
}
// Verify two-address constraints after leaving SSA form.
unsigned DefIdx;
if (!MRI->isSSA() && MO->isUse() &&
MI->isRegTiedToDefOperand(MONum, &DefIdx) &&
Reg != MI->getOperand(DefIdx).getReg())
report("Two-address instruction operands must be identical", MO, MONum);
// Check register classes.
Evan Cheng
committed
if (MONum < MCID.getNumOperands() && !MO->isImplicit()) {
unsigned SubIdx = MO->getSubReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
if (SubIdx) {
report("Illegal subregister index for physical register", MO, MONum);
return;
Jakob Stoklund Olesen
committed
if (const TargetRegisterClass *DRC =
TII->getRegClass(MCID, MONum, TRI, *MF)) {
if (!DRC->contains(Reg)) {
report("Illegal physical register for instruction", MO, MONum);
*OS << TRI->getName(Reg) << " is not a "
<< DRC->getName() << " register.\n";
}
}
} else {
// Virtual register.
const TargetRegisterClass *RC = MRI->getRegClass(Reg);
if (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";
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;
}
Jakob Stoklund Olesen
committed
if (const TargetRegisterClass *DRC =
TII->getRegClass(MCID, MONum, TRI, *MF)) {
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";
}
}
}
}
break;
}
case MachineOperand::MO_RegisterMask:
regMasks.push_back(MO->getRegMask());
break;
case MachineOperand::MO_MachineBasicBlock:
if (MI->isPHI() && !MO->getMBB()->isSuccessor(MI->getParent()))
report("PHI operand is not in the CFG", MO, MONum);
break;
case MachineOperand::MO_FrameIndex:
if (LiveStks && LiveStks->hasInterval(MO->getIndex()) &&
LiveInts && !LiveInts->isNotInMIMap(MI)) {
LiveInterval &LI = LiveStks->getInterval(MO->getIndex());
SlotIndex Idx = LiveInts->getInstructionIndex(MI);
if (MI->mayLoad() && !LI.liveAt(Idx.getRegSlot(true))) {
report("Instruction loads from dead spill slot", MO, MONum);
*OS << "Live stack: " << LI << '\n';
}
if (MI->mayStore() && !LI.liveAt(Idx.getRegSlot())) {
report("Instruction stores to dead spill slot", MO, MONum);
*OS << "Live stack: " << LI << '\n';
}
}
break;
default:
break;
}
}
void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
const MachineInstr *MI = MO->getParent();
const unsigned Reg = MO->getReg();
// Both use and def operands can read a register.
if (MO->readsReg()) {
regsLiveInButUnused.erase(Reg);
if (MO->isKill())
addRegWithSubRegs(regsKilled, Reg);
// Check that LiveVars knows this kill.
if (LiveVars && TargetRegisterInfo::isVirtualRegister(Reg) &&
MO->isKill()) {
LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
if (std::find(VI.Kills.begin(), VI.Kills.end(), MI) == VI.Kills.end())
report("Kill missing from LiveVariables", MO, MONum);
}
// Check LiveInts liveness and kill.
if (LiveInts && !LiveInts->isNotInMIMap(MI)) {
SlotIndex UseIdx = LiveInts->getInstructionIndex(MI);
// Check the cached regunit intervals.
if (TargetRegisterInfo::isPhysicalRegister(Reg) && !isReserved(Reg)) {
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units) {
if (const LiveInterval *LI = LiveInts->getCachedRegUnit(*Units)) {