Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/CodeGen/GCMetadata.cpp
35233 views
1
//===-- GCMetadata.cpp - Garbage collector metadata -----------------------===//
2
//
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
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements the GCFunctionInfo class and GCModuleInfo pass.
10
//
11
//===----------------------------------------------------------------------===//
12
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/IR/Module.h"
18
#include "llvm/InitializePasses.h"
19
#include "llvm/MC/MCSymbol.h"
20
#include "llvm/Pass.h"
21
#include "llvm/Support/raw_ostream.h"
22
#include <cassert>
23
#include <memory>
24
#include <string>
25
26
using namespace llvm;
27
28
bool GCStrategyMap::invalidate(Module &M, const PreservedAnalyses &PA,
29
ModuleAnalysisManager::Invalidator &) {
30
for (const auto &F : M) {
31
if (F.isDeclaration() || !F.hasGC())
32
continue;
33
if (!StrategyMap.contains(F.getGC()))
34
return true;
35
}
36
return false;
37
}
38
39
AnalysisKey CollectorMetadataAnalysis::Key;
40
41
CollectorMetadataAnalysis::Result
42
CollectorMetadataAnalysis::run(Module &M, ModuleAnalysisManager &MAM) {
43
Result R;
44
auto &Map = R.StrategyMap;
45
for (auto &F : M) {
46
if (F.isDeclaration() || !F.hasGC())
47
continue;
48
if (auto GCName = F.getGC(); !Map.contains(GCName))
49
Map[GCName] = getGCStrategy(GCName);
50
}
51
return R;
52
}
53
54
AnalysisKey GCFunctionAnalysis::Key;
55
56
GCFunctionAnalysis::Result
57
GCFunctionAnalysis::run(Function &F, FunctionAnalysisManager &FAM) {
58
assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
59
assert(F.hasGC() && "Function doesn't have GC!");
60
61
auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
62
assert(
63
MAMProxy.cachedResultExists<CollectorMetadataAnalysis>(*F.getParent()) &&
64
"This pass need module analysis `collector-metadata`!");
65
auto &Map =
66
MAMProxy.getCachedResult<CollectorMetadataAnalysis>(*F.getParent())
67
->StrategyMap;
68
GCFunctionInfo Info(F, *Map[F.getGC()]);
69
return Info;
70
}
71
72
INITIALIZE_PASS(GCModuleInfo, "collector-metadata",
73
"Create Garbage Collector Module Metadata", false, false)
74
75
// -----------------------------------------------------------------------------
76
77
GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S)
78
: F(F), S(S), FrameSize(~0LL) {}
79
80
GCFunctionInfo::~GCFunctionInfo() = default;
81
82
bool GCFunctionInfo::invalidate(Function &F, const PreservedAnalyses &PA,
83
FunctionAnalysisManager::Invalidator &) {
84
auto PAC = PA.getChecker<GCFunctionAnalysis>();
85
return !PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>();
86
}
87
88
// -----------------------------------------------------------------------------
89
90
char GCModuleInfo::ID = 0;
91
92
GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) {
93
initializeGCModuleInfoPass(*PassRegistry::getPassRegistry());
94
}
95
96
GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) {
97
assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!");
98
assert(F.hasGC());
99
100
finfo_map_type::iterator I = FInfoMap.find(&F);
101
if (I != FInfoMap.end())
102
return *I->second;
103
104
GCStrategy *S = getGCStrategy(F.getGC());
105
Functions.push_back(std::make_unique<GCFunctionInfo>(F, *S));
106
GCFunctionInfo *GFI = Functions.back().get();
107
FInfoMap[&F] = GFI;
108
return *GFI;
109
}
110
111
void GCModuleInfo::clear() {
112
Functions.clear();
113
FInfoMap.clear();
114
GCStrategyList.clear();
115
}
116
117
// -----------------------------------------------------------------------------
118
119
GCStrategy *GCModuleInfo::getGCStrategy(const StringRef Name) {
120
// TODO: Arguably, just doing a linear search would be faster for small N
121
auto NMI = GCStrategyMap.find(Name);
122
if (NMI != GCStrategyMap.end())
123
return NMI->getValue();
124
125
std::unique_ptr<GCStrategy> S = llvm::getGCStrategy(Name);
126
S->Name = std::string(Name);
127
GCStrategyMap[Name] = S.get();
128
GCStrategyList.push_back(std::move(S));
129
return GCStrategyList.back().get();
130
}
131
132