mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-31 15:53:42 +00:00
Make the verifier API more complete and useful.
Patch contributed by Reid Spencer git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12609 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0e4271f8b2
commit
fdc38c4ad3
@ -55,6 +55,7 @@
|
|||||||
#include "llvm/Support/InstVisitor.h"
|
#include "llvm/Support/InstVisitor.h"
|
||||||
#include "Support/STLExtras.h"
|
#include "Support/STLExtras.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <sstream>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
namespace { // Anonymous namespace for class
|
namespace { // Anonymous namespace for class
|
||||||
@ -62,14 +63,25 @@ namespace { // Anonymous namespace for class
|
|||||||
struct Verifier : public FunctionPass, InstVisitor<Verifier> {
|
struct Verifier : public FunctionPass, InstVisitor<Verifier> {
|
||||||
bool Broken; // Is this module found to be broken?
|
bool Broken; // Is this module found to be broken?
|
||||||
bool RealPass; // Are we not being run by a PassManager?
|
bool RealPass; // Are we not being run by a PassManager?
|
||||||
bool AbortBroken; // If broken, should it or should it not abort?
|
VerifierFailureAction action;
|
||||||
|
// What to do if verification fails.
|
||||||
Module *Mod; // Module we are verifying right now
|
Module *Mod; // Module we are verifying right now
|
||||||
DominatorSet *DS; // Dominator set, caution can be null!
|
DominatorSet *DS; // Dominator set, caution can be null!
|
||||||
|
std::stringstream msgs; // A stringstream to collect messages
|
||||||
|
|
||||||
Verifier() : Broken(false), RealPass(true), AbortBroken(true), DS(0) {}
|
Verifier()
|
||||||
Verifier(bool AB) : Broken(false), RealPass(true), AbortBroken(AB), DS(0) {}
|
: Broken(false), RealPass(true), action(AbortProcessAction),
|
||||||
|
DS(0), msgs( std::ios_base::app | std::ios_base::out ) {}
|
||||||
|
Verifier( VerifierFailureAction ctn )
|
||||||
|
: Broken(false), RealPass(true), action(ctn), DS(0),
|
||||||
|
msgs( std::ios_base::app | std::ios_base::out ) {}
|
||||||
|
Verifier(bool AB )
|
||||||
|
: Broken(false), RealPass(true),
|
||||||
|
action( AB ? AbortProcessAction : PrintMessageAction), DS(0),
|
||||||
|
msgs( std::ios_base::app | std::ios_base::out ) {}
|
||||||
Verifier(DominatorSet &ds)
|
Verifier(DominatorSet &ds)
|
||||||
: Broken(false), RealPass(false), AbortBroken(false), DS(&ds) {}
|
: Broken(false), RealPass(false), action(PrintMessageAction),
|
||||||
|
DS(&ds), msgs( std::ios_base::app | std::ios_base::out ) {}
|
||||||
|
|
||||||
|
|
||||||
bool doInitialization(Module &M) {
|
bool doInitialization(Module &M) {
|
||||||
@ -120,10 +132,26 @@ namespace { // Anonymous namespace for class
|
|||||||
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
||||||
/// this condition, do so.
|
/// this condition, do so.
|
||||||
///
|
///
|
||||||
void abortIfBroken() const {
|
void abortIfBroken() {
|
||||||
if (Broken && AbortBroken) {
|
if (Broken)
|
||||||
std::cerr << "Broken module found, compilation aborted!\n";
|
{
|
||||||
abort();
|
msgs << "Broken module found, ";
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case AbortProcessAction:
|
||||||
|
msgs << "compilation aborted!\n";
|
||||||
|
std::cerr << msgs.str();
|
||||||
|
abort();
|
||||||
|
case ThrowExceptionAction:
|
||||||
|
msgs << "verification terminated.\n";
|
||||||
|
throw msgs.str();
|
||||||
|
case PrintMessageAction:
|
||||||
|
msgs << "verification continues.\n";
|
||||||
|
std::cerr << msgs.str();
|
||||||
|
break;
|
||||||
|
case ReturnStatusAction:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,12 +182,12 @@ namespace { // Anonymous namespace for class
|
|||||||
void WriteValue(const Value *V) {
|
void WriteValue(const Value *V) {
|
||||||
if (!V) return;
|
if (!V) return;
|
||||||
if (isa<Instruction>(V)) {
|
if (isa<Instruction>(V)) {
|
||||||
std::cerr << *V;
|
msgs << *V;
|
||||||
} else if (const Type *Ty = dyn_cast<Type>(V)) {
|
} else if (const Type *Ty = dyn_cast<Type>(V)) {
|
||||||
WriteTypeSymbolic(std::cerr, Ty, Mod);
|
WriteTypeSymbolic(msgs, Ty, Mod);
|
||||||
} else {
|
} else {
|
||||||
WriteAsOperand (std::cerr, V, true, true, Mod);
|
WriteAsOperand (msgs, V, true, true, Mod);
|
||||||
std::cerr << "\n";
|
msgs << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +198,7 @@ namespace { // Anonymous namespace for class
|
|||||||
void CheckFailed(const std::string &Message,
|
void CheckFailed(const std::string &Message,
|
||||||
const Value *V1 = 0, const Value *V2 = 0,
|
const Value *V1 = 0, const Value *V2 = 0,
|
||||||
const Value *V3 = 0, const Value *V4 = 0) {
|
const Value *V3 = 0, const Value *V4 = 0) {
|
||||||
std::cerr << Message << "\n";
|
msgs << Message << "\n";
|
||||||
WriteValue(V1);
|
WriteValue(V1);
|
||||||
WriteValue(V2);
|
WriteValue(V2);
|
||||||
WriteValue(V3);
|
WriteValue(V3);
|
||||||
@ -623,18 +651,18 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
|||||||
// Implement the public interfaces to this file...
|
// Implement the public interfaces to this file...
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
FunctionPass *llvm::createVerifierPass() {
|
FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
|
||||||
return new Verifier();
|
return new Verifier(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// verifyFunction - Create
|
// verifyFunction - Create
|
||||||
bool llvm::verifyFunction(const Function &f) {
|
bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
|
||||||
Function &F = const_cast<Function&>(f);
|
Function &F = const_cast<Function&>(f);
|
||||||
assert(!F.isExternal() && "Cannot verify external functions");
|
assert(!F.isExternal() && "Cannot verify external functions");
|
||||||
|
|
||||||
FunctionPassManager FPM(new ExistingModuleProvider(F.getParent()));
|
FunctionPassManager FPM(new ExistingModuleProvider(F.getParent()));
|
||||||
Verifier *V = new Verifier();
|
Verifier *V = new Verifier(action);
|
||||||
FPM.add(V);
|
FPM.add(V);
|
||||||
FPM.run(F);
|
FPM.run(F);
|
||||||
return V->Broken;
|
return V->Broken;
|
||||||
@ -643,9 +671,9 @@ bool llvm::verifyFunction(const Function &f) {
|
|||||||
/// verifyModule - Check a module for errors, printing messages on stderr.
|
/// verifyModule - Check a module for errors, printing messages on stderr.
|
||||||
/// Return true if the module is corrupt.
|
/// Return true if the module is corrupt.
|
||||||
///
|
///
|
||||||
bool llvm::verifyModule(const Module &M) {
|
bool llvm::verifyModule(const Module &M, VerifierFailureAction action) {
|
||||||
PassManager PM;
|
PassManager PM;
|
||||||
Verifier *V = new Verifier();
|
Verifier *V = new Verifier(action);
|
||||||
PM.add(V);
|
PM.add(V);
|
||||||
PM.run((Module&)M);
|
PM.run((Module&)M);
|
||||||
return V->Broken;
|
return V->Broken;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user