Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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/JMCInstrumenter.h"
#include "llvm/CodeGen/MachinePassManager.h"
Expand Down
40 changes: 40 additions & 0 deletions llvm/include/llvm/CodeGen/GCMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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; }

Expand Down Expand Up @@ -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 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.
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/MachinePassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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())))
Expand Down
50 changes: 50 additions & 0 deletions llvm/lib/CodeGen/GCMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/JMCInstrumenter.h"
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Passes/PassRegistry.def
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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())
Expand Down