yrouban created this revision.
yrouban added reviewers: skatkov, kuhar, asbirlea, fedor.sergeev.
Herald added subscribers: cfe-commits, wenlei, steven_wu, hiraditya.
Herald added projects: clang, LLVM.
yrouban requested review of this revision.

Please see the reason for this redesign in the patch D91324 
<https://reviews.llvm.org/D91324>.
Basically the checker introduces an internal custom CFG analysis that tracks 
current up-to date CFG snapshot. The analysis is invalidated along with any 
other CFG related analysis (the key is //CFGAnalyses//). If the CFG analysis is 
not invalidated at a functional pass exit then the checker asserts that the CFG 
snapshot taken from this analysis is equals to a snapshot of the current CFG.

Along the way:

- the function //CFG::printDiff()// is simplified by removing function name 
calculation. The name is printed by the caller;
- fixed CFG invalidated condition (see //CFG::invalidate()//);
- //StandardInstrumentations::registerCallbacks()// gets additional optional 
parameter of type //FunctionAnalysisManager*//, which is needed by the checker 
to get the custom CFG analysis;
- several PM related tests updated to ignore lines related to running the 
custom CFG analysis.

This patch is safe to land as the CFGChecker is left switched off (the options 
//-verify-cfg-preserved// is false by default). It will be switched on by a 
separate patch to minimize possible reverts.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D91327

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  llvm/include/llvm/Passes/StandardInstrumentations.h
  llvm/lib/LTO/LTOBackend.cpp
  llvm/lib/Passes/StandardInstrumentations.cpp
  llvm/test/Other/loop-pm-invalidation.ll
  llvm/test/Other/new-pass-manager.ll
  llvm/test/Other/new-pm-defaults.ll
  llvm/test/Other/new-pm-lto-defaults.ll
  llvm/test/Other/new-pm-thinlto-defaults.ll
  llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
  llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
  llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
  llvm/test/Transforms/LoopRotate/pr35210.ll
  llvm/test/Transforms/SCCP/ipsccp-preserve-analysis.ll
  llvm/tools/opt/NewPMDriver.cpp
  llvm/unittests/IR/PassManagerTest.cpp

Index: llvm/unittests/IR/PassManagerTest.cpp
===================================================================
--- llvm/unittests/IR/PassManagerTest.cpp
+++ llvm/unittests/IR/PassManagerTest.cpp
@@ -826,7 +826,7 @@
   FunctionPassManager FPM(/*DebugLogging*/ true);
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(/*DebugLogging*/ true);
-  SI.registerCallbacks(PIC);
+  SI.registerCallbacks(PIC, &FAM);
   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
   FAM.registerPass([&] { return AssumptionAnalysis(); });
   FAM.registerPass([&] { return TargetIRAnalysis(); });
@@ -871,7 +871,7 @@
   FunctionPassManager FPM(/*DebugLogging*/ true);
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(/*DebugLogging*/ true);
-  SI.registerCallbacks(PIC);
+  SI.registerCallbacks(PIC, &FAM);
   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
   FAM.registerPass([&] { return AssumptionAnalysis(); });
   FAM.registerPass([&] { return TargetIRAnalysis(); });
@@ -935,7 +935,7 @@
   FunctionPassManager FPM(/*DebugLogging*/ true);
   PassInstrumentationCallbacks PIC;
   StandardInstrumentations SI(/*DebugLogging*/ true);
-  SI.registerCallbacks(PIC);
+  SI.registerCallbacks(PIC, &FAM);
   FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); });
   FAM.registerPass([&] { return AssumptionAnalysis(); });
   FAM.registerPass([&] { return TargetIRAnalysis(); });
Index: llvm/tools/opt/NewPMDriver.cpp
===================================================================
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -258,8 +258,6 @@
     }
   }
   PassInstrumentationCallbacks PIC;
