summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2009-11-18 20:36:57 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2009-11-18 20:36:57 +0000
commit8f16e02fc95c9b197d38bcd681f2612d36ed5c11 (patch)
tree3f1d6ce58e2a6821cd52b46ffc60b2b5fc854aa2 /lib/CodeGen/MachineVerifier.cpp
parent1e78aa445c5b5b466cea4478f3f9034d4be7278e (diff)
downloadllvm-8f16e02fc95c9b197d38bcd681f2612d36ed5c11.tar.gz
llvm-8f16e02fc95c9b197d38bcd681f2612d36ed5c11.tar.bz2
llvm-8f16e02fc95c9b197d38bcd681f2612d36ed5c11.tar.xz
Allow the machine verifier to be run outside the PassManager.
Verify LiveVariables information when present. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89241 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--lib/CodeGen/MachineVerifier.cpp177
1 files changed, 160 insertions, 17 deletions
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index be9f68f6a7..a1c74c0c48 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -42,23 +42,18 @@
using namespace llvm;
namespace {
- struct MachineVerifier : public MachineFunctionPass {
- static char ID; // Pass ID, replacement for typeid
+ struct MachineVerifier {
- MachineVerifier(bool allowDoubleDefs = false) :
- MachineFunctionPass(&ID),
+ MachineVerifier(Pass *pass, bool allowDoubleDefs) :
+ PASS(pass),
allowVirtDoubleDefs(allowDoubleDefs),
allowPhysDoubleDefs(allowDoubleDefs),
OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS"))
- {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- MachineFunctionPass::getAnalysisUsage(AU);
- }
+ {}
bool runOnMachineFunction(MachineFunction &MF);
+ Pass *const PASS;
const bool allowVirtDoubleDefs;
const bool allowPhysDoubleDefs;
@@ -112,6 +107,10 @@ namespace {
// 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;
+
BBInfo() : reachable(false) {}
// Add register to vregsPassed if it belongs there. Return true if
@@ -133,6 +132,34 @@ namespace {
return changed;
}
+ // 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);
@@ -146,6 +173,9 @@ namespace {
return Reg < regsReserved.size() && regsReserved.test(Reg);
}
+ // Analysis information if available
+ LiveVariables *LiveVars;
+
void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
void visitMachineInstrBefore(const MachineInstr *MI);
@@ -163,20 +193,44 @@ namespace {
void calcMaxRegsPassed();
void calcMinRegsPassed();
void checkPHIOps(const MachineBasicBlock *MBB);
+
+ void calcRegsRequired();
+ void verifyLiveVariables();
+ };
+
+ struct MachineVerifierPass : public MachineFunctionPass {
+ static char ID; // Pass ID, replacement for typeid
+ bool AllowDoubleDefs;
+
+ explicit MachineVerifierPass(bool allowDoubleDefs = false)
+ : MachineFunctionPass(&ID),
+ AllowDoubleDefs(allowDoubleDefs) {}
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+ }
+
+ bool runOnMachineFunction(MachineFunction &MF) {
+ MF.verify(this, AllowDoubleDefs);
+ return false;
+ }
};
+
}
-char MachineVerifier::ID = 0;
-static RegisterPass<MachineVerifier>
+char MachineVerifierPass::ID = 0;
+static RegisterPass<MachineVerifierPass>
MachineVer("machineverifier", "Verify generated machine code");
static const PassInfo *const MachineVerifyID = &MachineVer;
FunctionPass *llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) {
- return new MachineVerifier(allowPhysDoubleDefs);
+ return new MachineVerifierPass(allowPhysDoubleDefs);
}
-void MachineFunction::verify() const {
- MachineVerifier().runOnMachineFunction(const_cast<MachineFunction&>(*this));
+void MachineFunction::verify(Pass *p, bool allowDoubleDefs) const {
+ MachineVerifier(p, allowDoubleDefs)
+ .runOnMachineFunction(const_cast<MachineFunction&>(*this));
}
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
@@ -202,6 +256,12 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
TRI = TM->getRegisterInfo();
MRI = &MF.getRegInfo();
+ if (PASS) {
+ LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
+ } else {
+ LiveVars = NULL;
+ }
+
visitMachineFunctionBefore();
for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
MFI!=MFE; ++MFI) {
@@ -518,8 +578,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
} else if (MO->isUse()) {
regsLiveInButUnused.erase(Reg);
+ bool isKill = false;
if (MO->isKill()) {
- addRegWithSubRegs(regsKilled, Reg);
+ isKill = true;
// 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",
@@ -529,8 +590,20 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
unsigned defIdx;
if (MI->isRegTiedToDefOperand(MONum, &defIdx) &&
MI->getOperand(defIdx).getReg() == Reg)
- addRegWithSubRegs(regsKilled, Reg);
+ isKill = true;
+ }
+ if (isKill) {
+ addRegWithSubRegs(regsKilled, Reg);
+
+ // Check that LiveVars knows this kill
+ if (LiveVars && TargetRegisterInfo::isVirtualRegister(Reg)) {
+ 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);
+ }
}
+
// Use of a dead register.
if (!regsLive.count(Reg)) {
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
@@ -734,6 +807,41 @@ void MachineVerifier::calcMinRegsPassed() {
}
}
+// Calculate the set of virtual registers that must be passed through each basic
+// block in order to satisfy the requirements of successor blocks. This is very
+// similar to calcMaxRegsPassed, only backwards.
+void MachineVerifier::calcRegsRequired() {
+ // First push live-in regs to predecessors' vregsRequired.
+ 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];
+ for (MachineBasicBlock::const_pred_iterator PrI = MBB.pred_begin(),
+ PrE = MBB.pred_end(); PrI != PrE; ++PrI) {
+ BBInfo &PInfo = MBBInfoMap[*PrI];
+ if (PInfo.addRequired(MInfo.vregsLiveIn))
+ todo.insert(*PrI);
+ }
+ }
+
+ // Iteratively push vregsRequired to predecessors. 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_pred_iterator PrI = MBB->pred_begin(),
+ PrE = MBB->pred_end(); PrI != PrE; ++PrI) {
+ if (*PrI == MBB)
+ continue;
+ BBInfo &SInfo = MBBInfoMap[*PrI];
+ if (SInfo.addRequired(MInfo.vregsRequired))
+ todo.insert(*PrI);
+ }
+ }
+}
+
// 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) {
@@ -849,4 +957,39 @@ void MachineVerifier::visitMachineFunctionAfter() {
}
}
}
+
+ // Now check LiveVariables info if available
+ if (LiveVars) {
+ calcRegsRequired();
+ verifyLiveVariables();
+ }
}
+
+void MachineVerifier::verifyLiveVariables() {
+ assert(LiveVars && "Don't call verifyLiveVariables without LiveVars");
+ for (unsigned Reg = TargetRegisterInfo::FirstVirtualRegister,
+ RegE = MRI->getLastVirtReg()-1; Reg != RegE; ++Reg) {
+ LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
+ for (MachineFunction::const_iterator MFI = MF->begin(), MFE = MF->end();
+ MFI != MFE; ++MFI) {
+ BBInfo &MInfo = MBBInfoMap[MFI];
+
+ // Our vregsRequired should be identical to LiveVariables' AliveBlocks
+ if (MInfo.vregsRequired.count(Reg)) {
+ if (!VI.AliveBlocks.test(MFI->getNumber())) {
+ report("LiveVariables: Block missing from AliveBlocks", MFI);
+ *OS << "Virtual register %reg" << Reg
+ << " must be live through the block.\n";
+ }
+ } else {
+ if (VI.AliveBlocks.test(MFI->getNumber())) {
+ report("LiveVariables: Block should not be in AliveBlocks", MFI);
+ *OS << "Virtual register %reg" << Reg
+ << " is not needed live through the block.\n";
+ }
+ }
+ }
+ }
+}
+
+