1 | //===---- llvm/MDBuilder.cpp - Builder for LLVM 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 defines the MDBuilder class, which is used as a convenient way to |
10 | // create LLVM metadata with a consistent and simplified interface. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "llvm/IR/MDBuilder.h" |
15 | #include "llvm/IR/Constants.h" |
16 | #include "llvm/IR/Function.h" |
17 | #include "llvm/IR/Metadata.h" |
18 | using namespace llvm; |
19 | |
20 | MDString *MDBuilder::createString(StringRef Str) { |
21 | return MDString::get(Context, Str); |
22 | } |
23 | |
24 | ConstantAsMetadata *MDBuilder::createConstant(Constant *C) { |
25 | return ConstantAsMetadata::get(C); |
26 | } |
27 | |
28 | MDNode *MDBuilder::createFPMath(float Accuracy) { |
29 | if (Accuracy == 0.0) |
30 | return nullptr; |
31 | assert(Accuracy > 0.0 && "Invalid fpmath accuracy!" ); |
32 | auto *Op = |
33 | createConstant(C: ConstantFP::get(Ty: Type::getFloatTy(C&: Context), V: Accuracy)); |
34 | return MDNode::get(Context, MDs: Op); |
35 | } |
36 | |
37 | MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight, |
38 | uint32_t FalseWeight, bool IsExpected) { |
39 | return createBranchWeights(Weights: {TrueWeight, FalseWeight}, IsExpected); |
40 | } |
41 | |
42 | MDNode *MDBuilder::createLikelyBranchWeights() { |
43 | // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp |
44 | return createBranchWeights(TrueWeight: (1U << 20) - 1, FalseWeight: 1); |
45 | } |
46 | |
47 | MDNode *MDBuilder::createUnlikelyBranchWeights() { |
48 | // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp |
49 | return createBranchWeights(TrueWeight: 1, FalseWeight: (1U << 20) - 1); |
50 | } |
51 | |
52 | MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights, |
53 | bool IsExpected) { |
54 | assert(Weights.size() >= 1 && "Need at least one branch weights!" ); |
55 | |
56 | unsigned int Offset = IsExpected ? 2 : 1; |
57 | SmallVector<Metadata *, 4> Vals(Weights.size() + Offset); |
58 | Vals[0] = createString(Str: "branch_weights" ); |
59 | if (IsExpected) |
60 | Vals[1] = createString(Str: "expected" ); |
61 | |
62 | Type *Int32Ty = Type::getInt32Ty(C&: Context); |
63 | for (unsigned i = 0, e = Weights.size(); i != e; ++i) |
64 | Vals[i + Offset] = createConstant(C: ConstantInt::get(Ty: Int32Ty, V: Weights[i])); |
65 | |
66 | return MDNode::get(Context, MDs: Vals); |
67 | } |
68 | |
69 | MDNode *MDBuilder::createUnpredictable() { |
70 | return MDNode::get(Context, MDs: std::nullopt); |
71 | } |
72 | |
73 | MDNode *MDBuilder::createFunctionEntryCount( |
74 | uint64_t Count, bool Synthetic, |
75 | const DenseSet<GlobalValue::GUID> *Imports) { |
76 | Type *Int64Ty = Type::getInt64Ty(C&: Context); |
77 | SmallVector<Metadata *, 8> Ops; |
78 | if (Synthetic) |
79 | Ops.push_back(Elt: createString(Str: "synthetic_function_entry_count" )); |
80 | else |
81 | Ops.push_back(Elt: createString(Str: "function_entry_count" )); |
82 | Ops.push_back(Elt: createConstant(C: ConstantInt::get(Ty: Int64Ty, V: Count))); |
83 | if (Imports) { |
84 | SmallVector<GlobalValue::GUID, 2> OrderID(Imports->begin(), Imports->end()); |
85 | llvm::sort(C&: OrderID); |
86 | for (auto ID : OrderID) |
87 | Ops.push_back(Elt: createConstant(C: ConstantInt::get(Ty: Int64Ty, V: ID))); |
88 | } |
89 | return MDNode::get(Context, MDs: Ops); |
90 | } |
91 | |
92 | MDNode *MDBuilder::createFunctionSectionPrefix(StringRef Prefix) { |
93 | return MDNode::get( |
94 | Context, MDs: {createString(Str: "function_section_prefix" ), createString(Str: Prefix)}); |
95 | } |
96 | |
97 | MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) { |
98 | assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!" ); |
99 | |
100 | Type *Ty = IntegerType::get(C&: Context, NumBits: Lo.getBitWidth()); |
101 | return createRange(Lo: ConstantInt::get(Ty, V: Lo), Hi: ConstantInt::get(Ty, V: Hi)); |
102 | } |
103 | |
104 | MDNode *MDBuilder::createRange(Constant *Lo, Constant *Hi) { |
105 | // If the range is everything then it is useless. |
106 | if (Hi == Lo) |
107 | return nullptr; |
108 | |
109 | // Return the range [Lo, Hi). |
110 | return MDNode::get(Context, MDs: {createConstant(C: Lo), createConstant(C: Hi)}); |
111 | } |
112 | |
113 | MDNode *MDBuilder::createCallees(ArrayRef<Function *> Callees) { |
114 | SmallVector<Metadata *, 4> Ops; |
115 | for (Function *F : Callees) |
116 | Ops.push_back(Elt: createConstant(C: F)); |
117 | return MDNode::get(Context, MDs: Ops); |
118 | } |
119 | |
120 | MDNode *MDBuilder::createCallbackEncoding(unsigned CalleeArgNo, |
121 | ArrayRef<int> Arguments, |
122 | bool VarArgArePassed) { |
123 | SmallVector<Metadata *, 4> Ops; |
124 | |
125 | Type *Int64 = Type::getInt64Ty(C&: Context); |
126 | Ops.push_back(Elt: createConstant(C: ConstantInt::get(Ty: Int64, V: CalleeArgNo))); |
127 | |
128 | for (int ArgNo : Arguments) |
129 | Ops.push_back(Elt: createConstant(C: ConstantInt::get(Ty: Int64, V: ArgNo, IsSigned: true))); |
130 | |
131 | Type *Int1 = Type::getInt1Ty(C&: Context); |
132 | Ops.push_back(Elt: createConstant(C: ConstantInt::get(Ty: Int1, V: VarArgArePassed))); |
133 | |
134 | return MDNode::get(Context, MDs: Ops); |
135 | } |
136 | |
137 | MDNode *MDBuilder::mergeCallbackEncodings(MDNode *ExistingCallbacks, |
138 | MDNode *NewCB) { |
139 | if (!ExistingCallbacks) |
140 | return MDNode::get(Context, MDs: {NewCB}); |
141 | |
142 | auto *NewCBCalleeIdxAsCM = cast<ConstantAsMetadata>(Val: NewCB->getOperand(I: 0)); |
143 | uint64_t NewCBCalleeIdx = |
144 | cast<ConstantInt>(Val: NewCBCalleeIdxAsCM->getValue())->getZExtValue(); |
145 | (void)NewCBCalleeIdx; |
146 | |
147 | SmallVector<Metadata *, 4> Ops; |
148 | unsigned NumExistingOps = ExistingCallbacks->getNumOperands(); |
149 | Ops.resize(N: NumExistingOps + 1); |
150 | |
151 | for (unsigned u = 0; u < NumExistingOps; u++) { |
152 | Ops[u] = ExistingCallbacks->getOperand(I: u); |
153 | |
154 | auto *OldCBCalleeIdxAsCM = |
155 | cast<ConstantAsMetadata>(Val: cast<MDNode>(Val: Ops[u])->getOperand(I: 0)); |
156 | uint64_t OldCBCalleeIdx = |
157 | cast<ConstantInt>(Val: OldCBCalleeIdxAsCM->getValue())->getZExtValue(); |
158 | (void)OldCBCalleeIdx; |
159 | assert(NewCBCalleeIdx != OldCBCalleeIdx && |
160 | "Cannot map a callback callee index twice!" ); |
161 | } |
162 | |
163 | Ops[NumExistingOps] = NewCB; |
164 | return MDNode::get(Context, MDs: Ops); |
165 | } |
166 | |
167 | MDNode *MDBuilder::createRTTIPointerPrologue(Constant *PrologueSig, |
168 | Constant *RTTI) { |
169 | SmallVector<Metadata *, 4> Ops; |
170 | Ops.push_back(Elt: createConstant(C: PrologueSig)); |
171 | Ops.push_back(Elt: createConstant(C: RTTI)); |
172 | return MDNode::get(Context, MDs: Ops); |
173 | } |
174 | |
175 | MDNode *MDBuilder::createPCSections(ArrayRef<PCSection> Sections) { |
176 | SmallVector<Metadata *, 2> Ops; |
177 | |
178 | for (const auto &Entry : Sections) { |
179 | const StringRef &Sec = Entry.first; |
180 | Ops.push_back(Elt: createString(Str: Sec)); |
181 | |
182 | // If auxiliary data for this section exists, append it. |
183 | const SmallVector<Constant *> &AuxConsts = Entry.second; |
184 | if (!AuxConsts.empty()) { |
185 | SmallVector<Metadata *, 1> AuxMDs; |
186 | AuxMDs.reserve(N: AuxConsts.size()); |
187 | for (Constant *C : AuxConsts) |
188 | AuxMDs.push_back(Elt: createConstant(C)); |
189 | Ops.push_back(Elt: MDNode::get(Context, MDs: AuxMDs)); |
190 | } |
191 | } |
192 | |
193 | return MDNode::get(Context, MDs: Ops); |
194 | } |
195 | |
196 | MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *) { |
197 | SmallVector<Metadata *, 3> Args(1, nullptr); |
198 | if (Extra) |
199 | Args.push_back(Elt: Extra); |
200 | if (!Name.empty()) |
201 | Args.push_back(Elt: createString(Str: Name)); |
202 | MDNode *Root = MDNode::getDistinct(Context, MDs: Args); |
203 | |
204 | // At this point we have |
205 | // !0 = distinct !{null} <- root |
206 | // Replace the reserved operand with the root node itself. |
207 | Root->replaceOperandWith(I: 0, New: Root); |
208 | |
209 | // We now have |
210 | // !0 = distinct !{!0} <- root |
211 | return Root; |
212 | } |
213 | |
214 | MDNode *MDBuilder::createTBAARoot(StringRef Name) { |
215 | return MDNode::get(Context, MDs: createString(Str: Name)); |
216 | } |
217 | |
218 | /// Return metadata for a non-root TBAA node with the given name, |
219 | /// parent in the TBAA tree, and value for 'pointsToConstantMemory'. |
220 | MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent, |
221 | bool isConstant) { |
222 | if (isConstant) { |
223 | Constant *Flags = ConstantInt::get(Ty: Type::getInt64Ty(C&: Context), V: 1); |
224 | return MDNode::get(Context, |
225 | MDs: {createString(Str: Name), Parent, createConstant(C: Flags)}); |
226 | } |
227 | return MDNode::get(Context, MDs: {createString(Str: Name), Parent}); |
228 | } |
229 | |
230 | MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) { |
231 | return MDNode::get(Context, MDs: createString(Str: Name)); |
232 | } |
233 | |
234 | MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) { |
235 | return MDNode::get(Context, MDs: {createString(Str: Name), Domain}); |
236 | } |
237 | |
238 | /// Return metadata for a tbaa.struct node with the given |
239 | /// struct field descriptions. |
240 | MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) { |
241 | SmallVector<Metadata *, 4> Vals(Fields.size() * 3); |
242 | Type *Int64 = Type::getInt64Ty(C&: Context); |
243 | for (unsigned i = 0, e = Fields.size(); i != e; ++i) { |
244 | Vals[i * 3 + 0] = createConstant(C: ConstantInt::get(Ty: Int64, V: Fields[i].Offset)); |
245 | Vals[i * 3 + 1] = createConstant(C: ConstantInt::get(Ty: Int64, V: Fields[i].Size)); |
246 | Vals[i * 3 + 2] = Fields[i].Type; |
247 | } |
248 | return MDNode::get(Context, MDs: Vals); |
249 | } |
250 | |
251 | /// Return metadata for a TBAA struct node in the type DAG |
252 | /// with the given name, a list of pairs (offset, field type in the type DAG). |
253 | MDNode *MDBuilder::createTBAAStructTypeNode( |
254 | StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) { |
255 | SmallVector<Metadata *, 4> Ops(Fields.size() * 2 + 1); |
256 | Type *Int64 = Type::getInt64Ty(C&: Context); |
257 | Ops[0] = createString(Str: Name); |
258 | for (unsigned i = 0, e = Fields.size(); i != e; ++i) { |
259 | Ops[i * 2 + 1] = Fields[i].first; |
260 | Ops[i * 2 + 2] = createConstant(C: ConstantInt::get(Ty: Int64, V: Fields[i].second)); |
261 | } |
262 | return MDNode::get(Context, MDs: Ops); |
263 | } |
264 | |
265 | /// Return metadata for a TBAA scalar type node with the |
266 | /// given name, an offset and a parent in the TBAA type DAG. |
267 | MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent, |
268 | uint64_t Offset) { |
269 | ConstantInt *Off = ConstantInt::get(Ty: Type::getInt64Ty(C&: Context), V: Offset); |
270 | return MDNode::get(Context, |
271 | MDs: {createString(Str: Name), Parent, createConstant(C: Off)}); |
272 | } |
273 | |
274 | /// Return metadata for a TBAA tag node with the given |
275 | /// base type, access type and offset relative to the base type. |
276 | MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType, |
277 | uint64_t Offset, bool IsConstant) { |
278 | IntegerType *Int64 = Type::getInt64Ty(C&: Context); |
279 | ConstantInt *Off = ConstantInt::get(Ty: Int64, V: Offset); |
280 | if (IsConstant) { |
281 | return MDNode::get(Context, MDs: {BaseType, AccessType, createConstant(C: Off), |
282 | createConstant(C: ConstantInt::get(Ty: Int64, V: 1))}); |
283 | } |
284 | return MDNode::get(Context, MDs: {BaseType, AccessType, createConstant(C: Off)}); |
285 | } |
286 | |
287 | MDNode *MDBuilder::createTBAATypeNode(MDNode *Parent, uint64_t Size, |
288 | Metadata *Id, |
289 | ArrayRef<TBAAStructField> Fields) { |
290 | SmallVector<Metadata *, 4> Ops(3 + Fields.size() * 3); |
291 | Type *Int64 = Type::getInt64Ty(C&: Context); |
292 | Ops[0] = Parent; |
293 | Ops[1] = createConstant(C: ConstantInt::get(Ty: Int64, V: Size)); |
294 | Ops[2] = Id; |
295 | for (unsigned I = 0, E = Fields.size(); I != E; ++I) { |
296 | Ops[I * 3 + 3] = Fields[I].Type; |
297 | Ops[I * 3 + 4] = createConstant(C: ConstantInt::get(Ty: Int64, V: Fields[I].Offset)); |
298 | Ops[I * 3 + 5] = createConstant(C: ConstantInt::get(Ty: Int64, V: Fields[I].Size)); |
299 | } |
300 | return MDNode::get(Context, MDs: Ops); |
301 | } |
302 | |
303 | MDNode *MDBuilder::createTBAAAccessTag(MDNode *BaseType, MDNode *AccessType, |
304 | uint64_t Offset, uint64_t Size, |
305 | bool IsImmutable) { |
306 | IntegerType *Int64 = Type::getInt64Ty(C&: Context); |
307 | auto *OffsetNode = createConstant(C: ConstantInt::get(Ty: Int64, V: Offset)); |
308 | auto *SizeNode = createConstant(C: ConstantInt::get(Ty: Int64, V: Size)); |
309 | if (IsImmutable) { |
310 | auto *ImmutabilityFlagNode = createConstant(C: ConstantInt::get(Ty: Int64, V: 1)); |
311 | return MDNode::get(Context, MDs: {BaseType, AccessType, OffsetNode, SizeNode, |
312 | ImmutabilityFlagNode}); |
313 | } |
314 | return MDNode::get(Context, MDs: {BaseType, AccessType, OffsetNode, SizeNode}); |
315 | } |
316 | |
317 | MDNode *MDBuilder::createMutableTBAAAccessTag(MDNode *Tag) { |
318 | MDNode *BaseType = cast<MDNode>(Val: Tag->getOperand(I: 0)); |
319 | MDNode *AccessType = cast<MDNode>(Val: Tag->getOperand(I: 1)); |
320 | Metadata *OffsetNode = Tag->getOperand(I: 2); |
321 | uint64_t Offset = mdconst::extract<ConstantInt>(MD&: OffsetNode)->getZExtValue(); |
322 | |
323 | bool NewFormat = isa<MDNode>(Val: AccessType->getOperand(I: 0)); |
324 | |
325 | // See if the tag is already mutable. |
326 | unsigned ImmutabilityFlagOp = NewFormat ? 4 : 3; |
327 | if (Tag->getNumOperands() <= ImmutabilityFlagOp) |
328 | return Tag; |
329 | |
330 | // If Tag is already mutable then return it. |
331 | Metadata *ImmutabilityFlagNode = Tag->getOperand(I: ImmutabilityFlagOp); |
332 | if (!mdconst::extract<ConstantInt>(MD&: ImmutabilityFlagNode)->getValue()) |
333 | return Tag; |
334 | |
335 | // Otherwise, create another node. |
336 | if (!NewFormat) |
337 | return createTBAAStructTagNode(BaseType, AccessType, Offset); |
338 | |
339 | Metadata *SizeNode = Tag->getOperand(I: 3); |
340 | uint64_t Size = mdconst::extract<ConstantInt>(MD&: SizeNode)->getZExtValue(); |
341 | return createTBAAAccessTag(BaseType, AccessType, Offset, Size); |
342 | } |
343 | |
344 | MDNode *MDBuilder::(uint64_t Weight) { |
345 | Metadata *Vals[] = { |
346 | createString(Str: "loop_header_weight" ), |
347 | createConstant(C: ConstantInt::get(Ty: Type::getInt64Ty(C&: Context), V: Weight)), |
348 | }; |
349 | return MDNode::get(Context, MDs: Vals); |
350 | } |
351 | |
352 | MDNode *MDBuilder::createPseudoProbeDesc(uint64_t GUID, uint64_t Hash, |
353 | StringRef FName) { |
354 | auto *Int64Ty = Type::getInt64Ty(C&: Context); |
355 | SmallVector<Metadata *, 3> Ops(3); |
356 | Ops[0] = createConstant(C: ConstantInt::get(Ty: Int64Ty, V: GUID)); |
357 | Ops[1] = createConstant(C: ConstantInt::get(Ty: Int64Ty, V: Hash)); |
358 | Ops[2] = createString(Str: FName); |
359 | return MDNode::get(Context, MDs: Ops); |
360 | } |
361 | |
362 | MDNode * |
363 | MDBuilder::createLLVMStats(ArrayRef<std::pair<StringRef, uint64_t>> LLVMStats) { |
364 | auto *Int64Ty = Type::getInt64Ty(C&: Context); |
365 | SmallVector<Metadata *, 4> Ops(LLVMStats.size() * 2); |
366 | for (size_t I = 0; I < LLVMStats.size(); I++) { |
367 | Ops[I * 2] = createString(Str: LLVMStats[I].first); |
368 | Ops[I * 2 + 1] = |
369 | createConstant(C: ConstantInt::get(Ty: Int64Ty, V: LLVMStats[I].second)); |
370 | } |
371 | return MDNode::get(Context, MDs: Ops); |
372 | } |
373 | |