-  StandardInstrumentations SI(DebugPM, VerifyEachPass);
-  SI.registerCallbacks(PIC);
   DebugifyEachInstrumentation Debugify;
   if (DebugifyEach)
     Debugify.registerCallbacks(PIC);
@@ -360,6 +358,9 @@
   CGSCCAnalysisManager CGAM(DebugPM);
   ModuleAnalysisManager MAM(DebugPM);
 
+  StandardInstrumentations SI(DebugPM, VerifyEachPass);
+  SI.registerCallbacks(PIC, &FAM);
+
   // Register the AA manager first so that our version is the one used.
   FAM.registerPass([&] { return std::move(AA); });
   // Register our TargetLibraryInfoImpl.
Index: llvm/test/Transforms/SCCP/ipsccp-preserve-analysis.ll
===================================================================
--- llvm/test/Transforms/SCCP/ipsccp-preserve-analysis.ll
+++ llvm/test/Transforms/SCCP/ipsccp-preserve-analysis.ll
@@ -16,7 +16,7 @@
 ; NEW-PM: Running pass: IPSCCPPass
 ; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f1
 ; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f2
-; NEW-PM-NOT: Running analysis:
+; NEW-PM-NOT: Running analysis: AssumptionAnalysis
 
 ; IR-LABEL: @f1
 ; IR-LABEL: entry:
Index: llvm/test/Transforms/LoopRotate/pr35210.ll
===================================================================
--- llvm/test/Transforms/LoopRotate/pr35210.ll
+++ llvm/test/Transforms/LoopRotate/pr35210.ll
@@ -24,9 +24,9 @@
 ; CHECK-NEXT: Running pass: LoopRotatePass on Loop at depth 1 containing: %bb<header><exiting>,%bb4<latch>
 ; CHECK-NEXT: Folding loop latch bb4 into bb
 ; CHECK-NEXT: Finished Loop pass manager run.
-; CHECK-NEXT: Invalidating analysis: PostDominatorTreeAnalysis on f
+; CHECK:      Invalidating analysis: PostDominatorTreeAnalysis on f
 ; CHECK-NEXT: Running pass: ADCEPass on f
-; CHECK-NEXT: Running analysis: PostDominatorTreeAnalysis on f
+; CHECK:      Running analysis: PostDominatorTreeAnalysis on f
 ; CHECK-NEXT: Finished llvm::Function pass manager run.
 
 ; MSSA: Starting llvm::Function pass manager run.
@@ -49,9 +49,9 @@
 ; MSSA-NEXT: Running pass: LoopRotatePass on Loop at depth 1 containing: %bb<header><exiting>,%bb4<latch>
 ; MSSA-NEXT: Folding loop latch bb4 into bb
 ; MSSA-NEXT: Finished Loop pass manager run.
-; MSSA-NEXT: Invalidating analysis: PostDominatorTreeAnalysis on f
+; MSSA:      Invalidating analysis: PostDominatorTreeAnalysis on f
 ; MSSA-NEXT: Running pass: ADCEPass on f
