summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2010-09-17 15:48:55 +0000
committerdim <dim@FreeBSD.org>2010-09-17 15:48:55 +0000
commit5d5cc59cc77afe655b3707cb0e69e0827b444cad (patch)
tree36453626c792cccd91f783a38a169d610a6b9db9 /lib/CodeGen/MachineVerifier.cpp
parent786a18553586229ad99ecb5ecde8a9d914c45e27 (diff)
downloadFreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.zip
FreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.tar.gz
Vendor import of llvm r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/llvm/branches/release_28@114020 Approved by: rpaulo (mentor)
Diffstat (limited to 'lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--lib/CodeGen/MachineVerifier.cpp230
1 files changed, 137 insertions, 93 deletions
diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp
index 2297c90..1e88562 100644
--- a/lib/CodeGen/MachineVerifier.cpp
+++ b/lib/CodeGen/MachineVerifier.cpp
@@ -1,4 +1,4 @@
-//===-- MachineVerifier.cpp - Machine Code Verifier -------------*- C++ -*-===//
+//===-- MachineVerifier.cpp - Machine Code Verifier -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -24,6 +24,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Function.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
@@ -44,19 +45,14 @@ using namespace llvm;
namespace {
struct MachineVerifier {
- MachineVerifier(Pass *pass, bool allowDoubleDefs) :
+ MachineVerifier(Pass *pass) :
PASS(pass),
- allowVirtDoubleDefs(allowDoubleDefs),
- allowPhysDoubleDefs(true),
OutFileName(getenv("LLVM_VERIFY_MACHINEINSTRS"))
{}
bool runOnMachineFunction(MachineFunction &MF);
Pass *const PASS;
- const bool allowVirtDoubleDefs;
- const bool allowPhysDoubleDefs;
-
const char *const OutFileName;
raw_ostream *OS;
const MachineFunction *MF;
@@ -91,10 +87,6 @@ namespace {
// 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;
@@ -175,6 +167,7 @@ namespace {
// Analysis information if available
LiveVariables *LiveVars;
+ const LiveIntervals *LiveInts;
void visitMachineFunctionBefore();
void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
@@ -195,15 +188,14 @@ namespace {
void calcRegsRequired();
void verifyLiveVariables();
+ void verifyLiveIntervals();
};
struct MachineVerifierPass : public MachineFunctionPass {
static char ID; // Pass ID, replacement for typeid
- bool AllowDoubleDefs;
- explicit MachineVerifierPass(bool allowDoubleDefs = false)
- : MachineFunctionPass(&ID),
- AllowDoubleDefs(allowDoubleDefs) {}
+ MachineVerifierPass()
+ : MachineFunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
@@ -211,7 +203,7 @@ namespace {
}
bool runOnMachineFunction(MachineFunction &MF) {
- MF.verify(this, AllowDoubleDefs);
+ MF.verify(this);
return false;
}
};
@@ -219,17 +211,15 @@ namespace {
}
char MachineVerifierPass::ID = 0;
-static RegisterPass<MachineVerifierPass>
-MachineVer("machineverifier", "Verify generated machine code");
-static const PassInfo *const MachineVerifyID = &MachineVer;
+INITIALIZE_PASS(MachineVerifierPass, "machineverifier",
+ "Verify generated machine code", false, false);
-FunctionPass *llvm::createMachineVerifierPass(bool allowPhysDoubleDefs) {
- return new MachineVerifierPass(allowPhysDoubleDefs);
+FunctionPass *llvm::createMachineVerifierPass() {
+ return new MachineVerifierPass();
}
-void MachineFunction::verify(Pass *p, bool allowDoubleDefs) const {
- MachineVerifier(p, allowDoubleDefs)
- .runOnMachineFunction(const_cast<MachineFunction&>(*this));
+void MachineFunction::verify(Pass *p) const {
+ MachineVerifier(p).runOnMachineFunction(const_cast<MachineFunction&>(*this));
}
bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
@@ -255,10 +245,13 @@ bool MachineVerifier::runOnMachineFunction(MachineFunction &MF) {
TRI = TM->getRegisterInfo();
MRI = &MF.getRegInfo();
+ LiveVars = NULL;
+ LiveInts = NULL;
if (PASS) {
- LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
- } else {
- LiveVars = NULL;
+ LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>();
+ // We don't want to verify LiveVariables if LiveIntervals is available.
+ if (!LiveInts)
+ LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
}
visitMachineFunctionBefore();
@@ -512,6 +505,20 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
if ((*I)->isStore() && !TI.mayStore())
report("Missing mayStore flag", MI);
}
+
+ // Debug values must not have a slot index.
+ // Other instructions must have one.
+ if (LiveInts) {
+ bool mapped = !LiveInts->isNotInMIMap(MI);
+ if (MI->isDebugValue()) {
+ if (mapped)
+ report("Debug instruction has a slot index", MI);
+ } else {
+ if (!mapped)
+ report("Missing slot index", MI);
+ }
+ }
+
}
void
@@ -570,15 +577,30 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
} else
isKill = MO->isKill();
- if (isKill) {
+ 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);
+ // 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).getUseIndex();
+ if (LiveInts->hasInterval(Reg)) {
+ const LiveInterval &LI = LiveInts->getInterval(Reg);
+ if (!LI.liveAt(UseIdx)) {
+ report("No live range at use", MO, MONum);
+ *OS << UseIdx << " is not live in " << LI << '\n';
+ }
+ // TODO: Verify isKill == LI.killedAt.
+ } else if (TargetRegisterInfo::isVirtualRegister(Reg)) {
+ report("Virtual register has no Live interval", MO, MONum);
}
}
@@ -607,6 +629,28 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
addRegWithSubRegs(regsDead, Reg);
else
addRegWithSubRegs(regsDefined, Reg);
+
+ // Check LiveInts for a live range, but only for virtual registers.
+ if (LiveInts && TargetRegisterInfo::isVirtualRegister(Reg) &&
+ !LiveInts->isNotInMIMap(MI)) {
+ SlotIndex DefIdx = LiveInts->getInstructionIndex(MI).getDefIndex();
+ if (LiveInts->hasInterval(Reg)) {
+ const LiveInterval &LI = LiveInts->getInterval(Reg);
+ if (const LiveRange *LR = LI.getLiveRangeContaining(DefIdx)) {
+ assert(LR->valno && "NULL valno is not allowed");
+ if (LR->valno->def != DefIdx) {
+ report("Inconsistent valno->def", MO, MONum);
+ *OS << "Valno " << LR->valno->id << " is not defined at "
+ << DefIdx << " in " << LI << '\n';
+ }
+ } else {
+ report("No live range at def", MO, MONum);
+ *OS << DefIdx << " is not live in " << LI << '\n';
+ }
+ } else {
+ report("Virtual register has no Live interval", MO, MONum);
+ }
+ }
}
// Check register classes.
@@ -670,40 +714,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
void MachineVerifier::visitMachineInstrAfter(const MachineInstr *MI) {
BBInfo &MInfo = MBBInfoMap[MI->getParent()];
set_union(MInfo.regsKilled, regsKilled);
- set_subtract(regsLive, regsKilled);
- regsKilled.clear();
-
- // 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)) {
- 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";
- }
- } 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_subtract(regsLive, regsDead); regsDead.clear();
- set_union(regsLive, regsDefined); regsDefined.clear();
+ set_subtract(regsLive, regsKilled); regsKilled.clear();
+ set_subtract(regsLive, regsDead); regsDead.clear();
+ set_union(regsLive, regsDefined); regsDefined.clear();
}
void
@@ -828,35 +841,15 @@ void MachineVerifier::visitMachineFunctionAfter() {
continue;
checkPHIOps(MFI);
-
- // Verify dead-in virtual registers.
- if (!allowVirtDoubleDefs) {
- 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.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";
- }
- }
- }
- }
}
- // Now check LiveVariables info if available
- if (LiveVars) {
+ // Now check liveness info if available
+ if (LiveVars || LiveInts)
calcRegsRequired();
+ if (LiveVars)
verifyLiveVariables();
- }
+ if (LiveInts)
+ verifyLiveIntervals();
}
void MachineVerifier::verifyLiveVariables() {
@@ -886,4 +879,55 @@ void MachineVerifier::verifyLiveVariables() {
}
}
+void MachineVerifier::verifyLiveIntervals() {
+ assert(LiveInts && "Don't call verifyLiveIntervals without LiveInts");
+ for (LiveIntervals::const_iterator LVI = LiveInts->begin(),
+ LVE = LiveInts->end(); LVI != LVE; ++LVI) {
+ const LiveInterval &LI = *LVI->second;
+ assert(LVI->first == LI.reg && "Invalid reg to interval mapping");
+
+ for (LiveInterval::const_vni_iterator I = LI.vni_begin(), E = LI.vni_end();
+ I!=E; ++I) {
+ VNInfo *VNI = *I;
+ const LiveRange *DefLR = LI.getLiveRangeContaining(VNI->def);
+
+ if (!DefLR) {
+ if (!VNI->isUnused()) {
+ report("Valno not live at def and not marked unused", MF);
+ *OS << "Valno #" << VNI->id << " in " << LI << '\n';
+ }
+ continue;
+ }
+
+ if (VNI->isUnused())
+ continue;
+
+ if (DefLR->valno != VNI) {
+ report("Live range at def has different valno", MF);
+ DefLR->print(*OS);
+ *OS << " should use valno #" << VNI->id << " in " << LI << '\n';
+ }
+
+ }
+
+ for (LiveInterval::const_iterator I = LI.begin(), E = LI.end(); I!=E; ++I) {
+ const LiveRange &LR = *I;
+ assert(LR.valno && "Live range has no valno");
+
+ if (LR.valno->id >= LI.getNumValNums() ||
+ LR.valno != LI.getValNumInfo(LR.valno->id)) {
+ report("Foreign valno in live range", MF);
+ LR.print(*OS);
+ *OS << " has a valno not in " << LI << '\n';
+ }
+
+ if (LR.valno->isUnused()) {
+ report("Live range valno is marked unused", MF);
+ LR.print(*OS);
+ *OS << " in " << LI << '\n';
+ }
+
+ }
+ }
+}
OpenPOWER on IntegriCloud