Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -85,8 +85,10 @@ namespace { struct VerifierSupport { raw_ostream *OS; - const Module *M = nullptr; - Optional MST; + const Module *M; + ModuleSlotTracker MST; + const DataLayout &DL; + LLVMContext *Context; /// Track the brokenness of the module while recursively visiting. bool Broken = false; @@ -95,7 +97,9 @@ /// Whether to treat broken debug info as an error. bool TreatBrokenDebugInfoAsError = true; - explicit VerifierSupport(raw_ostream *OS) : OS(OS) {} + explicit VerifierSupport(raw_ostream *OS, const Module *M) + : OS(OS), M(M), MST(M), DL(M->getDataLayout()), + Context(&M->getContext()) {} private: template void Write(const ilist_iterator &I) { @@ -112,10 +116,10 @@ if (!V) return; if (isa(V)) { - V->print(*OS, *MST); + V->print(*OS, MST); *OS << '\n'; } else { - V->printAsOperand(*OS, true, *MST); + V->printAsOperand(*OS, true, MST); *OS << '\n'; } } @@ -126,7 +130,7 @@ void Write(const Metadata *MD) { if (!MD) return; - MD->print(*OS, *MST, M); + MD->print(*OS, MST, M); *OS << '\n'; } @@ -137,7 +141,7 @@ void Write(const NamedMDNode *NMD) { if (!NMD) return; - NMD->print(*OS, *MST); + NMD->print(*OS, MST); *OS << '\n'; } @@ -209,7 +213,6 @@ class Verifier : public InstVisitor, VerifierSupport { friend class InstVisitor; - LLVMContext *Context; DominatorTree DT; /// \brief When verifying a basic block, keep track of all of the @@ -252,19 +255,12 @@ // constant expressions, we can arrive at a particular user many times. SmallPtrSet GlobalValueVisited; - void checkAtomicMemAccessSize(const Module *M, Type *Ty, - const Instruction *I); - - void updateModule(const Module *NewM) { - if (M == NewM) - return; - MST.emplace(NewM); - M = NewM; - } + void checkAtomicMemAccessSize(Type *Ty, const Instruction *I); public: - explicit Verifier(raw_ostream *OS, bool ShouldTreatBrokenDebugInfoAsError) - : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr), + explicit Verifier(raw_ostream *OS, bool ShouldTreatBrokenDebugInfoAsError, + const Module *M) + : VerifierSupport(OS, M), LandingPadResultTy(nullptr), SawFrameEscape(false) { TreatBrokenDebugInfoAsError = ShouldTreatBrokenDebugInfoAsError; } @@ -272,8 +268,8 @@ bool hasBrokenDebugInfo() const { return BrokenDebugInfo; } bool verify(const Function &F) { - updateModule(F.getParent()); - Context = &M->getContext(); + assert(F.getParent() == M && + "An instance of this class only works with a specific module!"); // First ensure the function is well-enough formed to compute dominance // information, and directly compute a dominance tree. We don't rely on the @@ -291,7 +287,7 @@ if (OS) { *OS << "Basic Block in function '" << F.getName() << "' does not have terminator!\n"; - BB.printAsOperand(*OS, true, *MST); + BB.printAsOperand(*OS, true, MST); *OS << "\n"; } return false; @@ -309,33 +305,33 @@ return !Broken; } - bool verify(const Module &M) { - updateModule(&M); - Context = &M.getContext(); + + /// Verify the module that this instance of \c Verifier was initialized with. + bool verify() { Broken = false; // Collect all declarations of the llvm.experimental.deoptimize intrinsic. - for (const Function &F : M) + for (const Function &F : *M) if (F.getIntrinsicID() == Intrinsic::experimental_deoptimize) DeoptimizeDeclarations.push_back(&F); // Now that we've visited every function, verify that we never asked to // recover a frame index that wasn't escaped. verifyFrameRecoverIndices(); - for (const GlobalVariable &GV : M.globals()) + for (const GlobalVariable &GV : M->globals()) visitGlobalVariable(GV); - for (const GlobalAlias &GA : M.aliases()) + for (const GlobalAlias &GA : M->aliases()) visitGlobalAlias(GA); - for (const NamedMDNode &NMD : M.named_metadata()) + for (const NamedMDNode &NMD : M->named_metadata()) visitNamedMDNode(NMD); - for (const StringMapEntry &SMEC : M.getComdatSymbolTable()) + for (const StringMapEntry &SMEC : M->getComdatSymbolTable()) visitComdat(SMEC.getValue()); - visitModuleFlags(M); - visitModuleIdents(M); + visitModuleFlags(*M); + visitModuleIdents(*M); verifyCompileUnits(); @@ -2412,7 +2408,7 @@ "PtrToInt source must be pointer", &I); if (auto *PTy = dyn_cast(SrcTy->getScalarType())) - Assert(!M->getDataLayout().isNonIntegralPointerType(PTy), + Assert(!DL.isNonIntegralPointerType(PTy), "ptrtoint not supported for non-integral pointers"); Assert(DestTy->getScalarType()->isIntegerTy(), @@ -2441,7 +2437,7 @@ "IntToPtr result must be a pointer", &I); if (auto *PTy = dyn_cast(DestTy->getScalarType())) - Assert(!M->getDataLayout().isNonIntegralPointerType(PTy), + Assert(!DL.isNonIntegralPointerType(PTy), "inttoptr not supported for non-integral pointers"); Assert(SrcTy->isVectorTy() == DestTy->isVectorTy(), "IntToPtr type mismatch", @@ -2976,9 +2972,8 @@ } } -void Verifier::checkAtomicMemAccessSize(const Module *M, Type *Ty, - const Instruction *I) { - unsigned Size = M->getDataLayout().getTypeSizeInBits(Ty); +void Verifier::checkAtomicMemAccessSize(Type *Ty, const Instruction *I) { + unsigned Size = DL.getTypeSizeInBits(Ty); Assert(Size >= 8, "atomic memory access' size must be byte-sized", Ty, I); Assert(!(Size & (Size - 1)), "atomic memory access' operand must have a power-of-two size", Ty, I); @@ -3002,7 +2997,7 @@ "atomic load operand must have integer, pointer, or floating point " "type!", ElTy, &LI); - checkAtomicMemAccessSize(M, ElTy, &LI); + checkAtomicMemAccessSize(ElTy, &LI); } else { Assert(LI.getSynchScope() == CrossThread, "Non-atomic load cannot have SynchronizationScope specified", &LI); @@ -3031,7 +3026,7 @@ "atomic store operand must have integer, pointer, or floating point " "type!", ElTy, &SI); - checkAtomicMemAccessSize(M, ElTy, &SI); + checkAtomicMemAccessSize(ElTy, &SI); } else { Assert(SI.getSynchScope() == CrossThread, "Non-atomic store cannot have SynchronizationScope specified", &SI); @@ -3120,7 +3115,7 @@ Assert(ElTy->isIntegerTy() || ElTy->isPointerTy(), "cmpxchg operand must have integer or pointer type", ElTy, &CXI); - checkAtomicMemAccessSize(M, ElTy, &CXI); + checkAtomicMemAccessSize(ElTy, &CXI); Assert(ElTy == CXI.getOperand(1)->getType(), "Expected value type does not match pointer operand type!", &CXI, ElTy); @@ -3139,7 +3134,7 @@ Type *ElTy = PTy->getElementType(); Assert(ElTy->isIntegerTy(), "atomicrmw operand must have integer type!", &RMWI, ElTy); - checkAtomicMemAccessSize(M, ElTy, &RMWI); + checkAtomicMemAccessSize(ElTy, &RMWI); Assert(ElTy == RMWI.getOperand(1)->getType(), "Argument value type does not match pointer operand type!", &RMWI, ElTy); @@ -4311,7 +4306,7 @@ Function &F = const_cast(f); // Don't use a raw_null_ostream. Printing IR is expensive. - Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true); + Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true, f.getParent()); // Note that this function's return value is inverted from what you would // expect of a function called "verify". @@ -4321,13 +4316,13 @@ bool llvm::verifyModule(const Module &M, raw_ostream *OS, bool *BrokenDebugInfo) { // Don't use a raw_null_ostream. Printing IR is expensive. - Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/!BrokenDebugInfo); + Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/!BrokenDebugInfo, &M); bool Broken = false; for (const Function &F : M) Broken |= !V.verify(F); - Broken |= !V.verify(M); + Broken |= !V.verify(); if (BrokenDebugInfo) *BrokenDebugInfo = V.hasBrokenDebugInfo(); // Note that this function's return value is inverted from what you would @@ -4339,23 +4334,27 @@ struct VerifierLegacyPass : public FunctionPass { static char ID; - Verifier V; + std::unique_ptr V; bool FatalErrors = true; VerifierLegacyPass() - : FunctionPass(ID), - V(&dbgs(), /*ShouldTreatBrokenDebugInfoAsError=*/false) { + : FunctionPass(ID) { initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); } explicit VerifierLegacyPass(bool FatalErrors) : FunctionPass(ID), - V(&dbgs(), /*ShouldTreatBrokenDebugInfoAsError=*/false), FatalErrors(FatalErrors) { initializeVerifierLegacyPassPass(*PassRegistry::getPassRegistry()); } + bool doInitialization(Module &M) override { + V = llvm::make_unique( + &dbgs(), /*ShouldTreatBrokenDebugInfoAsError=*/false, &M); + return false; + } + bool runOnFunction(Function &F) override { - if (!V.verify(F) && FatalErrors) + if (!V->verify(F) && FatalErrors) report_fatal_error("Broken function found, compilation aborted!"); return false; @@ -4365,17 +4364,17 @@ bool HasErrors = false; for (Function &F : M) if (F.isDeclaration()) - HasErrors |= !V.verify(F); + HasErrors |= !V->verify(F); - HasErrors |= !V.verify(M); + HasErrors |= !V->verify(); if (FatalErrors) { if (HasErrors) report_fatal_error("Broken module found, compilation aborted!"); - assert(!V.hasBrokenDebugInfo() && "Module contains invalid debug info"); + assert(!V->hasBrokenDebugInfo() && "Module contains invalid debug info"); } // Strip broken debug info. - if (V.hasBrokenDebugInfo()) { + if (V->hasBrokenDebugInfo()) { DiagnosticInfoIgnoringInvalidDebugMetadata DiagInvalid(M); M.getContext().diagnose(DiagInvalid); if (!StripDebugInfo(M))