-; MSSA-NEXT: Running analysis: PostDominatorTreeAnalysis on f
+; MSSA:      Running analysis: PostDominatorTreeAnalysis on f
 ; MSSA-NEXT: Finished llvm::Function pass manager run.
 
 ; CHECK-LABEL: define i8 @f() {
Index: llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
+++ llvm/test/Other/new-pm-thinlto-prelink-pgo-defaults.ll
@@ -33,7 +33,7 @@
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O-NEXT: Starting {{.*}}Function pass manager run.
+; CHECK-O:      Starting {{.*}}Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis
@@ -111,7 +111,7 @@
 ; CHECK-O3-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O2-NEXT: Running pass: OpenMPOptPass
 ; CHECK-O3-NEXT: Running pass: OpenMPOptPass
-; CHECK-O-NEXT: Starting {{.*}}Function pass manager run.
+; CHECK-O:      Starting {{.*}}Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SROA
 ; These next two can appear in any order since they are accessed as parameters
 ; on the same call to SROA::runImpl
Index: llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
+++ llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll
@@ -34,7 +34,7 @@
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O-NEXT: Starting {{.*}}Function pass manager run.
+; CHECK-O:      Starting {{.*}}Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis
Index: llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
+++ llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
@@ -32,7 +32,7 @@
 ; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O-NEXT: Starting {{.*}}Function pass manager run.
+; CHECK-O:      Starting {{.*}}Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis
Index: llvm/test/Other/new-pm-thinlto-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-thinlto-defaults.ll
+++ llvm/test/Other/new-pm-thinlto-defaults.ll
@@ -62,7 +62,7 @@
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-PRELINK-O-NODIS-NEXT: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O-NEXT: Starting llvm::Function pass manager run.
+; CHECK-O:      Starting llvm::Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis
Index: llvm/test/Other/new-pm-lto-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-lto-defaults.ll
+++ llvm/test/Other/new-pm-lto-defaults.ll
@@ -29,7 +29,7 @@
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}Module
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O2-NEXT: Starting llvm::Function pass manager run.
+; CHECK-O2:     Starting llvm::Function pass manager run.
 ; CHECK-O2-NEXT: Running pass: CallSiteSplittingPass on foo
 ; CHECK-O2-NEXT: Running analysis: TargetLibraryAnalysis on foo
 ; CHECK-O2-NEXT: Running analysis: TargetIRAnalysis on foo
Index: llvm/test/Other/new-pm-defaults.ll
===================================================================
--- llvm/test/Other/new-pm-defaults.ll
+++ llvm/test/Other/new-pm-defaults.ll
@@ -97,7 +97,7 @@
 ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass
 ; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy
 ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis
-; CHECK-O-NEXT: Starting llvm::Function pass manager run.
+; CHECK-O:      Starting llvm::Function pass manager run.
 ; CHECK-O-NEXT: Running pass: SimplifyCFGPass
 ; CHECK-O-NEXT: Running analysis: TargetIRAnalysis
 ; CHECK-O-NEXT: Running analysis: AssumptionAnalysis
Index: llvm/test/Other/new-pass-manager.ll
===================================================================
--- llvm/test/Other/new-pass-manager.ll
+++ llvm/test/Other/new-pass-manager.ll
@@ -38,7 +38,7 @@
 ; RUN:     | FileCheck %s --check-prefix=CHECK-FUNCTION-PASS
 ; CHECK-FUNCTION-PASS: Starting llvm::Module pass manager run
 ; CHECK-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
-; CHECK-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-FUNCTION-PASS:      Starting llvm::Function pass manager run
 ; CHECK-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
 ; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
 ; CHECK-FUNCTION-PASS-NEXT: Finished llvm::Module pass manager run
@@ -411,7 +411,7 @@
 ; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-FUNCTION-PASS
 ; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run
 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
-; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS:      Starting llvm::Function pass manager run
 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatedPass
 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
 ; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
@@ -430,14 +430,14 @@
 ; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-LOOP-PASS
 ; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
-; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-LOOP-PASS:      Starting llvm::Function pass manager run
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: LoopSimplify
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: LoopAnalysis
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: DominatorTreeAnalysis
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AssumptionAnalysis
-; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: LCSSAPass
-; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-LOOP-PASS:      Running pass: LCSSAPass
+; CHECK-REPEAT-LOOP-PASS:      Finished llvm::Function pass manager run
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AAManager
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetLibraryAnalysis
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: ScalarEvolutionAnalysis
Index: llvm/test/Other/loop-pm-invalidation.ll
===================================================================
--- llvm/test/Other/loop-pm-invalidation.ll
+++ llvm/test/Other/loop-pm-invalidation.ll
@@ -308,8 +308,8 @@
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: LoopDeletionPass
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Clearing all analysis results for:
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Finished {{.*}}Loop pass manager run.
-; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
-; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Invalidating analysis: ScalarEvolutionAnalysis
+; CHECK-SCEV-INV-AFTER-DELETE:      Running pass: InvalidateAnalysisPass<{{.*}}ScalarEvolutionAnalysis
+; CHECK-SCEV-INV-AFTER-DELETE:      Invalidating analysis: ScalarEvolutionAnalysis
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Invalidating analysis: InnerAnalysisManagerProxy<{{.*}}Loop
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Starting {{.*}}Function pass manager run
 ; CHECK-SCEV-INV-AFTER-DELETE-NEXT: Running pass: LoopSimplifyPass
