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