[llvm] [CodeGen] Port `GCInfoPrinter` to new pass manager (PR #74972)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 9 22:01:32 PST 2023
https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/74972
- Add two helper analysis passes.
- Don't skip function which has GC.
>From 49892be03dab7184e1bd89a050c109fface91f68 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 076719abd0356b..0ef52097b16766 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -24,6 +24,7 @@
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
#include "llvm/CodeGen/CallBrPrepare.h"
#include "llvm/CodeGen/ExpandReductions.h"
+#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/PreISelIntrinsicLowering.h"
#include "llvm/CodeGen/ReplaceWithVeclib.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 1e9e5838841b29..55e489da0ff129 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..477b0a7eca781e 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 a5f9b5424358ec..f3f1bddd720daa 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/SafeStack.h"
#include "llvm/CodeGen/TypePromotion.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 7462704ec2df8e..92fd642f3cae08 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 b88258cdf4afe684f66c69d75ec4cfbb3d27f6dd 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 | 32 ++++++++++++++++++-
llvm/lib/Passes/PassRegistry.def | 1 +
4 files changed, 41 insertions(+), 2 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 55e489da0ff129..65bbd15dd39907 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -50,6 +50,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, ())
@@ -126,7 +127,6 @@ DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())
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("interleaved-access", InterleavedAccessPass, ())
diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
index 477b0a7eca781e..d7b54a1556bf3b 100644
--- a/llvm/lib/CodeGen/GCMetadata.cpp
+++ b/llvm/lib/CodeGen/GCMetadata.cpp
@@ -142,6 +142,36 @@ void GCModuleInfo::clear() {
// -----------------------------------------------------------------------------
+PreservedAnalyses GCInfoPrinterPass::run(Function &F,
+ FunctionAnalysisManager &FAM) {
+ if (F.isDeclaration() || !F.hasGC())
+ return PreservedAnalyses::all();
+
+ auto &Info = FAM.getResult<GCFunctionAnalysis>(F);
+ 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";
+ }
+
+ return PreservedAnalyses::all();
+}
+
+// -----------------------------------------------------------------------------
+
char Printer::ID = 0;
FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) {
@@ -159,7 +189,7 @@ void Printer::getAnalysisUsage(AnalysisUsage &AU) const {
}
bool Printer::runOnFunction(Function &F) {
- if (F.hasGC())
+ if (!F.hasGC())
return false;
GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F);
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 92fd642f3cae08..c88346adc8bb14 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -378,6 +378,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