Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -85,8 +85,8 @@ namespace { struct VerifierSupport { raw_ostream *OS; - const Module *M = nullptr; - Optional MST; + const Module *M; + ModuleSlotTracker MST; /// Track the brokenness of the module while recursively visiting. bool Broken = false; @@ -95,7 +95,8 @@ /// 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) {} private: template void Write(const ilist_iterator &I) { @@ -112,10 +113,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 +127,7 @@ void Write(const Metadata *MD) { if (!MD) return; - MD->print(*OS, *MST, M); + MD->print(*OS, MST, M); *OS << '\n'; } @@ -137,7 +138,7 @@ void Write(const NamedMDNode *NMD) { if (!NMD) return; - NMD->print(*OS, *MST); + NMD->print(*OS, MST); *OS << '\n'; } @@ -255,16 +256,10 @@ void checkAtomicMemAccessSize(const Module *M, Type *Ty, const Instruction *I); - void updateModule(const Module *NewM) { - if (M == NewM) - return; - MST.emplace(NewM); - M = NewM; - } - 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), Context(nullptr), LandingPadResultTy(nullptr), SawFrameEscape(false) { TreatBrokenDebugInfoAsError = ShouldTreatBrokenDebugInfoAsError; } @@ -272,7 +267,8 @@ bool hasBrokenDebugInfo() const { return BrokenDebugInfo; } bool verify(const Function &F) { - updateModule(F.getParent()); + assert(F.getParent() == M && + "An instance of this class only works with a specific module!"); Context = &M->getContext(); // First ensure the function is well-enough formed to compute dominance @@ -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; @@ -310,7 +306,8 @@ } bool verify(const Module &M) { - updateModule(&M); + assert(&M == this->M && + "An instance of this class only works with a specific module!"); Context = &M.getContext(); Broken = false; @@ -4311,7 +4308,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,7 +4318,7 @@ 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) @@ -4339,23 +4336,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 +4366,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(M); 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))