[llvm] [CodeGen] Port `GCInfoPrinter` to new pass manager (PR #74972)

via llvm-commits llvm-commits at lists.llvm.org
Sun Dec 10 18:40:59 PST 2023


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/74972

>From e189193711337bd2cca7595ef70a875006d333e8 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sun, 10 Dec 2023 13:49:05 +0800
Subject: [PATCH 1/2] [CodeGen] Add analyses to help for porting GC passes

---
 .../include/llvm/CodeGen/CodeGenPassBuilder.h |  1 +
 llvm/include/llvm/CodeGen/GCMetadata.h        | 40 +++++++++++++
 .../llvm/CodeGen/MachinePassRegistry.def      |  2 +
 llvm/lib/CodeGen/GCMetadata.cpp               | 58 +++++++++++++++++++
 llvm/lib/Passes/PassBuilder.cpp               |  1 +
 llvm/lib/Passes/PassRegistry.def              |  2 +
 6 files changed, 104 insertions(+)

diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index bb139ef2eb3510..f83cea28f1a7a1 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -25,6 +25,7 @@
 #include "llvm/CodeGen/CallBrPrepare.h"
 #include "llvm/CodeGen/DwarfEHPrepare.h"
 #include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/MachinePassManager.h"
 #include "llvm/CodeGen/PreISelIntrinsicLowering.h"
diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index 334c5c23b8facc..ac9513f08d37bf 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -38,6 +38,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DebugLoc.h"
 #include "llvm/IR/GCStrategy.h"
+#include "llvm/IR/PassManager.h"
 #include "llvm/Pass.h"
 #include <algorithm>
 #include <cstddef>
@@ -101,6 +102,10 @@ class GCFunctionInfo {
   GCFunctionInfo(const Function &F, GCStrategy &S);
   ~GCFunctionInfo();
 
+  /// Handle invalidation explicitly.
+  bool invalidate(Function &F, const PreservedAnalyses &PA,
+                  FunctionAnalysisManager::Invalidator &Inv);
+
   /// getFunction - Return the function to which this metadata applies.
   const Function &getFunction() const { return F; }
 
@@ -146,6 +151,41 @@ class GCFunctionInfo {
   size_t live_size(const iterator &p) const { return roots_size(); }
 };
 
+struct GCStrategyMap {
+  StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
+
+  GCStrategyMap() = default;
+  GCStrategyMap(GCStrategyMap &&) = default;
+
+  /// Handle invalidation explicitly.
+  bool invalidate(Module &M, const PreservedAnalyses &PA,
+                  ModuleAnalysisManager::Invalidator &Inv);
+};
+
+/// An analysis pass which caches information about the entire Module.
+/// Records a cache of the 'active' gc strategy objects for the current Module.
+class CollectorMetadataAnalysis
+    : public AnalysisInfoMixin<CollectorMetadataAnalysis> {
+  friend class AnalysisInfoMixin<CollectorMetadataAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = GCStrategyMap;
+  Result run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+/// An analysis pass which caches information about the Function.
+/// Records the function level information used by GCRoots.
+/// This pass depends on `CollectorMetadataAnalysis`.
+class GCFunctionAnalysis : public AnalysisInfoMixin<GCFunctionAnalysis> {
+  friend class AnalysisInfoMixin<GCFunctionAnalysis>;
+  static AnalysisKey Key;
+
+public:
+  using Result = GCFunctionInfo;
+  Result run(Function &F, FunctionAnalysisManager &FAM);
+};
+
 /// An analysis pass which caches information about the entire Module.
 /// Records both the function level information used by GCRoots and a
 /// cache of the 'active' gc strategy objects for the current Module.
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index e6e979a4582c7a..7fd316084b0c2a 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -16,6 +16,7 @@
 #ifndef MODULE_ANALYSIS
 #define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
 #endif
+MODULE_ANALYSIS("collector-metadata", CollectorMetadataAnalysis, ())
 MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
 #undef MODULE_ANALYSIS
 
@@ -28,6 +29,7 @@ MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())
 #ifndef FUNCTION_ANALYSIS
 #define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)
 #endif
+FUNCTION_ANALYSIS("gc-function", GCFunctionAnalysis, ())
 FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))
 FUNCTION_ANALYSIS("targetir", TargetIRAnalysis,
                   (std::move(TM.getTargetIRAnalysis())))
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index 4d27143c529823..50ca4af065949c 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -43,6 +43,58 @@ class Printer : public FunctionPass {
 
 } // end anonymous namespace
 
