mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 12:50:00 +00:00
[PM] [cleanup] Rename some of the Verifier's members, re-arrange them,
and tweak comments prior to more invasive surgery. Also clean up some other non-doxygen comments, and run clang-format over the parts that are going to change dramatically in subsequent commits so that those don't get cluttered with formatting changes. No functionality changed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199489 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bd2c711cdd
commit
825488c539
@ -36,9 +36,9 @@ class Function;
|
||||
/// this enumeration as an argument provides a default value for it. The
|
||||
/// actions are listed below.
|
||||
enum VerifierFailureAction {
|
||||
AbortProcessAction, ///< verifyModule will print to stderr and abort()
|
||||
PrintMessageAction, ///< verifyModule will print to stderr and return true
|
||||
ReturnStatusAction ///< verifyModule will just return true
|
||||
AbortProcessAction, ///< verifyModule will print to stderr and abort()
|
||||
PrintMessageAction, ///< verifyModule will print to stderr and return true
|
||||
ReturnStatusAction ///< verifyModule will just return true
|
||||
};
|
||||
|
||||
/// \brief Create a verifier pass.
|
||||
@ -51,6 +51,9 @@ createVerifierPass(VerifierFailureAction action = AbortProcessAction);
|
||||
|
||||
/// \brief Check a function for errors, useful for use when debugging a
|
||||
/// pass.
|
||||
///
|
||||
/// If there are no errors, the function returns false. If an error is found,
|
||||
/// the action taken depends on the \p action parameter.
|
||||
bool verifyFunction(const Function &F,
|
||||
VerifierFailureAction action = AbortProcessAction);
|
||||
|
||||
|
@ -80,293 +80,296 @@ static cl::opt<bool> DisableDebugInfoVerifier("disable-debug-info-verifier",
|
||||
cl::init(true));
|
||||
|
||||
namespace {
|
||||
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
|
||||
static char ID; // Pass ID, replacement for typeid
|
||||
bool Broken; // Is this module found to be broken?
|
||||
VerifierFailureAction action;
|
||||
// What to do if verification fails.
|
||||
Module *Mod; // Module we are verifying right now
|
||||
LLVMContext *Context; // Context within which we are verifying
|
||||
DominatorTree DT;
|
||||
const DataLayout *DL;
|
||||
struct Verifier : public FunctionPass, public InstVisitor<Verifier> {
|
||||
static char ID;
|
||||
|
||||
std::string Messages;
|
||||
raw_string_ostream MessagesStr;
|
||||
// What to do if verification fails.
|
||||
VerifierFailureAction Action;
|
||||
|
||||
/// InstInThisBlock - when verifying a basic block, keep track of all of the
|
||||
/// instructions we have seen so far. This allows us to do efficient
|
||||
/// dominance checks for the case when an instruction has an operand that is
|
||||
/// an instruction in the same block.
|
||||
SmallPtrSet<Instruction*, 16> InstsInThisBlock;
|
||||
Module *M;
|
||||
LLVMContext *Context;
|
||||
const DataLayout *DL;
|
||||
DominatorTree DT;
|
||||
|
||||
/// MDNodes - keep track of the metadata nodes that have been checked
|
||||
/// already.
|
||||
SmallPtrSet<MDNode *, 32> MDNodes;
|
||||
bool Broken;
|
||||
std::string Messages;
|
||||
raw_string_ostream MessagesStr;
|
||||
|
||||
/// PersonalityFn - The personality function referenced by the
|
||||
/// LandingPadInsts. All LandingPadInsts within the same function must use
|
||||
/// the same personality function.
|
||||
const Value *PersonalityFn;
|
||||
/// \brief When verifying a basic block, keep track of all of the
|
||||
/// instructions we have seen so far.
|
||||
///
|
||||
/// This allows us to do efficient dominance checks for the case when an
|
||||
/// instruction has an operand that is an instruction in the same block.
|
||||
SmallPtrSet<Instruction *, 16> InstsInThisBlock;
|
||||
|
||||
/// Finder keeps track of all debug info MDNodes in a Module.
|
||||
DebugInfoFinder Finder;
|
||||
/// \brief Keep track of the metadata nodes that have been checked already.
|
||||
SmallPtrSet<MDNode *, 32> MDNodes;
|
||||
|
||||
Verifier()
|
||||
: FunctionPass(ID), Broken(false),
|
||||
action(AbortProcessAction), Mod(0), Context(0), DL(0),
|
||||
MessagesStr(Messages), PersonalityFn(0) {
|
||||
initializeVerifierPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
explicit Verifier(VerifierFailureAction ctn)
|
||||
: FunctionPass(ID), Broken(false), action(ctn), Mod(0),
|
||||
Context(0), DL(0), MessagesStr(Messages), PersonalityFn(0) {
|
||||
initializeVerifierPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
/// \brief The personality function referenced by the LandingPadInsts.
|
||||
/// All LandingPadInsts within the same function must use the same
|
||||
/// personality function.
|
||||
const Value *PersonalityFn;
|
||||
|
||||
bool doInitialization(Module &M) {
|
||||
Mod = &M;
|
||||
Context = &M.getContext();
|
||||
/// \brief Finder keeps track of all debug info MDNodes in a Module.
|
||||
DebugInfoFinder Finder;
|
||||
|
||||
DL = getAnalysisIfAvailable<DataLayout>();
|
||||
Verifier()
|
||||
: FunctionPass(ID), Action(AbortProcessAction), M(0), Context(0), DL(0),
|
||||
Broken(false), MessagesStr(Messages), PersonalityFn(0) {
|
||||
initializeVerifierPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
explicit Verifier(VerifierFailureAction Action)
|
||||
: FunctionPass(ID), Action(Action), M(0), Context(0), DL(0),
|
||||
Broken(false), MessagesStr(Messages), PersonalityFn(0) {
|
||||
initializeVerifierPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
// We must abort before returning back to the pass manager, or else the
|
||||
// pass manager may try to run other passes on the broken module.
|
||||
return abortIfBroken();
|
||||
}
|
||||
bool doInitialization(Module &M) {
|
||||
this->M = &M;
|
||||
Context = &M.getContext();
|
||||
|
||||
bool runOnFunction(Function &F) {
|
||||
Broken = false;
|
||||
DL = getAnalysisIfAvailable<DataLayout>();
|
||||
|
||||
// First ensure the function is well-enough formed to compute dominance
|
||||
// information.
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
||||
if (I->empty() || !I->back().isTerminator()) {
|
||||
dbgs() << "Basic Block in function '" << F.getName()
|
||||
<< "' does not have terminator!\n";
|
||||
I->printAsOperand(dbgs(), true);
|
||||
dbgs() << "\n";
|
||||
Broken = true;
|
||||
}
|
||||
// We must abort before returning back to the pass manager, or else the
|
||||
// pass manager may try to run other passes on the broken module.
|
||||
return abortIfBroken();
|
||||
}
|
||||
|
||||
bool runOnFunction(Function &F) {
|
||||
Broken = false;
|
||||
|
||||
// First ensure the function is well-enough formed to compute dominance
|
||||
// information.
|
||||
for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
|
||||
if (I->empty() || !I->back().isTerminator()) {
|
||||
dbgs() << "Basic Block in function '" << F.getName()
|
||||
<< "' does not have terminator!\n";
|
||||
I->printAsOperand(dbgs(), true);
|
||||
dbgs() << "\n";
|
||||
Broken = true;
|
||||
}
|
||||
if (Broken)
|
||||
return abortIfBroken();
|
||||
}
|
||||
if (Broken)
|
||||
return abortIfBroken();
|
||||
|
||||
// Now directly compute a dominance tree. We don't rely on the pass
|
||||
// manager to provide this as it isolates us from a potentially
|
||||
// out-of-date dominator tree and makes it significantly more complex to
|
||||
// run this code outside of a pass manager.
|
||||
DT.recalculate(F);
|
||||
// Now directly compute a dominance tree. We don't rely on the pass
|
||||
// manager to provide this as it isolates us from a potentially
|
||||
// out-of-date dominator tree and makes it significantly more complex to
|
||||
// run this code outside of a pass manager.
|
||||
DT.recalculate(F);
|
||||
|
||||
Mod = F.getParent();
|
||||
if (!Context) Context = &F.getContext();
|
||||
M = F.getParent();
|
||||
if (!Context)
|
||||
Context = &F.getContext();
|
||||
|
||||
Finder.reset();
|
||||
visit(F);
|
||||
InstsInThisBlock.clear();
|
||||
PersonalityFn = 0;
|
||||
|
||||
if (!DisableDebugInfoVerifier)
|
||||
// Verify Debug Info.
|
||||
verifyDebugInfo();
|
||||
|
||||
// We must abort before returning back to the pass manager, or else the
|
||||
// pass manager may try to run other passes on the broken module.
|
||||
return abortIfBroken();
|
||||
}
|
||||
|
||||
bool doFinalization(Module &M) {
|
||||
// Scan through, checking all of the external function's linkage now...
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||
visitGlobalValue(*I);
|
||||
|
||||
// Check to make sure function prototypes are okay.
|
||||
if (I->isDeclaration())
|
||||
visitFunction(*I);
|
||||
}
|
||||
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I)
|
||||
visitGlobalVariable(*I);
|
||||
|
||||
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
|
||||
++I)
|
||||
visitGlobalAlias(*I);
|
||||
|
||||
for (Module::named_metadata_iterator I = M.named_metadata_begin(),
|
||||
E = M.named_metadata_end();
|
||||
I != E; ++I)
|
||||
visitNamedMDNode(*I);
|
||||
|
||||
visitModuleFlags(M);
|
||||
visitModuleIdents(M);
|
||||
|
||||
if (!DisableDebugInfoVerifier) {
|
||||
Finder.reset();
|
||||
visit(F);
|
||||
InstsInThisBlock.clear();
|
||||
PersonalityFn = 0;
|
||||
|
||||
if (!DisableDebugInfoVerifier)
|
||||
// Verify Debug Info.
|
||||
verifyDebugInfo();
|
||||
|
||||
// We must abort before returning back to the pass manager, or else the
|
||||
// pass manager may try to run other passes on the broken module.
|
||||
return abortIfBroken();
|
||||
Finder.processModule(M);
|
||||
// Verify Debug Info.
|
||||
verifyDebugInfo();
|
||||
}
|
||||
|
||||
bool doFinalization(Module &M) {
|
||||
// Scan through, checking all of the external function's linkage now...
|
||||
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
|
||||
visitGlobalValue(*I);
|
||||
// If the module is broken, abort at this time.
|
||||
return abortIfBroken();
|
||||
}
|
||||
|
||||
// Check to make sure function prototypes are okay.
|
||||
if (I->isDeclaration()) visitFunction(*I);
|
||||
}
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
}
|
||||
|
||||
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
|
||||
I != E; ++I)
|
||||
visitGlobalVariable(*I);
|
||||
|
||||
for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
|
||||
I != E; ++I)
|
||||
visitGlobalAlias(*I);
|
||||
|
||||
for (Module::named_metadata_iterator I = M.named_metadata_begin(),
|
||||
E = M.named_metadata_end(); I != E; ++I)
|
||||
visitNamedMDNode(*I);
|
||||
|
||||
visitModuleFlags(M);
|
||||
visitModuleIdents(M);
|
||||
|
||||
if (!DisableDebugInfoVerifier) {
|
||||
Finder.reset();
|
||||
Finder.processModule(M);
|
||||
// Verify Debug Info.
|
||||
verifyDebugInfo();
|
||||
}
|
||||
|
||||
// If the module is broken, abort at this time.
|
||||
return abortIfBroken();
|
||||
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
||||
/// this condition, do so.
|
||||
///
|
||||
bool abortIfBroken() {
|
||||
if (!Broken)
|
||||
return false;
|
||||
MessagesStr << "Broken module found, ";
|
||||
switch (Action) {
|
||||
case AbortProcessAction:
|
||||
MessagesStr << "compilation aborted!\n";
|
||||
dbgs() << MessagesStr.str();
|
||||
// Client should choose different reaction if abort is not desired
|
||||
abort();
|
||||
case PrintMessageAction:
|
||||
MessagesStr << "verification continues.\n";
|
||||
dbgs() << MessagesStr.str();
|
||||
return false;
|
||||
case ReturnStatusAction:
|
||||
MessagesStr << "compilation terminated.\n";
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Invalid action");
|
||||
}
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesAll();
|
||||
// Verification methods...
|
||||
void visitGlobalValue(GlobalValue &GV);
|
||||
void visitGlobalVariable(GlobalVariable &GV);
|
||||
void visitGlobalAlias(GlobalAlias &GA);
|
||||
void visitNamedMDNode(NamedMDNode &NMD);
|
||||
void visitMDNode(MDNode &MD, Function *F);
|
||||
void visitModuleIdents(Module &M);
|
||||
void visitModuleFlags(Module &M);
|
||||
void visitModuleFlag(MDNode *Op, DenseMap<MDString *, MDNode *> &SeenIDs,
|
||||
SmallVectorImpl<MDNode *> &Requirements);
|
||||
void visitFunction(Function &F);
|
||||
void visitBasicBlock(BasicBlock &BB);
|
||||
using InstVisitor<Verifier>::visit;
|
||||
|
||||
void visit(Instruction &I);
|
||||
|
||||
void visitTruncInst(TruncInst &I);
|
||||
void visitZExtInst(ZExtInst &I);
|
||||
void visitSExtInst(SExtInst &I);
|
||||
void visitFPTruncInst(FPTruncInst &I);
|
||||
void visitFPExtInst(FPExtInst &I);
|
||||
void visitFPToUIInst(FPToUIInst &I);
|
||||
void visitFPToSIInst(FPToSIInst &I);
|
||||
void visitUIToFPInst(UIToFPInst &I);
|
||||
void visitSIToFPInst(SIToFPInst &I);
|
||||
void visitIntToPtrInst(IntToPtrInst &I);
|
||||
void visitPtrToIntInst(PtrToIntInst &I);
|
||||
void visitBitCastInst(BitCastInst &I);
|
||||
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
|
||||
void visitPHINode(PHINode &PN);
|
||||
void visitBinaryOperator(BinaryOperator &B);
|
||||
void visitICmpInst(ICmpInst &IC);
|
||||
void visitFCmpInst(FCmpInst &FC);
|
||||
void visitExtractElementInst(ExtractElementInst &EI);
|
||||
void visitInsertElementInst(InsertElementInst &EI);
|
||||
void visitShuffleVectorInst(ShuffleVectorInst &EI);
|
||||
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
|
||||
void visitCallInst(CallInst &CI);
|
||||
void visitInvokeInst(InvokeInst &II);
|
||||
void visitGetElementPtrInst(GetElementPtrInst &GEP);
|
||||
void visitLoadInst(LoadInst &LI);
|
||||
void visitStoreInst(StoreInst &SI);
|
||||
void verifyDominatesUse(Instruction &I, unsigned i);
|
||||
void visitInstruction(Instruction &I);
|
||||
void visitTerminatorInst(TerminatorInst &I);
|
||||
void visitBranchInst(BranchInst &BI);
|
||||
void visitReturnInst(ReturnInst &RI);
|
||||
void visitSwitchInst(SwitchInst &SI);
|
||||
void visitIndirectBrInst(IndirectBrInst &BI);
|
||||
void visitSelectInst(SelectInst &SI);
|
||||
void visitUserOp1(Instruction &I);
|
||||
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
|
||||
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
|
||||
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
|
||||
void visitAtomicRMWInst(AtomicRMWInst &RMWI);
|
||||
void visitFenceInst(FenceInst &FI);
|
||||
void visitAllocaInst(AllocaInst &AI);
|
||||
void visitExtractValueInst(ExtractValueInst &EVI);
|
||||
void visitInsertValueInst(InsertValueInst &IVI);
|
||||
void visitLandingPadInst(LandingPadInst &LPI);
|
||||
|
||||
void VerifyCallSite(CallSite CS);
|
||||
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, int VT,
|
||||
unsigned ArgNo, std::string &Suffix);
|
||||
bool VerifyIntrinsicType(Type *Ty, ArrayRef<Intrinsic::IITDescriptor> &Infos,
|
||||
SmallVectorImpl<Type *> &ArgTys);
|
||||
bool VerifyIntrinsicIsVarArg(bool isVarArg,
|
||||
ArrayRef<Intrinsic::IITDescriptor> &Infos);
|
||||
bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
|
||||
void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx, bool isFunction,
|
||||
const Value *V);
|
||||
void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
|
||||
bool isReturnValue, const Value *V);
|
||||
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
const Value *V);
|
||||
|
||||
void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
|
||||
void VerifyConstantExprBitcastType(const ConstantExpr *CE);
|
||||
|
||||
void verifyDebugInfo();
|
||||
|
||||
void WriteValue(const Value *V) {
|
||||
if (!V)
|
||||
return;
|
||||
if (isa<Instruction>(V)) {
|
||||
MessagesStr << *V << '\n';
|
||||
} else {
|
||||
V->printAsOperand(MessagesStr, true, M);
|
||||
MessagesStr << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
/// abortIfBroken - If the module is broken and we are supposed to abort on
|
||||
/// this condition, do so.
|
||||
///
|
||||
bool abortIfBroken() {
|
||||
if (!Broken) return false;
|
||||
MessagesStr << "Broken module found, ";
|
||||
switch (action) {
|
||||
case AbortProcessAction:
|
||||
MessagesStr << "compilation aborted!\n";
|
||||
dbgs() << MessagesStr.str();
|
||||
// Client should choose different reaction if abort is not desired
|
||||
abort();
|
||||
case PrintMessageAction:
|
||||
MessagesStr << "verification continues.\n";
|
||||
dbgs() << MessagesStr.str();
|
||||
return false;
|
||||
case ReturnStatusAction:
|
||||
MessagesStr << "compilation terminated.\n";
|
||||
return true;
|
||||
}
|
||||
llvm_unreachable("Invalid action");
|
||||
}
|
||||
void WriteType(Type *T) {
|
||||
if (!T)
|
||||
return;
|
||||
MessagesStr << ' ' << *T;
|
||||
}
|
||||
|
||||
// CheckFailed - A check failed, so print out the condition and the message
|
||||
// that failed. This provides a nice place to put a breakpoint if you want
|
||||
// to see why something is not correct.
|
||||
void CheckFailed(const Twine &Message, const Value *V1 = 0,
|
||||
const Value *V2 = 0, const Value *V3 = 0,
|
||||
const Value *V4 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteValue(V1);
|
||||
WriteValue(V2);
|
||||
WriteValue(V3);
|
||||
WriteValue(V4);
|
||||
Broken = true;
|
||||
}
|
||||
|
||||
// Verification methods...
|
||||
void visitGlobalValue(GlobalValue &GV);
|
||||
void visitGlobalVariable(GlobalVariable &GV);
|
||||
void visitGlobalAlias(GlobalAlias &GA);
|
||||
void visitNamedMDNode(NamedMDNode &NMD);
|
||||
void visitMDNode(MDNode &MD, Function *F);
|
||||
void visitModuleIdents(Module &M);
|
||||
void visitModuleFlags(Module &M);
|
||||
void visitModuleFlag(MDNode *Op, DenseMap<MDString*, MDNode*> &SeenIDs,
|
||||
SmallVectorImpl<MDNode*> &Requirements);
|
||||
void visitFunction(Function &F);
|
||||
void visitBasicBlock(BasicBlock &BB);
|
||||
using InstVisitor<Verifier>::visit;
|
||||
void CheckFailed(const Twine &Message, const Value *V1, Type *T2,
|
||||
const Value *V3 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteValue(V1);
|
||||
WriteType(T2);
|
||||
WriteValue(V3);
|
||||
Broken = true;
|
||||
}
|
||||
|
||||
void visit(Instruction &I);
|
||||
|
||||
void visitTruncInst(TruncInst &I);
|
||||
void visitZExtInst(ZExtInst &I);
|
||||
void visitSExtInst(SExtInst &I);
|
||||
void visitFPTruncInst(FPTruncInst &I);
|
||||
void visitFPExtInst(FPExtInst &I);
|
||||
void visitFPToUIInst(FPToUIInst &I);
|
||||
void visitFPToSIInst(FPToSIInst &I);
|
||||
void visitUIToFPInst(UIToFPInst &I);
|
||||
void visitSIToFPInst(SIToFPInst &I);
|
||||
void visitIntToPtrInst(IntToPtrInst &I);
|
||||
void visitPtrToIntInst(PtrToIntInst &I);
|
||||
void visitBitCastInst(BitCastInst &I);
|
||||
void visitAddrSpaceCastInst(AddrSpaceCastInst &I);
|
||||
void visitPHINode(PHINode &PN);
|
||||
void visitBinaryOperator(BinaryOperator &B);
|
||||
void visitICmpInst(ICmpInst &IC);
|
||||
void visitFCmpInst(FCmpInst &FC);
|
||||
void visitExtractElementInst(ExtractElementInst &EI);
|
||||
void visitInsertElementInst(InsertElementInst &EI);
|
||||
void visitShuffleVectorInst(ShuffleVectorInst &EI);
|
||||
void visitVAArgInst(VAArgInst &VAA) { visitInstruction(VAA); }
|
||||
void visitCallInst(CallInst &CI);
|
||||
void visitInvokeInst(InvokeInst &II);
|
||||
void visitGetElementPtrInst(GetElementPtrInst &GEP);
|
||||
void visitLoadInst(LoadInst &LI);
|
||||
void visitStoreInst(StoreInst &SI);
|
||||
void verifyDominatesUse(Instruction &I, unsigned i);
|
||||
void visitInstruction(Instruction &I);
|
||||
void visitTerminatorInst(TerminatorInst &I);
|
||||
void visitBranchInst(BranchInst &BI);
|
||||
void visitReturnInst(ReturnInst &RI);
|
||||
void visitSwitchInst(SwitchInst &SI);
|
||||
void visitIndirectBrInst(IndirectBrInst &BI);
|
||||
void visitSelectInst(SelectInst &SI);
|
||||
void visitUserOp1(Instruction &I);
|
||||
void visitUserOp2(Instruction &I) { visitUserOp1(I); }
|
||||
void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
|
||||
void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
|
||||
void visitAtomicRMWInst(AtomicRMWInst &RMWI);
|
||||
void visitFenceInst(FenceInst &FI);
|
||||
void visitAllocaInst(AllocaInst &AI);
|
||||
void visitExtractValueInst(ExtractValueInst &EVI);
|
||||
void visitInsertValueInst(InsertValueInst &IVI);
|
||||
void visitLandingPadInst(LandingPadInst &LPI);
|
||||
|
||||
void VerifyCallSite(CallSite CS);
|
||||
bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty,
|
||||
int VT, unsigned ArgNo, std::string &Suffix);
|
||||
bool VerifyIntrinsicType(Type *Ty,
|
||||
ArrayRef<Intrinsic::IITDescriptor> &Infos,
|
||||
SmallVectorImpl<Type*> &ArgTys);
|
||||
bool VerifyIntrinsicIsVarArg(bool isVarArg,
|
||||
ArrayRef<Intrinsic::IITDescriptor> &Infos);
|
||||
bool VerifyAttributeCount(AttributeSet Attrs, unsigned Params);
|
||||
void VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
|
||||
bool isFunction, const Value *V);
|
||||
void VerifyParameterAttrs(AttributeSet Attrs, unsigned Idx, Type *Ty,
|
||||
bool isReturnValue, const Value *V);
|
||||
void VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
|
||||
const Value *V);
|
||||
|
||||
void VerifyBitcastType(const Value *V, Type *DestTy, Type *SrcTy);
|
||||
void VerifyConstantExprBitcastType(const ConstantExpr *CE);
|
||||
|
||||
void verifyDebugInfo();
|
||||
|
||||
void WriteValue(const Value *V) {
|
||||
if (!V) return;
|
||||
if (isa<Instruction>(V)) {
|
||||
MessagesStr << *V << '\n';
|
||||
} else {
|
||||
V->printAsOperand(MessagesStr, true, Mod);
|
||||
MessagesStr << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void WriteType(Type *T) {
|
||||
if (!T) return;
|
||||
MessagesStr << ' ' << *T;
|
||||
}
|
||||
|
||||
|
||||
// CheckFailed - A check failed, so print out the condition and the message
|
||||
// that failed. This provides a nice place to put a breakpoint if you want
|
||||
// to see why something is not correct.
|
||||
void CheckFailed(const Twine &Message,
|
||||
const Value *V1 = 0, const Value *V2 = 0,
|
||||
const Value *V3 = 0, const Value *V4 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteValue(V1);
|
||||
WriteValue(V2);
|
||||
WriteValue(V3);
|
||||
WriteValue(V4);
|
||||
Broken = true;
|
||||
}
|
||||
|
||||
void CheckFailed(const Twine &Message, const Value *V1,
|
||||
Type *T2, const Value *V3 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteValue(V1);
|
||||
WriteType(T2);
|
||||
WriteValue(V3);
|
||||
Broken = true;
|
||||
}
|
||||
|
||||
void CheckFailed(const Twine &Message, Type *T1,
|
||||
Type *T2 = 0, Type *T3 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteType(T1);
|
||||
WriteType(T2);
|
||||
WriteType(T3);
|
||||
Broken = true;
|
||||
}
|
||||
};
|
||||
void CheckFailed(const Twine &Message, Type *T1, Type *T2 = 0, Type *T3 = 0) {
|
||||
MessagesStr << Message.str() << "\n";
|
||||
WriteType(T1);
|
||||
WriteType(T2);
|
||||
WriteType(T3);
|
||||
Broken = true;
|
||||
}
|
||||
};
|
||||
} // End anonymous namespace
|
||||
|
||||
char Verifier::ID = 0;
|
||||
@ -2064,7 +2067,7 @@ void Verifier::visitInstruction(Instruction &I) {
|
||||
Assert1(!F->isIntrinsic() || isa<CallInst>(I) ||
|
||||
F->getIntrinsicID() == Intrinsic::donothing,
|
||||
"Cannot invoke an intrinsinc other than donothing", &I);
|
||||
Assert1(F->getParent() == Mod, "Referencing function in another module!",
|
||||
Assert1(F->getParent() == M, "Referencing function in another module!",
|
||||
&I);
|
||||
} else if (BasicBlock *OpBB = dyn_cast<BasicBlock>(I.getOperand(i))) {
|
||||
Assert1(OpBB->getParent() == BB->getParent(),
|
||||
@ -2073,7 +2076,7 @@ void Verifier::visitInstruction(Instruction &I) {
|
||||
Assert1(OpArg->getParent() == BB->getParent(),
|
||||
"Referring to an argument in another function!", &I);
|
||||
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(I.getOperand(i))) {
|
||||
Assert1(GV->getParent() == Mod, "Referencing global in another module!",
|
||||
Assert1(GV->getParent() == M, "Referencing global in another module!",
|
||||
&I);
|
||||
} else if (isa<Instruction>(I.getOperand(i))) {
|
||||
verifyDominatesUse(I, i);
|
||||
@ -2124,7 +2127,7 @@ void Verifier::visitInstruction(Instruction &I) {
|
||||
|
||||
if (!DisableDebugInfoVerifier) {
|
||||
MD = I.getMetadata(LLVMContext::MD_dbg);
|
||||
Finder.processLocation(*Mod, DILocation(MD));
|
||||
Finder.processLocation(*M, DILocation(MD));
|
||||
}
|
||||
|
||||
InstsInThisBlock.insert(&I);
|
||||
@ -2302,13 +2305,13 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
|
||||
Assert1(MD->getNumOperands() == 1,
|
||||
"invalid llvm.dbg.declare intrinsic call 2", &CI);
|
||||
if (!DisableDebugInfoVerifier)
|
||||
Finder.processDeclare(*Mod, cast<DbgDeclareInst>(&CI));
|
||||
Finder.processDeclare(*M, cast<DbgDeclareInst>(&CI));
|
||||
} break;
|
||||
case Intrinsic::dbg_value: { //llvm.dbg.value
|
||||
if (!DisableDebugInfoVerifier) {
|
||||
Assert1(CI.getArgOperand(0) && isa<MDNode>(CI.getArgOperand(0)),
|
||||
"invalid llvm.dbg.value intrinsic call 1", &CI);
|
||||
Finder.processValue(*Mod, cast<DbgValueInst>(&CI));
|
||||
Finder.processValue(*M, cast<DbgValueInst>(&CI));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2403,12 +2406,8 @@ FunctionPass *llvm::createVerifierPass(VerifierFailureAction action) {
|
||||
return new Verifier(action);
|
||||
}
|
||||
|
||||
|
||||
/// verifyFunction - Check a function for errors, printing messages on stderr.
|
||||
/// Return true if the function is corrupt.
|
||||
///
|
||||
bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
|
||||
Function &F = const_cast<Function&>(f);
|
||||
Function &F = const_cast<Function &>(f);
|
||||
assert(!F.isDeclaration() && "Cannot verify external functions");
|
||||
|
||||
FunctionPassManager FPM(F.getParent());
|
||||
@ -2419,15 +2418,12 @@ bool llvm::verifyFunction(const Function &f, VerifierFailureAction action) {
|
||||
return V->Broken;
|
||||
}
|
||||
|
||||
/// verifyModule - Check a module for errors, printing messages on stderr.
|
||||
/// Return true if the module is corrupt.
|
||||
///
|
||||
bool llvm::verifyModule(const Module &M, VerifierFailureAction action,
|
||||
std::string *ErrorInfo) {
|
||||
PassManager PM;
|
||||
Verifier *V = new Verifier(action);
|
||||
PM.add(V);
|
||||
PM.run(const_cast<Module&>(M));
|
||||
PM.run(const_cast<Module &>(M));
|
||||
|
||||
if (ErrorInfo && V->Broken)
|
||||
*ErrorInfo = V->MessagesStr.str();
|
||||
|
Loading…
Reference in New Issue
Block a user