Index: include/llvm/Pass.h =================================================================== --- include/llvm/Pass.h +++ include/llvm/Pass.h @@ -82,16 +82,21 @@ AnalysisResolver *Resolver; // Used to resolve analysis const void *PassID; PassKind Kind; + bool Unavailable; void operator=(const Pass&) = delete; Pass(const Pass &) = delete; public: explicit Pass(PassKind K, char &pid) - : Resolver(nullptr), PassID(&pid), Kind(K) { } + : Resolver(nullptr), PassID(&pid), Kind(K), Unavailable(false) { } virtual ~Pass(); - PassKind getPassKind() const { return Kind; } + bool isAvailable() const { return !Unavailable; } + + /// Sets a flag to indicates that the pass does not have results, either + /// because it was skipped or is already freed. + void markUnavailable(bool x = true) { Unavailable = x; } /// getPassName - Return a nice clean name for a pass. This usually /// implemented in terms of the name that is registered by one of the @@ -316,8 +321,9 @@ protected: /// Optional passes call this function to check whether the pass should be /// skipped. This is the case when Attribute::OptimizeNone is set or when - /// optimization bisect is over the limit. - bool skipFunction(const Function &F) const; + /// optimization bisect is over the limit. It also sets flag Unavailable on + /// the pass. + bool skipFunction(const Function &F); }; Index: lib/CodeGen/MachineDominators.cpp =================================================================== --- lib/CodeGen/MachineDominators.cpp +++ lib/CodeGen/MachineDominators.cpp @@ -69,7 +69,7 @@ } void MachineDominatorTree::verifyAnalysis() const { - if (VerifyMachineDomInfo) + if (VerifyMachineDomInfo && isAvailable()) verifyDomTree(); } Index: lib/CodeGen/MachineFunctionPass.cpp =================================================================== --- lib/CodeGen/MachineFunctionPass.cpp +++ lib/CodeGen/MachineFunctionPass.cpp @@ -38,8 +38,10 @@ bool MachineFunctionPass::runOnFunction(Function &F) { // Do not codegen any 'available_externally' functions at all, they have // definitions outside the translation unit. - if (F.hasAvailableExternallyLinkage()) + if (F.hasAvailableExternallyLinkage()) { + markUnavailable(); return false; + } MachineModuleInfo &MMI = getAnalysis(); MachineFunction &MF = MMI.getMachineFunction(F); Index: lib/IR/Pass.cpp =================================================================== --- lib/IR/Pass.cpp +++ lib/IR/Pass.cpp @@ -146,13 +146,16 @@ return PMT_FunctionPassManager; } -bool FunctionPass::skipFunction(const Function &F) const { - if (!F.getContext().getOptBisect().shouldRunPass(this, F)) +bool FunctionPass::skipFunction(const Function &F) { + if (!F.getContext().getOptBisect().shouldRunPass(this, F)) { + markUnavailable(); return true; + } if (F.hasFnAttribute(Attribute::OptimizeNone)) { DEBUG(dbgs() << "Skipping pass '" << getPassName() << "' on function " << F.getName() << "\n"); + markUnavailable(); return true; } return false; Index: test/CodeGen/Generic/externally_available.ll =================================================================== --- test/CodeGen/Generic/externally_available.ll +++ test/CodeGen/Generic/externally_available.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | not grep test_ +; RUN: llc -verify-machine-dom-info < %s | not grep test_ ; test_function should not be emitted to the .s file. define available_externally i32 @test_function() {