#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <fstream>
using namespace llvm;
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF);
BitVector regsReserved;
RegSet regsLive;
- RegVector regsDefined, regsImpDefined, regsDead, regsKilled;
+ RegVector regsDefined, regsDead, regsKilled;
+ RegSet regsLiveInButUnused;
// Add Reg and any sub-registers to RV
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
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;
DenseMap<const MachineBasicBlock*, BBInfo> MBBInfoMap;
bool isReserved(unsigned Reg) {
- return Reg < regsReserved.size() && regsReserved[Reg];
+ return Reg < regsReserved.size() && regsReserved.test(Reg);
}
void visitMachineFunctionBefore();
char MachineVerifier::ID = 0;
static RegisterPass<MachineVerifier>
-MachineVer("verify-machineinstrs", "Verify generated machine code");
+MachineVer("machineverifier", "Verify generated machine code");
static const PassInfo *const MachineVerifyID = &MachineVer;
FunctionPass *
if (OutFileName)
OutFile.close();
-
- if (foundErrors) {
- cerr << "\nStopping with " << foundErrors << " machine code errors.\n";
- exit(1);
+ else if (foundErrors) {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Found " << foundErrors << " machine code errors.";
+ llvm_report_error(Msg.str());
}
+ // Clean up.
+ regsLive.clear();
+ regsDefined.clear();
+ regsDead.clear();
+ regsKilled.clear();
+ regsLiveInButUnused.clear();
+ MBBInfoMap.clear();
+
return false; // no changes
}
if (!foundErrors++)
MF->print(OS);
*OS << "*** Bad machine code: " << msg << " ***\n"
- << "- function: " << MF->getFunction()->getName() << "\n";
+ << "- function: " << MF->getFunction()->getNameStr() << "\n";
}
void
{
assert(MBB);
report(msg, MBB->getParent());
- *OS << "- basic block: " << MBB->getBasicBlock()->getName()
+ *OS << "- basic block: " << MBB->getBasicBlock()->getNameStr()
<< " " << (void*)MBB
<< " (#" << MBB->getNumber() << ")\n";
}
MachineVerifier::visitMachineFunctionBefore()
{
regsReserved = TRI->getReservedRegs(*MF);
+
+ // A sub-register of a reserved register is also reserved
+ for (int Reg = regsReserved.find_first(); Reg>=0;
+ Reg = regsReserved.find_next(Reg)) {
+ for (const unsigned *Sub = TRI->getSubRegisters(Reg); *Sub; ++Sub) {
+ // FIXME: This should probably be:
+ // assert(regsReserved.test(*Sub) && "Non-reserved sub-register");
+ regsReserved.set(*Sub);
+ }
+ }
markReachable(&MF->front());
}
for (const unsigned *R = TRI->getSubRegisters(*I); *R; R++)
regsLive.insert(*R);
}
+ regsLiveInButUnused = regsLive;
regsKilled.clear();
regsDefined.clear();
- regsImpDefined.clear();
}
void
MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum)
{
const MachineInstr *MI = MO->getParent();
+ const TargetInstrDesc &TI = MI->getDesc();
+
+ // The first TI.NumDefs operands must be explicit register defines
+ if (MONum < TI.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);
+ }
+
switch (MO->getType()) {
case MachineOperand::MO_Register: {
const unsigned Reg = MO->getReg();
return;
// Check Live Variables.
- if (MO->isUse()) {
+ if (MO->isUndef()) {
+ // An <undef> doesn't refer to any register, so just skip it.
+ } else if (MO->isUse()) {
+ regsLiveInButUnused.erase(Reg);
+
if (MO->isKill()) {
addRegWithSubRegs(regsKilled, Reg);
+ // Tied operands on two-address instuctions MUST NOT have a <kill> flag.
+ if (MI->isRegTiedToDefOperand(MONum))
+ report("Illegal kill flag on two-address instruction operand",
+ MO, MONum);
} else {
- // TwoAddress instr modyfying a reg is treated as kill+def.
+ // TwoAddress instr modifying 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))
+ // Use of a dead register.
+ if (!regsLive.count(Reg)) {
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
// Reserved registers may be used even when 'dead'.
if (!isReserved(Reg))
else if (MI->getOpcode() != TargetInstrInfo::PHI)
MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI));
}
+ }
} else {
+ assert(MO->isDef());
// 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);
+ else
+ addRegWithSubRegs(regsDefined, 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();
}
sr = s;
}
- if (TOI.RegClass) {
- const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass);
+ if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
if (!DRC->contains(sr)) {
report("Illegal physical register for instruction", MO, MONum);
*OS << TRI->getName(sr) << " is not a "
}
RC = *(RC->subregclasses_begin()+SubIdx);
}
- if (TOI.RegClass) {
- const TargetRegisterClass *DRC = TRI->getRegClass(TOI.RegClass);
+ if (const TargetRegisterClass *DRC = TOI.getRegClass(TRI)) {
if (RC != DRC && !RC->hasSuperClass(DRC)) {
report("Illegal virtual register for instruction", MO, MONum);
*OS << "Expected a " << DRC->getName() << " register, but got a "
set_subtract(regsLive, regsKilled);
regsKilled.clear();
- for (RegVector::const_iterator I = regsDefined.begin(),
- E = regsDefined.end(); I != E; ++I) {
+ // Verify that both <def> and <def,dead> operands refer to dead registers.
+ RegVector defs(regsDefined);
+ defs.append(regsDead.begin(), regsDead.end());
+
+ for (RegVector::const_iterator I = defs.begin(), E = defs.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)) {
+ if (!allowPhysDoubleDefs && !isReserved(*I) &&
+ !regsLiveInButUnused.count(*I)) {
report("Redefining a live physical register", MI);
*OS << "Register " << TRI->getName(*I)
<< " was defined but already live.\n";
}
}
- set_union(regsLive, regsDefined); regsDefined.clear();
- set_union(regsLive, regsImpDefined); regsImpDefined.clear();
set_subtract(regsLive, regsDead); regsDead.clear();
+ set_union(regsLive, regsDefined); regsDefined.clear();
}
void
for (MachineBasicBlock::const_livein_iterator I = MFI->livein_begin(),
E = MFI->livein_end(); I != E; ++I) {
if (TargetRegisterInfo::isPhysicalRegister(*I) &&
- !PrInfo.isLiveOut(*I)) {
+ !isReserved (*I) && !PrInfo.isLiveOut(*I)) {
report("Live-in physical register is not live-out from predecessor",
MFI);
*OS << "Register " << TRI->getName(*I)