+// -----------------------------------------------------------------------------
+
+bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
+                               ModuleAnalysisManager::Invalidator &) {
+  for (const auto &F : M) {
+    if (F.isDeclaration() || !F.hasGC())
+      continue;
+    if (!StrategyMap.contains(F.getGC()))
+      return true;
+  }
+  return false;
+}
+
+// -----------------------------------------------------------------------------
+
+AnalysisKey CollectorMetadataAnalysis::Key;
+
+CollectorMetadataAnalysis::Result
+CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
+  Result R;
+  auto &Map = R.StrategyMap;
+  for (auto &F : M) {
+    if (F.isDeclaration() || !F.hasGC())
+      continue;
+    if (auto GCName = F.getGC(); !Map.contains(GCName))
+      Map[GCName] = getGCStrategy(GCName);
+  }
+  return R;
+}
+
+// -----------------------------------------------------------------------------
+
+AnalysisKey GCFunctionAnalysis::Key;
+
+GCFunctionAnalysis::Result
+GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
+  assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
+  assert(F.hasGC() && "Function doesn't have GC!");
+
+  auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
+  assert(
+      MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&
+      "This pass need module analysis `collector-metadata`!");
+  auto &Map =
+      MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent())
+          ->StrategyMap;
+  GCFunctionInfo Info(F, *Map[F.getGC()]);
+  return Info;
+}
+
+// -----------------------------------------------------------------------------
+
 INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
                 "Create Garbage Collector Module Metadata", false, false)
 
@@ -53,6 +105,12 @@ GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
 
 GCFunctionInfo::~GCFunctionInfo() = default;
 
+bool GCFunctionInfo::invalidate(Function &F, const PreservedAnalyses &PA,
+                                FunctionAnalysisManager::Invalidator &) {
+  auto PAC = PA.getChecker<GCFunctionAnalysis>();
+  return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>());
+}
+
 // -----------------------------------------------------------------------------
 
 char GCModuleInfo::ID = 0;
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f26450e9418700..bc127f62624164 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -76,6 +76,7 @@
 #include "llvm/CodeGen/DwarfEHPrepare.h"
 #include "llvm/CodeGen/ExpandLargeDivRem.h"
 #include "llvm/CodeGen/ExpandLargeFpConvert.h"
+#include "llvm/CodeGen/GCMetadata.h"
 #include "llvm/CodeGen/HardwareLoops.h"
 #include "llvm/CodeGen/InterleavedAccess.h"
 #include "llvm/CodeGen/SafeStack.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index bf9622670ba59b..335a103db6f73d 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -19,6 +19,7 @@
 #define MODULE_ANALYSIS(NAME, CREATE_PASS)
 #endif
 MODULE_ANALYSIS("callgraph", CallGraphAnalysis())
+MODULE_ANALYSIS("collector-metadata", CollectorMetadataAnalysis())
 MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
 MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
 MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
@@ -234,6 +235,7 @@ FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis())
 FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())
 FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis())
 FUNCTION_ANALYSIS("func-properties", FunctionPropertiesAnalysis())
+FUNCTION_ANALYSIS("gc-function", GCFunctionAnalysis())
 FUNCTION_ANALYSIS("inliner-size-estimator", InlineSizeEstimatorAnalysis())
 FUNCTION_ANALYSIS("lazy-value-info", LazyValueAnalysis())
 FUNCTION_ANALYSIS("loops", LoopAnalysis())

>From cb96d32f291e82629b5ab854841619c5c2fc8056 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sun, 10 Dec 2023 13:49:46 +0800
Subject: [PATCH 2/2] [CodeGen] Port `GCInfoPrinter` to new pass manager

---
 llvm/include/llvm/CodeGen/GCMetadata.h        |  8 +++
 .../llvm/CodeGen/MachinePassRegistry.def      |  2 +-
 llvm/lib/CodeGen/GCMetadata.cpp               | 66 ++++++++++---------
 llvm/lib/Passes/PassRegistry.def              |  1 +
 4 files changed, 46 insertions(+), 31 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GCMetadata.h b/llvm/include/llvm/CodeGen/GCMetadata.h
index ac9513f08d37bf..f183277bda56be 100644
--- a/llvm/include/llvm/CodeGen/GCMetadata.h
+++ b/llvm/include/llvm/CodeGen/GCMetadata.h
@@ -240,6 +240,14 @@ class GCModuleInfo : public ImmutablePass {
   GCFunctionInfo &getFunctionInfo(const Function &F);
 };
 
+class GCInfoPrinterPass : public PassInfoMixin<GCInfoPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  GCInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+
 } // end namespace llvm
 
 #endif // LLVM_CODEGEN_GCMETADATA_H
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index 7fd316084b0c2a..f1826de46b0b00 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -52,6 +52,7 @@ FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())
 FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())
 FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())
 FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))
