Line data Source code
1 : //===- GCMetadata.h - Garbage collector metadata ----------------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file declares the GCFunctionInfo and GCModuleInfo classes, which are
11 : // used as a communication channel from the target code generator to the target
12 : // garbage collectors. This interface allows code generators and garbage
13 : // collectors to be developed independently.
14 : //
15 : // The GCFunctionInfo class logs the data necessary to build a type accurate
16 : // stack map. The code generator outputs:
17 : //
18 : // - Safe points as specified by the GCStrategy's NeededSafePoints.
19 : // - Stack offsets for GC roots, as specified by calls to llvm.gcroot
20 : //
21 : // As a refinement, liveness analysis calculates the set of live roots at each
22 : // safe point. Liveness analysis is not presently performed by the code
23 : // generator, so all roots are assumed live.
24 : //
25 : // GCModuleInfo simply collects GCFunctionInfo instances for each Function as
26 : // they are compiled. This accretion is necessary for collectors which must emit
27 : // a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo
28 : // outlives the MachineFunction from which it is derived and must not refer to
29 : // any code generator data structures.
30 : //
31 : //===----------------------------------------------------------------------===//
32 :
33 : #ifndef LLVM_CODEGEN_GCMETADATA_H
34 : #define LLVM_CODEGEN_GCMETADATA_H
35 :
36 : #include "llvm/ADT/DenseMap.h"
37 : #include "llvm/ADT/SmallVector.h"
38 : #include "llvm/ADT/StringMap.h"
39 : #include "llvm/ADT/StringRef.h"
40 : #include "llvm/CodeGen/GCStrategy.h"
41 : #include "llvm/IR/DebugLoc.h"
42 : #include "llvm/Pass.h"
43 : #include <algorithm>
44 : #include <cstddef>
45 : #include <cstdint>
46 : #include <memory>
47 : #include <vector>
48 :
49 : namespace llvm {
50 :
51 : class Constant;
52 : class Function;
53 : class MCSymbol;
54 :
55 : /// GCPoint - Metadata for a collector-safe point in machine code.
56 : ///
57 4 : struct GCPoint {
58 : GC::PointKind Kind; ///< The kind of the safe point.
59 : MCSymbol *Label; ///< A label.
60 : DebugLoc Loc;
61 :
62 : GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL)
63 0 : : Kind(K), Label(L), Loc(std::move(DL)) {}
64 : };
65 :
66 : /// GCRoot - Metadata for a pointer to an object managed by the garbage
67 : /// collector.
68 : struct GCRoot {
69 : int Num; ///< Usually a frame index.
70 : int StackOffset = -1; ///< Offset from the stack pointer.
71 : const Constant *Metadata; ///< Metadata straight from the call
72 : ///< to llvm.gcroot.
73 :
74 2 : GCRoot(int N, const Constant *MD) : Num(N), Metadata(MD) {}
75 : };
76 :
77 : /// Garbage collection metadata for a single function. Currently, this
78 : /// information only applies to GCStrategies which use GCRoot.
79 66 : class GCFunctionInfo {
80 : public:
81 : using iterator = std::vector<GCPoint>::iterator;
82 : using roots_iterator = std::vector<GCRoot>::iterator;
83 : using live_iterator = std::vector<GCRoot>::const_iterator;
84 :
85 : private:
86 : const Function &F;
87 : GCStrategy &S;
88 : uint64_t FrameSize;
89 : std::vector<GCRoot> Roots;
90 : std::vector<GCPoint> SafePoints;
91 :
92 : // FIXME: Liveness. A 2D BitVector, perhaps?
93 : //
94 : // BitVector Liveness;
95 : //
96 : // bool islive(int point, int root) =
97 : // Liveness[point * SafePoints.size() + root]
98 : //
99 : // The bit vector is the more compact representation where >3.2% of roots
100 : // are live per safe point (1.5% on 64-bit hosts).
101 :
102 : public:
103 : GCFunctionInfo(const Function &F, GCStrategy &S);
104 : ~GCFunctionInfo();
105 :
106 : /// getFunction - Return the function to which this metadata applies.
107 0 : const Function &getFunction() const { return F; }
108 :
109 : /// getStrategy - Return the GC strategy for the function.
110 0 : GCStrategy &getStrategy() { return S; }
111 :
112 : /// addStackRoot - Registers a root that lives on the stack. Num is the
113 : /// stack object ID for the alloca (if the code generator is
114 : // using MachineFrameInfo).
115 : void addStackRoot(int Num, const Constant *Metadata) {
116 2 : Roots.push_back(GCRoot(Num, Metadata));
117 : }
118 :
119 : /// removeStackRoot - Removes a root.
120 : roots_iterator removeStackRoot(roots_iterator position) {
121 : return Roots.erase(position);
122 : }
123 :
124 : /// addSafePoint - Notes the existence of a safe point. Num is the ID of the
125 : /// label just prior to the safe point (if the code generator is using
126 : /// MachineModuleInfo).
127 : void addSafePoint(GC::PointKind Kind, MCSymbol *Label, const DebugLoc &DL) {
128 4 : SafePoints.emplace_back(Kind, Label, DL);
129 : }
130 :
131 : /// getFrameSize/setFrameSize - Records the function's frame size.
132 0 : uint64_t getFrameSize() const { return FrameSize; }
133 66 : void setFrameSize(uint64_t S) { FrameSize = S; }
134 :
135 : /// begin/end - Iterators for safe points.
136 : iterator begin() { return SafePoints.begin(); }
137 : iterator end() { return SafePoints.end(); }
138 3 : size_t size() const { return SafePoints.size(); }
139 :
140 : /// roots_begin/roots_end - Iterators for all roots in the function.
141 : roots_iterator roots_begin() { return Roots.begin(); }
142 : roots_iterator roots_end() { return Roots.end(); }
143 4 : size_t roots_size() const { return Roots.size(); }
144 :
145 : /// live_begin/live_end - Iterators for live roots at a given safe point.
146 0 : live_iterator live_begin(const iterator &p) { return roots_begin(); }
147 0 : live_iterator live_end(const iterator &p) { return roots_end(); }
148 0 : size_t live_size(const iterator &p) const { return roots_size(); }
149 : };
150 :
151 : /// An analysis pass which caches information about the entire Module.
152 : /// Records both the function level information used by GCRoots and a
153 : /// cache of the 'active' gc strategy objects for the current Module.
154 : class GCModuleInfo : public ImmutablePass {
155 : /// An owning list of all GCStrategies which have been created
156 : SmallVector<std::unique_ptr<GCStrategy>, 1> GCStrategyList;
157 : /// A helper map to speedup lookups into the above list
158 : StringMap<GCStrategy*> GCStrategyMap;
159 :
160 : public:
161 : /// Lookup the GCStrategy object associated with the given gc name.
162 : /// Objects are owned internally; No caller should attempt to delete the
163 : /// returned objects.
164 : GCStrategy *getGCStrategy(const StringRef Name);
165 :
166 : /// List of per function info objects. In theory, Each of these
167 : /// may be associated with a different GC.
168 : using FuncInfoVec = std::vector<std::unique_ptr<GCFunctionInfo>>;
169 :
170 : FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); }
171 : FuncInfoVec::iterator funcinfo_end() { return Functions.end(); }
172 :
173 : private:
174 : /// Owning list of all GCFunctionInfos associated with this Module
175 : FuncInfoVec Functions;
176 :
177 : /// Non-owning map to bypass linear search when finding the GCFunctionInfo
178 : /// associated with a particular Function.
179 : using finfo_map_type = DenseMap<const Function *, GCFunctionInfo *>;
180 : finfo_map_type FInfoMap;
181 :
182 : public:
183 : using iterator = SmallVector<std::unique_ptr<GCStrategy>, 1>::const_iterator;
184 :
185 : static char ID;
186 :
187 : GCModuleInfo();
188 :
189 : /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should
190 : /// call it in doFinalization().
191 : ///
192 : void clear();
193 :
194 : /// begin/end - Iterators for used strategies.
195 : ///
196 : iterator begin() const { return GCStrategyList.begin(); }
197 : iterator end() const { return GCStrategyList.end(); }
198 :
199 : /// get - Look up function metadata. This is currently assumed
200 : /// have the side effect of initializing the associated GCStrategy. That
201 : /// will soon change.
202 : GCFunctionInfo &getFunctionInfo(const Function &F);
203 : };
204 :
205 : } // end namespace llvm
206 :
207 : #endif // LLVM_CODEGEN_GCMETADATA_H
|