[CodeGen] Add analyses to help for porting GC passes (#74972)

- `CollectorMetadataAnalysis` provides `GCStrategyMap`.
- `GCFunctionAnalysis` provides `GCFunctionInfo`.

`GCStrategyMap` owns `GCStrategy` pointers and this
pass is used by `AsmPrinter` to iterate all GC strategies.

Most passes that require `GCModuleInfo` actually require the
`GCFunctionInfo`,
so add `GCFunctionAnalysis` for convenience.
This commit is contained in:
paperchalice 2023-12-13 15:56:12 +08:00 committed by GitHub
parent dbf67ea1d3
commit 06aa8b189a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 0 deletions

View File

@ -26,6 +26,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/InterleavedLoadCombine.h"
#include "llvm/CodeGen/JMCInstrumenter.h"

View File

@ -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 @@ public:
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 @@ public:
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 struct 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 struct 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.

View File

@ -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
@ -29,6 +30,7 @@ MODULE_PASS("jmc-instrumenter", JMCInstrumenterPass, ())
#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())))

View File

@ -24,6 +24,50 @@
using namespace llvm;
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)
@ -34,6 +78,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;

View File

@ -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/InterleavedLoadCombine.h"

View File

@ -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())
@ -235,6 +236,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())