File indexing completed on 2026-05-10 08:43:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #ifndef LLVM_CODEGEN_GCMETADATA_H
0033 #define LLVM_CODEGEN_GCMETADATA_H
0034
0035 #include "llvm/ADT/DenseMap.h"
0036 #include "llvm/ADT/SmallVector.h"
0037 #include "llvm/ADT/StringMap.h"
0038 #include "llvm/ADT/StringRef.h"
0039 #include "llvm/IR/DebugLoc.h"
0040 #include "llvm/IR/GCStrategy.h"
0041 #include "llvm/IR/PassManager.h"
0042 #include "llvm/Pass.h"
0043 #include <algorithm>
0044 #include <cstddef>
0045 #include <cstdint>
0046 #include <memory>
0047 #include <vector>
0048
0049 namespace llvm {
0050
0051 class Constant;
0052 class Function;
0053 class MCSymbol;
0054
0055
0056
0057 struct GCPoint {
0058 MCSymbol *Label;
0059 DebugLoc Loc;
0060
0061 GCPoint(MCSymbol *L, DebugLoc DL)
0062 : Label(L), Loc(std::move(DL)) {}
0063 };
0064
0065
0066
0067 struct GCRoot {
0068 int Num;
0069 int StackOffset = -1;
0070 const Constant *Metadata;
0071
0072
0073 GCRoot(int N, const Constant *MD) : Num(N), Metadata(MD) {}
0074 };
0075
0076
0077
0078 class GCFunctionInfo {
0079 public:
0080 using iterator = std::vector<GCPoint>::iterator;
0081 using roots_iterator = std::vector<GCRoot>::iterator;
0082 using live_iterator = std::vector<GCRoot>::const_iterator;
0083
0084 private:
0085 const Function &F;
0086 GCStrategy &S;
0087 uint64_t FrameSize;
0088 std::vector<GCRoot> Roots;
0089 std::vector<GCPoint> SafePoints;
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 public:
0102 GCFunctionInfo(const Function &F, GCStrategy &S);
0103 ~GCFunctionInfo();
0104
0105
0106 bool invalidate(Function &F, const PreservedAnalyses &PA,
0107 FunctionAnalysisManager::Invalidator &Inv);
0108
0109
0110 const Function &getFunction() const { return F; }
0111
0112
0113 GCStrategy &getStrategy() { return S; }
0114
0115
0116
0117
0118 void addStackRoot(int Num, const Constant *Metadata) {
0119 Roots.push_back(GCRoot(Num, Metadata));
0120 }
0121
0122
0123 roots_iterator removeStackRoot(roots_iterator position) {
0124 return Roots.erase(position);
0125 }
0126
0127
0128
0129
0130 void addSafePoint(MCSymbol *Label, const DebugLoc &DL) {
0131 SafePoints.emplace_back(Label, DL);
0132 }
0133
0134
0135 uint64_t getFrameSize() const { return FrameSize; }
0136 void setFrameSize(uint64_t S) { FrameSize = S; }
0137
0138
0139 iterator begin() { return SafePoints.begin(); }
0140 iterator end() { return SafePoints.end(); }
0141 size_t size() const { return SafePoints.size(); }
0142
0143
0144 roots_iterator roots_begin() { return Roots.begin(); }
0145 roots_iterator roots_end() { return Roots.end(); }
0146 size_t roots_size() const { return Roots.size(); }
0147
0148
0149 live_iterator live_begin(const iterator &p) { return roots_begin(); }
0150 live_iterator live_end(const iterator &p) { return roots_end(); }
0151 size_t live_size(const iterator &p) const { return roots_size(); }
0152 };
0153
0154 struct GCStrategyMap {
0155 StringMap<std::unique_ptr<GCStrategy>> StrategyMap;
0156
0157 GCStrategyMap() = default;
0158 GCStrategyMap(GCStrategyMap &&) = default;
0159
0160
0161 bool invalidate(Module &M, const PreservedAnalyses &PA,
0162 ModuleAnalysisManager::Invalidator &Inv);
0163 };
0164
0165
0166
0167 class CollectorMetadataAnalysis
0168 : public AnalysisInfoMixin<CollectorMetadataAnalysis> {
0169 friend struct AnalysisInfoMixin<CollectorMetadataAnalysis>;
0170 static AnalysisKey Key;
0171
0172 public:
0173 using Result = GCStrategyMap;
0174 Result run(Module &M, ModuleAnalysisManager &MAM);
0175 };
0176
0177
0178
0179
0180 class GCFunctionAnalysis : public AnalysisInfoMixin<GCFunctionAnalysis> {
0181 friend struct AnalysisInfoMixin<GCFunctionAnalysis>;
0182 static AnalysisKey Key;
0183
0184 public:
0185 using Result = GCFunctionInfo;
0186 Result run(Function &F, FunctionAnalysisManager &FAM);
0187 };
0188
0189
0190
0191
0192
0193
0194
0195 class GCLoweringPass : public PassInfoMixin<GCLoweringPass> {
0196 public:
0197 PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
0198 };
0199
0200
0201
0202
0203 class GCModuleInfo : public ImmutablePass {
0204
0205 SmallVector<std::unique_ptr<GCStrategy>, 1> GCStrategyList;
0206
0207 StringMap<GCStrategy*> GCStrategyMap;
0208
0209 public:
0210
0211
0212
0213 GCStrategy *getGCStrategy(const StringRef Name);
0214
0215
0216
0217 using FuncInfoVec = std::vector<std::unique_ptr<GCFunctionInfo>>;
0218
0219 FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
0220 FuncInfoVec::iterator funcinfo_end() { return Functions.end(); }
0221
0222 private:
0223
0224 FuncInfoVec Functions;
0225
0226
0227
0228 using finfo_map_type = DenseMap<const Function *, GCFunctionInfo *>;
0229 finfo_map_type FInfoMap;
0230
0231 public:
0232 using iterator = SmallVector<std::unique_ptr<GCStrategy>, 1>::const_iterator;
0233
0234 static char ID;
0235
0236 GCModuleInfo();
0237
0238
0239
0240
0241 void clear();
0242
0243
0244
0245 iterator begin() const { return GCStrategyList.begin(); }
0246 iterator end() const { return GCStrategyList.end(); }
0247
0248
0249
0250
0251 GCFunctionInfo &getFunctionInfo(const Function &F);
0252 };
0253
0254 }
0255
0256 #endif