+FUNCTION_PASS("print<gc-info>", GCInfoPrinterPass, (dbgs()))
 FUNCTION_PASS("replace-with-veclib", ReplaceWithVeclib, ())
 FUNCTION_PASS("safe-stack", SafeStackPass, (TM))
 FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())
@@ -127,7 +128,6 @@ DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())
 DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
 DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
 DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
-DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())
 DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
 DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())
 DUMMY_FUNCTION_PASS("select-optimize", SelectOptimizePass, ())
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index 50ca4af065949c..a669afd5322a18 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -43,8 +43,6 @@ class Printer : public FunctionPass {
 
 } // end anonymous namespace
 
-// -----------------------------------------------------------------------------
-
 bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
                                ModuleAnalysisManager::Invalidator &) {
   for (const auto &F : M) {
@@ -56,8 +54,6 @@ bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
   return false;
 }
 
-// -----------------------------------------------------------------------------
-
 AnalysisKey CollectorMetadataAnalysis::Key;
 
 CollectorMetadataAnalysis::Result
@@ -73,8 +69,6 @@ CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
   return R;
 }
 
-// -----------------------------------------------------------------------------
-
 AnalysisKey GCFunctionAnalysis::Key;
 
 GCFunctionAnalysis::Result
@@ -93,8 +87,6 @@ GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
   return Info;
 }
 
-// -----------------------------------------------------------------------------
-
 INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
                 "Create Garbage Collector Module Metadata", false, false)
 
@@ -142,6 +134,39 @@ void GCModuleInfo::clear() {
 
 // -----------------------------------------------------------------------------
 
+static void printGCInfo(const Function &F, GCFunctionInfo &Info,
+                        raw_ostream &OS) {
+  auto FName = F.getName();
+
+  OS << "GC roots for " << FName << ":\n";
+  for (const auto &R : make_range(Info.roots_begin(), Info.roots_end()))
+    OS << "\t" << R.Num << "\t" << R.StackOffset << "[sp]\n";
+
+  OS << "GC safe points for " << FName << ":\n";
+  for (auto PI = Info.begin(), PE = Info.end(); PI != PE; ++PI) {
+    OS << "\t" << PI->Label->getName() << ": "
+       << "post-call"
+       << ", live = {";
+
+    ListSeparator LS(",");
+    for (const GCRoot &R : make_range(Info.live_begin(PI), Info.live_end(PI)))
+      OS << LS << " " << R.Num;
+
+    OS << " }\n";
+  }
+}
+
+PreservedAnalyses GCInfoPrinterPass::run(Function &F,
+                                         FunctionAnalysisManager &FAM) {
+  if (F.isDeclaration() || !F.hasGC())
+    return PreservedAnalyses::all();
+
+  auto &Info = FAM.getResult<GCFunctionAnalysis>(F);
+  printGCInfo(F, Info, OS);
+
+  return PreservedAnalyses::all();
+}
+
 char Printer::ID = 0;
 
 FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) {
@@ -159,30 +184,11 @@ void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
 }
 
 bool Printer::runOnFunction(Function &F) {
-  if (F.hasGC())
+  if (F.isDeclaration() || !F.hasGC())
     return false;
 
-  GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
-
-  OS << "GC roots for " << FD->getFunction().getName() << ":\n";
-  for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(),
-                                      RE = FD->roots_end();
-       RI != RE; ++RI)
-    OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n";
-
-  OS << "GC safe points for " << FD->getFunction().getName() << ":\n";
-  for (GCFunctionInfo::iterator PI = FD->begin(), PE = FD->end(); PI != PE;
-       ++PI) {
-
-    OS << "\t" << PI->Label->getName() << ": " << "post-call"
-       << ", live = {";
-
-    ListSeparator LS(",");
-    for (const GCRoot &R : make_range(FD->live_begin(PI), FD->live_end(PI)))
-      OS << LS << " " << R.Num;
-
-    OS << " }\n";
-  }
+  GCFunctionInfo &Info = getAnalysis<GCModuleInfo>().getFunctionInfo(F);
+  printGCInfo(F, Info, OS);
 
   return false;
 }
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 335a103db6f73d..b373377d235a5b 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -379,6 +379,7 @@ FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
 FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))
 FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
 FUNCTION_PASS("print<func-properties>", FunctionPropertiesPrinterPass(dbgs()))
+FUNCTION_PASS("print<gc-info>", GCInfoPrinterPass(dbgs()))
 FUNCTION_PASS("print<inline-cost>", InlineCostAnnotationPrinterPass(dbgs()))
 FUNCTION_PASS("print<inliner-size-estimator>",
               InlineSizeEstimatorAnalysisPrinterPass(dbgs()))



More information about the llvm-commits mailing list