xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/MDBuilder.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===---- llvm/MDBuilder.cpp - Builder for LLVM metadata ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the MDBuilder class, which is used as a convenient way to
100b57cec5SDimitry Andric // create LLVM metadata with a consistent and simplified interface.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h"
150b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
160b57cec5SDimitry Andric #include "llvm/IR/Function.h"
170b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric MDString *MDBuilder::createString(StringRef Str) {
210b57cec5SDimitry Andric   return MDString::get(Context, Str);
220b57cec5SDimitry Andric }
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric ConstantAsMetadata *MDBuilder::createConstant(Constant *C) {
250b57cec5SDimitry Andric   return ConstantAsMetadata::get(C);
260b57cec5SDimitry Andric }
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric MDNode *MDBuilder::createFPMath(float Accuracy) {
290b57cec5SDimitry Andric   if (Accuracy == 0.0)
300b57cec5SDimitry Andric     return nullptr;
310b57cec5SDimitry Andric   assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
320b57cec5SDimitry Andric   auto *Op =
330b57cec5SDimitry Andric       createConstant(ConstantFP::get(Type::getFloatTy(Context), Accuracy));
340b57cec5SDimitry Andric   return MDNode::get(Context, Op);
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric MDNode *MDBuilder::createBranchWeights(uint32_t TrueWeight,
38*0fca6ea1SDimitry Andric                                        uint32_t FalseWeight, bool IsExpected) {
39*0fca6ea1SDimitry Andric   return createBranchWeights({TrueWeight, FalseWeight}, IsExpected);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
42*0fca6ea1SDimitry Andric MDNode *MDBuilder::createLikelyBranchWeights() {
43*0fca6ea1SDimitry Andric   // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp
44*0fca6ea1SDimitry Andric   return createBranchWeights((1U << 20) - 1, 1);
45*0fca6ea1SDimitry Andric }
46*0fca6ea1SDimitry Andric 
47*0fca6ea1SDimitry Andric MDNode *MDBuilder::createUnlikelyBranchWeights() {
48*0fca6ea1SDimitry Andric   // Value chosen to match UR_NONTAKEN_WEIGHT, see BranchProbabilityInfo.cpp
49*0fca6ea1SDimitry Andric   return createBranchWeights(1, (1U << 20) - 1);
50*0fca6ea1SDimitry Andric }
51*0fca6ea1SDimitry Andric 
52*0fca6ea1SDimitry Andric MDNode *MDBuilder::createBranchWeights(ArrayRef<uint32_t> Weights,
53*0fca6ea1SDimitry Andric                                        bool IsExpected) {
540b57cec5SDimitry Andric   assert(Weights.size() >= 1 && "Need at least one branch weights!");
550b57cec5SDimitry Andric 
56*0fca6ea1SDimitry Andric   unsigned int Offset = IsExpected ? 2 : 1;
57*0fca6ea1SDimitry Andric   SmallVector<Metadata *, 4> Vals(Weights.size() + Offset);
580b57cec5SDimitry Andric   Vals[0] = createString("branch_weights");
59*0fca6ea1SDimitry Andric   if (IsExpected)
60*0fca6ea1SDimitry Andric     Vals[1] = createString("expected");
610b57cec5SDimitry Andric 
620b57cec5SDimitry Andric   Type *Int32Ty = Type::getInt32Ty(Context);
630b57cec5SDimitry Andric   for (unsigned i = 0, e = Weights.size(); i != e; ++i)
64*0fca6ea1SDimitry Andric     Vals[i + Offset] = createConstant(ConstantInt::get(Int32Ty, Weights[i]));
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   return MDNode::get(Context, Vals);
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric MDNode *MDBuilder::createUnpredictable() {
70bdd1243dSDimitry Andric   return MDNode::get(Context, std::nullopt);
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric MDNode *MDBuilder::createFunctionEntryCount(
740b57cec5SDimitry Andric     uint64_t Count, bool Synthetic,
750b57cec5SDimitry Andric     const DenseSet<GlobalValue::GUID> *Imports) {
760b57cec5SDimitry Andric   Type *Int64Ty = Type::getInt64Ty(Context);
770b57cec5SDimitry Andric   SmallVector<Metadata *, 8> Ops;
780b57cec5SDimitry Andric   if (Synthetic)
790b57cec5SDimitry Andric     Ops.push_back(createString("synthetic_function_entry_count"));
800b57cec5SDimitry Andric   else
810b57cec5SDimitry Andric     Ops.push_back(createString("function_entry_count"));
820b57cec5SDimitry Andric   Ops.push_back(createConstant(ConstantInt::get(Int64Ty, Count)));
830b57cec5SDimitry Andric   if (Imports) {
840b57cec5SDimitry Andric     SmallVector<GlobalValue::GUID, 2> OrderID(Imports->begin(), Imports->end());
855ffd83dbSDimitry Andric     llvm::sort(OrderID);
860b57cec5SDimitry Andric     for (auto ID : OrderID)
870b57cec5SDimitry Andric       Ops.push_back(createConstant(ConstantInt::get(Int64Ty, ID)));
880b57cec5SDimitry Andric   }
890b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric MDNode *MDBuilder::createFunctionSectionPrefix(StringRef Prefix) {
93*0fca6ea1SDimitry Andric   return MDNode::get(
94*0fca6ea1SDimitry Andric       Context, {createString("function_section_prefix"), createString(Prefix)});
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric MDNode *MDBuilder::createRange(const APInt &Lo, const APInt &Hi) {
980b57cec5SDimitry Andric   assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
1010b57cec5SDimitry Andric   return createRange(ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi));
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric MDNode *MDBuilder::createRange(Constant *Lo, Constant *Hi) {
1050b57cec5SDimitry Andric   // If the range is everything then it is useless.
1060b57cec5SDimitry Andric   if (Hi == Lo)
1070b57cec5SDimitry Andric     return nullptr;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   // Return the range [Lo, Hi).
1100b57cec5SDimitry Andric   return MDNode::get(Context, {createConstant(Lo), createConstant(Hi)});
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric MDNode *MDBuilder::createCallees(ArrayRef<Function *> Callees) {
1140b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Ops;
1150b57cec5SDimitry Andric   for (Function *F : Callees)
1160b57cec5SDimitry Andric     Ops.push_back(createConstant(F));
1170b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric MDNode *MDBuilder::createCallbackEncoding(unsigned CalleeArgNo,
1210b57cec5SDimitry Andric                                           ArrayRef<int> Arguments,
1220b57cec5SDimitry Andric                                           bool VarArgArePassed) {
1230b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Ops;
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   Type *Int64 = Type::getInt64Ty(Context);
1260b57cec5SDimitry Andric   Ops.push_back(createConstant(ConstantInt::get(Int64, CalleeArgNo)));
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   for (int ArgNo : Arguments)
1290b57cec5SDimitry Andric     Ops.push_back(createConstant(ConstantInt::get(Int64, ArgNo, true)));
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   Type *Int1 = Type::getInt1Ty(Context);
1320b57cec5SDimitry Andric   Ops.push_back(createConstant(ConstantInt::get(Int1, VarArgArePassed)));
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric MDNode *MDBuilder::mergeCallbackEncodings(MDNode *ExistingCallbacks,
1380b57cec5SDimitry Andric                                           MDNode *NewCB) {
1390b57cec5SDimitry Andric   if (!ExistingCallbacks)
1400b57cec5SDimitry Andric     return MDNode::get(Context, {NewCB});
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   auto *NewCBCalleeIdxAsCM = cast<ConstantAsMetadata>(NewCB->getOperand(0));
1430b57cec5SDimitry Andric   uint64_t NewCBCalleeIdx =
1440b57cec5SDimitry Andric       cast<ConstantInt>(NewCBCalleeIdxAsCM->getValue())->getZExtValue();
1450b57cec5SDimitry Andric   (void)NewCBCalleeIdx;
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Ops;
1480b57cec5SDimitry Andric   unsigned NumExistingOps = ExistingCallbacks->getNumOperands();
1490b57cec5SDimitry Andric   Ops.resize(NumExistingOps + 1);
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   for (unsigned u = 0; u < NumExistingOps; u++) {
1520b57cec5SDimitry Andric     Ops[u] = ExistingCallbacks->getOperand(u);
1530b57cec5SDimitry Andric 
154*0fca6ea1SDimitry Andric     auto *OldCBCalleeIdxAsCM =
155*0fca6ea1SDimitry Andric         cast<ConstantAsMetadata>(cast<MDNode>(Ops[u])->getOperand(0));
1560b57cec5SDimitry Andric     uint64_t OldCBCalleeIdx =
1570b57cec5SDimitry Andric         cast<ConstantInt>(OldCBCalleeIdxAsCM->getValue())->getZExtValue();
1580b57cec5SDimitry Andric     (void)OldCBCalleeIdx;
1590b57cec5SDimitry Andric     assert(NewCBCalleeIdx != OldCBCalleeIdx &&
1600b57cec5SDimitry Andric            "Cannot map a callback callee index twice!");
1610b57cec5SDimitry Andric   }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   Ops[NumExistingOps] = NewCB;
1640b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
16781ad6265SDimitry Andric MDNode *MDBuilder::createRTTIPointerPrologue(Constant *PrologueSig,
16881ad6265SDimitry Andric                                              Constant *RTTI) {
16981ad6265SDimitry Andric   SmallVector<Metadata *, 4> Ops;
17081ad6265SDimitry Andric   Ops.push_back(createConstant(PrologueSig));
17181ad6265SDimitry Andric   Ops.push_back(createConstant(RTTI));
17281ad6265SDimitry Andric   return MDNode::get(Context, Ops);
17381ad6265SDimitry Andric }
17481ad6265SDimitry Andric 
175bdd1243dSDimitry Andric MDNode *MDBuilder::createPCSections(ArrayRef<PCSection> Sections) {
176bdd1243dSDimitry Andric   SmallVector<Metadata *, 2> Ops;
177bdd1243dSDimitry Andric 
178bdd1243dSDimitry Andric   for (const auto &Entry : Sections) {
179bdd1243dSDimitry Andric     const StringRef &Sec = Entry.first;
180bdd1243dSDimitry Andric     Ops.push_back(createString(Sec));
181bdd1243dSDimitry Andric 
182bdd1243dSDimitry Andric     // If auxiliary data for this section exists, append it.
183bdd1243dSDimitry Andric     const SmallVector<Constant *> &AuxConsts = Entry.second;
184bdd1243dSDimitry Andric     if (!AuxConsts.empty()) {
185bdd1243dSDimitry Andric       SmallVector<Metadata *, 1> AuxMDs;
186bdd1243dSDimitry Andric       AuxMDs.reserve(AuxConsts.size());
187bdd1243dSDimitry Andric       for (Constant *C : AuxConsts)
188bdd1243dSDimitry Andric         AuxMDs.push_back(createConstant(C));
189bdd1243dSDimitry Andric       Ops.push_back(MDNode::get(Context, AuxMDs));
190bdd1243dSDimitry Andric     }
191bdd1243dSDimitry Andric   }
192bdd1243dSDimitry Andric 
193bdd1243dSDimitry Andric   return MDNode::get(Context, Ops);
194bdd1243dSDimitry Andric }
195bdd1243dSDimitry Andric 
1960b57cec5SDimitry Andric MDNode *MDBuilder::createAnonymousAARoot(StringRef Name, MDNode *Extra) {
197e8d8bef9SDimitry Andric   SmallVector<Metadata *, 3> Args(1, nullptr);
1980b57cec5SDimitry Andric   if (Extra)
1990b57cec5SDimitry Andric     Args.push_back(Extra);
2000b57cec5SDimitry Andric   if (!Name.empty())
2010b57cec5SDimitry Andric     Args.push_back(createString(Name));
202e8d8bef9SDimitry Andric   MDNode *Root = MDNode::getDistinct(Context, Args);
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   // At this point we have
205e8d8bef9SDimitry Andric   //   !0 = distinct !{null} <- root
206e8d8bef9SDimitry Andric   // Replace the reserved operand with the root node itself.
2070b57cec5SDimitry Andric   Root->replaceOperandWith(0, Root);
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   // We now have
210e8d8bef9SDimitry Andric   //   !0 = distinct !{!0} <- root
2110b57cec5SDimitry Andric   return Root;
2120b57cec5SDimitry Andric }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric MDNode *MDBuilder::createTBAARoot(StringRef Name) {
2150b57cec5SDimitry Andric   return MDNode::get(Context, createString(Name));
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric /// Return metadata for a non-root TBAA node with the given name,
2190b57cec5SDimitry Andric /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
2200b57cec5SDimitry Andric MDNode *MDBuilder::createTBAANode(StringRef Name, MDNode *Parent,
2210b57cec5SDimitry Andric                                   bool isConstant) {
2220b57cec5SDimitry Andric   if (isConstant) {
2230b57cec5SDimitry Andric     Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
2240b57cec5SDimitry Andric     return MDNode::get(Context,
2250b57cec5SDimitry Andric                        {createString(Name), Parent, createConstant(Flags)});
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric   return MDNode::get(Context, {createString(Name), Parent});
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric MDNode *MDBuilder::createAliasScopeDomain(StringRef Name) {
2310b57cec5SDimitry Andric   return MDNode::get(Context, createString(Name));
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric MDNode *MDBuilder::createAliasScope(StringRef Name, MDNode *Domain) {
2350b57cec5SDimitry Andric   return MDNode::get(Context, {createString(Name), Domain});
2360b57cec5SDimitry Andric }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric /// Return metadata for a tbaa.struct node with the given
2390b57cec5SDimitry Andric /// struct field descriptions.
2400b57cec5SDimitry Andric MDNode *MDBuilder::createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
2410b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Vals(Fields.size() * 3);
2420b57cec5SDimitry Andric   Type *Int64 = Type::getInt64Ty(Context);
2430b57cec5SDimitry Andric   for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
2440b57cec5SDimitry Andric     Vals[i * 3 + 0] = createConstant(ConstantInt::get(Int64, Fields[i].Offset));
2450b57cec5SDimitry Andric     Vals[i * 3 + 1] = createConstant(ConstantInt::get(Int64, Fields[i].Size));
2460b57cec5SDimitry Andric     Vals[i * 3 + 2] = Fields[i].Type;
2470b57cec5SDimitry Andric   }
2480b57cec5SDimitry Andric   return MDNode::get(Context, Vals);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric /// Return metadata for a TBAA struct node in the type DAG
2520b57cec5SDimitry Andric /// with the given name, a list of pairs (offset, field type in the type DAG).
2530b57cec5SDimitry Andric MDNode *MDBuilder::createTBAAStructTypeNode(
2540b57cec5SDimitry Andric     StringRef Name, ArrayRef<std::pair<MDNode *, uint64_t>> Fields) {
2550b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Ops(Fields.size() * 2 + 1);
2560b57cec5SDimitry Andric   Type *Int64 = Type::getInt64Ty(Context);
2570b57cec5SDimitry Andric   Ops[0] = createString(Name);
2580b57cec5SDimitry Andric   for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
2590b57cec5SDimitry Andric     Ops[i * 2 + 1] = Fields[i].first;
2600b57cec5SDimitry Andric     Ops[i * 2 + 2] = createConstant(ConstantInt::get(Int64, Fields[i].second));
2610b57cec5SDimitry Andric   }
2620b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
2630b57cec5SDimitry Andric }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric /// Return metadata for a TBAA scalar type node with the
2660b57cec5SDimitry Andric /// given name, an offset and a parent in the TBAA type DAG.
2670b57cec5SDimitry Andric MDNode *MDBuilder::createTBAAScalarTypeNode(StringRef Name, MDNode *Parent,
2680b57cec5SDimitry Andric                                             uint64_t Offset) {
2690b57cec5SDimitry Andric   ConstantInt *Off = ConstantInt::get(Type::getInt64Ty(Context), Offset);
2700b57cec5SDimitry Andric   return MDNode::get(Context,
2710b57cec5SDimitry Andric                      {createString(Name), Parent, createConstant(Off)});
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric /// Return metadata for a TBAA tag node with the given
2750b57cec5SDimitry Andric /// base type, access type and offset relative to the base type.
2760b57cec5SDimitry Andric MDNode *MDBuilder::createTBAAStructTagNode(MDNode *BaseType, MDNode *AccessType,
2770b57cec5SDimitry Andric                                            uint64_t Offset, bool IsConstant) {
2780b57cec5SDimitry Andric   IntegerType *Int64 = Type::getInt64Ty(Context);
2790b57cec5SDimitry Andric   ConstantInt *Off = ConstantInt::get(Int64, Offset);
2800b57cec5SDimitry Andric   if (IsConstant) {
2810b57cec5SDimitry Andric     return MDNode::get(Context, {BaseType, AccessType, createConstant(Off),
2820b57cec5SDimitry Andric                                  createConstant(ConstantInt::get(Int64, 1))});
2830b57cec5SDimitry Andric   }
2840b57cec5SDimitry Andric   return MDNode::get(Context, {BaseType, AccessType, createConstant(Off)});
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric MDNode *MDBuilder::createTBAATypeNode(MDNode *Parent, uint64_t Size,
2880b57cec5SDimitry Andric                                       Metadata *Id,
2890b57cec5SDimitry Andric                                       ArrayRef<TBAAStructField> Fields) {
2900b57cec5SDimitry Andric   SmallVector<Metadata *, 4> Ops(3 + Fields.size() * 3);
2910b57cec5SDimitry Andric   Type *Int64 = Type::getInt64Ty(Context);
2920b57cec5SDimitry Andric   Ops[0] = Parent;
2930b57cec5SDimitry Andric   Ops[1] = createConstant(ConstantInt::get(Int64, Size));
2940b57cec5SDimitry Andric   Ops[2] = Id;
2950b57cec5SDimitry Andric   for (unsigned I = 0, E = Fields.size(); I != E; ++I) {
2960b57cec5SDimitry Andric     Ops[I * 3 + 3] = Fields[I].Type;
2970b57cec5SDimitry Andric     Ops[I * 3 + 4] = createConstant(ConstantInt::get(Int64, Fields[I].Offset));
2980b57cec5SDimitry Andric     Ops[I * 3 + 5] = createConstant(ConstantInt::get(Int64, Fields[I].Size));
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric   return MDNode::get(Context, Ops);
3010b57cec5SDimitry Andric }
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric MDNode *MDBuilder::createTBAAAccessTag(MDNode *BaseType, MDNode *AccessType,
3040b57cec5SDimitry Andric                                        uint64_t Offset, uint64_t Size,
3050b57cec5SDimitry Andric                                        bool IsImmutable) {
3060b57cec5SDimitry Andric   IntegerType *Int64 = Type::getInt64Ty(Context);
3070b57cec5SDimitry Andric   auto *OffsetNode = createConstant(ConstantInt::get(Int64, Offset));
3080b57cec5SDimitry Andric   auto *SizeNode = createConstant(ConstantInt::get(Int64, Size));
3090b57cec5SDimitry Andric   if (IsImmutable) {
3100b57cec5SDimitry Andric     auto *ImmutabilityFlagNode = createConstant(ConstantInt::get(Int64, 1));
3110b57cec5SDimitry Andric     return MDNode::get(Context, {BaseType, AccessType, OffsetNode, SizeNode,
3120b57cec5SDimitry Andric                                  ImmutabilityFlagNode});
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric   return MDNode::get(Context, {BaseType, AccessType, OffsetNode, SizeNode});
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric MDNode *MDBuilder::createMutableTBAAAccessTag(MDNode *Tag) {
3180b57cec5SDimitry Andric   MDNode *BaseType = cast<MDNode>(Tag->getOperand(0));
3190b57cec5SDimitry Andric   MDNode *AccessType = cast<MDNode>(Tag->getOperand(1));
3200b57cec5SDimitry Andric   Metadata *OffsetNode = Tag->getOperand(2);
3210b57cec5SDimitry Andric   uint64_t Offset = mdconst::extract<ConstantInt>(OffsetNode)->getZExtValue();
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   bool NewFormat = isa<MDNode>(AccessType->getOperand(0));
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   // See if the tag is already mutable.
3260b57cec5SDimitry Andric   unsigned ImmutabilityFlagOp = NewFormat ? 4 : 3;
3270b57cec5SDimitry Andric   if (Tag->getNumOperands() <= ImmutabilityFlagOp)
3280b57cec5SDimitry Andric     return Tag;
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric   // If Tag is already mutable then return it.
3310b57cec5SDimitry Andric   Metadata *ImmutabilityFlagNode = Tag->getOperand(ImmutabilityFlagOp);
3320b57cec5SDimitry Andric   if (!mdconst::extract<ConstantInt>(ImmutabilityFlagNode)->getValue())
3330b57cec5SDimitry Andric     return Tag;
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric   // Otherwise, create another node.
3360b57cec5SDimitry Andric   if (!NewFormat)
3370b57cec5SDimitry Andric     return createTBAAStructTagNode(BaseType, AccessType, Offset);
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   Metadata *SizeNode = Tag->getOperand(3);
3400b57cec5SDimitry Andric   uint64_t Size = mdconst::extract<ConstantInt>(SizeNode)->getZExtValue();
3410b57cec5SDimitry Andric   return createTBAAAccessTag(BaseType, AccessType, Offset, Size);
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric MDNode *MDBuilder::createIrrLoopHeaderWeight(uint64_t Weight) {
3450b57cec5SDimitry Andric   Metadata *Vals[] = {
3460b57cec5SDimitry Andric       createString("loop_header_weight"),
3470b57cec5SDimitry Andric       createConstant(ConstantInt::get(Type::getInt64Ty(Context), Weight)),
3480b57cec5SDimitry Andric   };
3490b57cec5SDimitry Andric   return MDNode::get(Context, Vals);
3500b57cec5SDimitry Andric }
3518bcb0991SDimitry Andric 
352e8d8bef9SDimitry Andric MDNode *MDBuilder::createPseudoProbeDesc(uint64_t GUID, uint64_t Hash,
35306c3fb27SDimitry Andric                                          StringRef FName) {
354e8d8bef9SDimitry Andric   auto *Int64Ty = Type::getInt64Ty(Context);
355e8d8bef9SDimitry Andric   SmallVector<Metadata *, 3> Ops(3);
356e8d8bef9SDimitry Andric   Ops[0] = createConstant(ConstantInt::get(Int64Ty, GUID));
357e8d8bef9SDimitry Andric   Ops[1] = createConstant(ConstantInt::get(Int64Ty, Hash));
35806c3fb27SDimitry Andric   Ops[2] = createString(FName);
359e8d8bef9SDimitry Andric   return MDNode::get(Context, Ops);
3608bcb0991SDimitry Andric }
361bdd1243dSDimitry Andric 
362bdd1243dSDimitry Andric MDNode *
363bdd1243dSDimitry Andric MDBuilder::createLLVMStats(ArrayRef<std::pair<StringRef, uint64_t>> LLVMStats) {
364bdd1243dSDimitry Andric   auto *Int64Ty = Type::getInt64Ty(Context);
365bdd1243dSDimitry Andric   SmallVector<Metadata *, 4> Ops(LLVMStats.size() * 2);
366bdd1243dSDimitry Andric   for (size_t I = 0; I < LLVMStats.size(); I++) {
367bdd1243dSDimitry Andric     Ops[I * 2] = createString(LLVMStats[I].first);
368bdd1243dSDimitry Andric     Ops[I * 2 + 1] =
369bdd1243dSDimitry Andric         createConstant(ConstantInt::get(Int64Ty, LLVMStats[I].second));
370bdd1243dSDimitry Andric   }
371bdd1243dSDimitry Andric   return MDNode::get(Context, Ops);
372bdd1243dSDimitry Andric }
373