1 //===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the GCFunctionInfo class and GCModuleInfo pass.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/CodeGen/GCMetadata.h"
14 #include "llvm/ADT/StringExtras.h"
15 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/InitializePasses.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/Pass.h"
20 #include "llvm/Support/raw_ostream.h"
27 bool GCStrategyMap::invalidate(Module
&M
, const PreservedAnalyses
&PA
,
28 ModuleAnalysisManager::Invalidator
&) {
29 for (const auto &F
: M
) {
30 if (F
.isDeclaration() || !F
.hasGC())
32 if (!StrategyMap
.contains(F
.getGC()))
38 AnalysisKey
CollectorMetadataAnalysis::Key
;
40 CollectorMetadataAnalysis::Result
41 CollectorMetadataAnalysis::run(Module
&M
, ModuleAnalysisManager
&MAM
) {
43 auto &Map
= R
.StrategyMap
;
45 if (F
.isDeclaration() || !F
.hasGC())
47 if (auto GCName
= F
.getGC(); !Map
.contains(GCName
))
48 Map
[GCName
] = getGCStrategy(GCName
);
53 AnalysisKey
GCFunctionAnalysis::Key
;
55 GCFunctionAnalysis::Result
56 GCFunctionAnalysis::run(Function
&F
, FunctionAnalysisManager
&FAM
) {
57 assert(!F
.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
58 assert(F
.hasGC() && "Function doesn't have GC!");
60 auto &MAMProxy
= FAM
.getResult
<ModuleAnalysisManagerFunctionProxy
>(F
);
62 MAMProxy
.cachedResultExists
<CollectorMetadataAnalysis
>(*F
.getParent()) &&
63 "This pass need module analysis `collector-metadata`!");
65 MAMProxy
.getCachedResult
<CollectorMetadataAnalysis
>(*F
.getParent())
67 GCFunctionInfo
Info(F
, *Map
[F
.getGC()]);
71 INITIALIZE_PASS(GCModuleInfo
, "collector-metadata",
72 "Create Garbage Collector Module Metadata", false, false)
74 // -----------------------------------------------------------------------------
76 GCFunctionInfo::GCFunctionInfo(const Function
&F
, GCStrategy
&S
)
77 : F(F
), S(S
), FrameSize(~0LL) {}
79 GCFunctionInfo::~GCFunctionInfo() = default;
81 bool GCFunctionInfo::invalidate(Function
&F
, const PreservedAnalyses
&PA
,
82 FunctionAnalysisManager::Invalidator
&) {
83 auto PAC
= PA
.getChecker
<GCFunctionAnalysis
>();
84 return !PAC
.preserved() && !PAC
.preservedSet
<AllAnalysesOn
<Function
>>();
87 // -----------------------------------------------------------------------------
89 char GCModuleInfo::ID
= 0;
91 GCModuleInfo::GCModuleInfo() : ImmutablePass(ID
) {
92 initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
95 GCFunctionInfo
&GCModuleInfo::getFunctionInfo(const Function
&F
) {
96 assert(!F
.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
99 finfo_map_type::iterator I
= FInfoMap
.find(&F
);
100 if (I
!= FInfoMap
.end())
103 GCStrategy
*S
= getGCStrategy(F
.getGC());
104 Functions
.push_back(std::make_unique
<GCFunctionInfo
>(F
, *S
));
105 GCFunctionInfo
*GFI
= Functions
.back().get();
110 void GCModuleInfo::clear() {
113 GCStrategyList
.clear();
116 // -----------------------------------------------------------------------------
118 GCStrategy
*GCModuleInfo::getGCStrategy(const StringRef Name
) {
119 // TODO: Arguably, just doing a linear search would be faster for small N
120 auto NMI
= GCStrategyMap
.find(Name
);
121 if (NMI
!= GCStrategyMap
.end())
122 return NMI
->getValue();
124 std::unique_ptr
<GCStrategy
> S
= llvm::getGCStrategy(Name
);
125 S
->Name
= std::string(Name
);
126 GCStrategyMap
[Name
] = S
.get();
127 GCStrategyList
.push_back(std::move(S
));
128 return GCStrategyList
.back().get();