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