Index: llvm/lib/Passes/StandardInstrumentations.cpp
===================================================================
--- llvm/lib/Passes/StandardInstrumentations.cpp
+++ llvm/lib/Passes/StandardInstrumentations.cpp
@@ -658,18 +658,6 @@
                                                         const CFG &Before,
                                                         const CFG &After) {
   assert(!After.isPoisoned());
-
-  // Print function name.
-  const CFG *FuncGraph = nullptr;
-  if (!After.Graph.empty())
-    FuncGraph = &After;
-  else if (!Before.isPoisoned() && !Before.Graph.empty())
-    FuncGraph = &Before;
-
-  if (FuncGraph)
-    out << "In function @"
-        << FuncGraph->Graph.begin()->first->getParent()->getName() << "\n";
-
   if (Before.isPoisoned()) {
     out << "Some blocks were deleted\n";
     return;
@@ -725,46 +713,90 @@
   }
 }
 
+struct PreservedCFGCheckerAnalysis
+    : public AnalysisInfoMixin<PreservedCFGCheckerAnalysis> {
+  friend AnalysisInfoMixin<PreservedCFGCheckerAnalysis>;
+
+  static AnalysisKey Key;
+
+public:
+  /// Provide the result type for this analysis pass.
+  using Result = PreservedCFGCheckerInstrumentation::CFG;
+
+  /// Run the analysis pass over a function and produce CFG.
+  Result run(Function &F, FunctionAnalysisManager &AM) {
+    return Result(&F, true /* TrackBBLifetime */);
+  }
+};
+
+AnalysisKey PreservedCFGCheckerAnalysis::Key;
+
+bool PreservedCFGCheckerInstrumentation::CFG::invalidate(
+    Function &F, const PreservedAnalyses &PA,
+    FunctionAnalysisManager::Invalidator &) {
+  auto PAC = PA.getChecker<PreservedCFGCheckerAnalysis>();
+  return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
+           PAC.preservedSet<CFGAnalyses>());
+}
+
 void PreservedCFGCheckerInstrumentation::registerCallbacks(
-    PassInstrumentationCallbacks &PIC) {
+    PassInstrumentationCallbacks &PIC, FunctionAnalysisManager &FAM) {
   if (!VerifyPreservedCFG)
     return;
 
-  PIC.registerBeforeNonSkippedPassCallback([this](StringRef P, Any IR) {
-    if (any_isa<const Function *>(IR))
-      GraphStackBefore.emplace_back(P, CFG(any_cast<const Function *>(IR)));
+  FAM.registerPass([&] { return PreservedCFGCheckerAnalysis(); });
+
+  auto checkCFG = [](StringRef Pass, StringRef FuncName, const CFG &GraphBefore,
+                     const CFG &GraphAfter) {
+    if (GraphAfter == GraphBefore)
+      return;
+
+    dbgs() << "Error: " << Pass
+           << " does not invalidate CFG analyses but CFG changes detected in "
+              "function @"
+           << FuncName << ":\n";
+    CFG::printDiff(dbgs(), GraphBefore, GraphAfter);
+    report_fatal_error(Twine("CFG unexpectedly changed by ", Pass));
+  };
+
+  PIC.registerBeforeNonSkippedPassCallback([this, &FAM, checkCFG](StringRef P,
+                                                                  Any IR) {
+    assert(&PassStack.emplace_back(P));
+    if (!any_isa<const Function *>(IR))
+      return;
+
+    auto *F = any_cast<const Function *>(IR);
+    if (auto *Result = FAM.getCachedResult<PreservedCFGCheckerAnalysis>(
+            *const_cast<Function *>(F)))
+      checkCFG(P, F->getName(), *Result, CFG(F, false /* TrackBBLifetime */));
     else
-      GraphStackBefore.emplace_back(P, None);
+      FAM.getResult<PreservedCFGCheckerAnalysis>(*const_cast<Function *>(F));
   });
 
   PIC.registerAfterPassInvalidatedCallback(
       [this](StringRef P, const PreservedAnalyses &PassPA) {
-        auto Before = GraphStackBefore.pop_back_val();
-        assert(Before.first == P &&
+        assert(PassStack.pop_back_val() == P &&
                "Before and After callbacks must correspond");
-        (void)Before;
       });
 
-  PIC.registerAfterPassCallback([this](StringRef P, Any IR,
-                                       const PreservedAnalyses &PassPA) {
-    auto Before = GraphStackBefore.pop_back_val();
-    assert(Before.first == P && "Before and After callbacks must correspond");
-    auto &GraphBefore = Before.second;
+  PIC.registerAfterPassCallback([this, &FAM,
+                                 checkCFG](StringRef P, Any IR,
+                                           const PreservedAnalyses &PassPA) {
+    assert(PassStack.pop_back_val() == P &&
+           "Before and After callbacks must correspond");
 
-    if (!PassPA.allAnalysesInSetPreserved<CFGAnalyses>())
+    if (!any_isa<const Function *>(IR))
       return;
 
-    if (any_isa<const Function *>(IR)) {
-      assert(GraphBefore && "Must be built in BeforePassCallback");
-      CFG GraphAfter(any_cast<const Function *>(IR), false /* NeedsGuard */);
-      if (GraphAfter == *GraphBefore)
-        return;
+    if (!PassPA.allAnalysesInSetPreserved<CFGAnalyses>() &&
+        !PassPA.allAnalysesInSetPreserved<AllAnalysesOn<Function>>())
+      return;
 
-      dbgs() << "Error: " << P
-             << " reported it preserved CFG, but changes detected:\n";
-      CFG::printDiff(dbgs(), *GraphBefore, GraphAfter);
-      report_fatal_error(Twine("Preserved CFG changed by ", P));
-    }
+    auto *F = any_cast<const Function *>(IR);
+    if (auto *GraphBefore = FAM.getCachedResult<PreservedCFGCheckerAnalysis>(
+            *const_cast<Function *>(F)))
+      checkCFG(P, F->getName(), *GraphBefore,
+               CFG(F, false /* TrackBBLifetime */));
   });
 }
 
@@ -805,13 +837,14 @@
 }
 
 void StandardInstrumentations::registerCallbacks(
-    PassInstrumentationCallbacks &PIC) {
+    PassInstrumentationCallbacks &PIC, FunctionAnalysisManager *FAM) {
   PrintIR.registerCallbacks(PIC);
   PrintPass.registerCallbacks(PIC);
   TimePasses.registerCallbacks(PIC);
   OptNone.registerCallbacks(PIC);
   OptBisect.registerCallbacks(PIC);
-  PreservedCFGChecker.registerCallbacks(PIC);
+  if (FAM)
+    PreservedCFGChecker.registerCallbacks(PIC, *FAM);
   PrintChangedIR.registerCallbacks(PIC);
   if (VerifyEach)
     Verify.registerCallbacks(PIC);
Index: llvm/lib/LTO/LTOBackend.cpp
===================================================================
--- llvm/lib/LTO/LTOBackend.cpp
+++ llvm/lib/LTO/LTOBackend.cpp
@@ -221,8 +221,6 @@
   }
 
   PassInstrumentationCallbacks PIC;
-  StandardInstrumentations SI(Conf.DebugPassManager);
-  SI.registerCallbacks(PIC);
   PassBuilder PB(Conf.DebugPassManager, TM, Conf.PTO, PGOOpt, &PIC);
   AAManager AA;
 
@@ -237,6 +235,9 @@
   CGSCCAnalysisManager CGAM(Conf.DebugPassManager);
   ModuleAnalysisManager MAM(Conf.DebugPassManager);
 
+  StandardInstrumentations SI(Conf.DebugPassManager);
+  SI.registerCallbacks(PIC, &FAM);
+
   // Register the AA manager first so that our version is the one used.
   FAM.registerPass([&] { return std::move(AA); });
 
Index: llvm/include/llvm/Passes/StandardInstrumentations.h
===================================================================
--- llvm/include/llvm/Passes/StandardInstrumentations.h
+++ llvm/include/llvm/Passes/StandardInstrumentations.h
@@ -20,6 +20,7 @@
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/OptBisect.h"
 #include "llvm/IR/PassInstrumentation.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/IR/PassTimingInfo.h"
 #include "llvm/IR/ValueHandle.h"
 #include "llvm/Support/CommandLine.h"
@@ -85,7 +86,7 @@
 };
 
 class PreservedCFGCheckerInstrumentation {
-private:
+public:
   // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
   // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
   // and the multiplicity of the edge (BB->Succ). As the mapped sets are
@@ -105,7 +106,7 @@
     Optional<DenseMap<intptr_t, BBGuard>> BBGuards;
     DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph;
 
-    CFG(const Function *F, bool TrackBBLifetime = false);
+    CFG(const Function *F, bool TrackBBLifetime);
 
     bool operator==(const CFG &G) const {
       return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
@@ -122,13 +123,18 @@
 
     static void printDiff(raw_ostream &out, const CFG &Before,
                           const CFG &After);
+    bool invalidate(Function &F, const PreservedAnalyses &PA,
+                    FunctionAnalysisManager::Invalidator &);
   };
 
-  SmallVector<std::pair<StringRef, Optional<CFG>>, 8> GraphStackBefore;
+#ifndef NDEBUG
+  SmallVector<StringRef, 8> PassStack;
+#endif
 
 public:
   static cl::opt<bool> VerifyPreservedCFG;
-  void registerCallbacks(PassInstrumentationCallbacks &PIC);
+  void registerCallbacks(PassInstrumentationCallbacks &PIC,
+                         FunctionAnalysisManager &FAM);
 };
 
 // Base class for classes that report changes to the IR.
@@ -249,7 +255,8 @@
       : PrintPass(DebugLogging), OptNone(DebugLogging), Verify(DebugLogging),
         VerifyEach(VerifyEach) {}
 
-  void registerCallbacks(PassInstrumentationCallbacks &PIC);
+  void registerCallbacks(PassInstrumentationCallbacks &PIC,
+                         FunctionAnalysisManager *FAM = nullptr);
 
   TimePassesHandler &getTimePasses() { return TimePasses; }
 };
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -1209,8 +1209,6 @@
   PTO.Coroutines = LangOpts.Coroutines;
 
   PassInstrumentationCallbacks PIC;
-  StandardInstrumentations SI(CodeGenOpts.DebugPassManager);
-  SI.registerCallbacks(PIC);
   PassBuilder PB(CodeGenOpts.DebugPassManager, TM.get(), PTO, PGOOpt, &PIC);
 
   // Attempt to load pass plugins and register their callbacks with PB.
@@ -1232,6 +1230,9 @@
   CGSCCAnalysisManager CGAM(CodeGenOpts.DebugPassManager);
   ModuleAnalysisManager MAM(CodeGenOpts.DebugPassManager);
 
+  StandardInstrumentations SI(CodeGenOpts.DebugPassManager);
+  SI.registerCallbacks(PIC, &FAM);
+
   // Register the AA manager first so that our version is the one used.
   FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to