From 825488c539aca77a4e2adb6155fba2f19495fddd Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Fri, 17 Jan 2014 11:09:34 +0000 Subject: [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 --- lib/IR/Verifier.cpp | 542 ++++++++++++++++++++++++++-------------------------- 1 file changed, 269 insertions(+), 273 deletions(-) (limited to 'lib/IR/Verifier.cpp') diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 0868ef8fab..a004955e80 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -80,293 +80,296 @@ static cl::opt DisableDebugInfoVerifier("disable-debug-info-verifier", cl::init(true)); namespace { - struct Verifier : public FunctionPass, public InstVisitor { - 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; - - std::string Messages; - raw_string_ostream MessagesStr; - - /// 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 InstsInThisBlock; - - /// MDNodes - keep track of the metadata nodes that have been checked - /// already. - SmallPtrSet MDNodes; - - /// PersonalityFn - The personality function referenced by the - /// LandingPadInsts. All LandingPadInsts within the same function must use - /// the same personality function. - const Value *PersonalityFn; - - /// Finder keeps track of all debug info MDNodes in a Module. - DebugInfoFinder Finder; - - 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()); - } +struct Verifier : public FunctionPass, public InstVisitor { + static char ID; + + // What to do if verification fails. + VerifierFailureAction Action; + + Module *M; + LLVMContext *Context; + const DataLayout *DL; + DominatorTree DT; + + bool Broken; + std::string Messages; + raw_string_ostream MessagesStr; + + /// \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 InstsInThisBlock; + + /// \brief Keep track of the metadata nodes that have been checked already. + SmallPtrSet MDNodes; + + /// \brief The personality function referenced by the LandingPadInsts. + /// All LandingPadInsts within the same function must use the same + /// personality function. + const Value *PersonalityFn; + + /// \brief Finder keeps track of all debug info MDNodes in a Module. + DebugInfoFinder Finder; + + 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()); + } - bool doInitialization(Module &M) { - Mod = &M; - Context = &M.getContext(); + bool doInitialization(Module &M) { + this->M = &M; + Context = &M.getContext(); - DL = getAnalysisIfAvailable(); + DL = getAnalysisIfAvailable(); - // 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(); - } + // 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; - } + 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(); - - // 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(); + } + if (Broken) + return abortIfBroken(); - Finder.reset(); - visit(F); - InstsInThisBlock.clear(); - PersonalityFn = 0; + // 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); - if (!DisableDebugInfoVerifier) - // Verify Debug Info. - verifyDebugInfo(); + M = F.getParent(); + if (!Context) + Context = &F.getContext(); - // 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.reset(); + visit(F); + InstsInThisBlock.clear(); + PersonalityFn = 0; - 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 (!DisableDebugInfoVerifier) + // Verify Debug Info. + verifyDebugInfo(); - // Check to make sure function prototypes are okay. - if (I->isDeclaration()) visitFunction(*I); - } + // 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(); + } - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - visitGlobalVariable(*I); + 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); - for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); - I != E; ++I) - visitGlobalAlias(*I); + // Check to make sure function prototypes are okay. + if (I->isDeclaration()) + visitFunction(*I); + } - for (Module::named_metadata_iterator I = M.named_metadata_begin(), - E = M.named_metadata_end(); I != E; ++I) - visitNamedMDNode(*I); + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) + visitGlobalVariable(*I); - visitModuleFlags(M); - visitModuleIdents(M); + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; + ++I) + visitGlobalAlias(*I); - if (!DisableDebugInfoVerifier) { - Finder.reset(); - Finder.processModule(M); - // Verify Debug Info. - verifyDebugInfo(); - } + for (Module::named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); + I != E; ++I) + visitNamedMDNode(*I); - // If the module is broken, abort at this time. - return abortIfBroken(); - } + visitModuleFlags(M); + visitModuleIdents(M); - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); + if (!DisableDebugInfoVerifier) { + Finder.reset(); + Finder.processModule(M); + // Verify Debug Info. + verifyDebugInfo(); } - /// 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"); - } + // If the module is broken, abort at this time. + return abortIfBroken(); + } + 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 &SeenIDs, - SmallVectorImpl &Requirements); - void visitFunction(Function &F); - void visitBasicBlock(BasicBlock &BB); - using InstVisitor::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 &Infos, - SmallVectorImpl &ArgTys); - bool VerifyIntrinsicIsVarArg(bool isVarArg, - ArrayRef &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(V)) { - MessagesStr << *V << '\n'; - } else { - V->printAsOperand(MessagesStr, true, Mod); - 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; + // 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 &SeenIDs, + SmallVectorImpl &Requirements); + void visitFunction(Function &F); + void visitBasicBlock(BasicBlock &BB); + using InstVisitor::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 &Infos, + SmallVectorImpl &ArgTys); + bool VerifyIntrinsicIsVarArg(bool isVarArg, + ArrayRef &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(V)) { + MessagesStr << *V << '\n'; + } else { + V->printAsOperand(MessagesStr, true, M); + 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; - } + // 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, 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(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(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(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(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(&CI)); + Finder.processDeclare(*M, cast(&CI)); } break; case Intrinsic::dbg_value: { //llvm.dbg.value if (!DisableDebugInfoVerifier) { Assert1(CI.getArgOperand(0) && isa(CI.getArgOperand(0)), "invalid llvm.dbg.value intrinsic call 1", &CI); - Finder.processValue(*Mod, cast(&CI)); + Finder.processValue(*M, cast(&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(f); + Function &F = const_cast(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(M)); + PM.run(const_cast(M)); if (ErrorInfo && V->Broken) *ErrorInfo = V->MessagesStr.str(); -- cgit v1.2.3