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