1bdd1243dSDimitry Andric //===- DXILMetadata.cpp - DXIL Metadata helper objects --------------------===// 2bdd1243dSDimitry Andric // 3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6bdd1243dSDimitry Andric // 7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8bdd1243dSDimitry Andric /// 9bdd1243dSDimitry Andric /// \file This file contains helper objects for working with DXIL metadata. 10bdd1243dSDimitry Andric /// 11bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 12bdd1243dSDimitry Andric 13bdd1243dSDimitry Andric #include "DXILMetadata.h" 14bdd1243dSDimitry Andric #include "llvm/IR/Constants.h" 15bdd1243dSDimitry Andric #include "llvm/IR/IRBuilder.h" 16bdd1243dSDimitry Andric #include "llvm/IR/Metadata.h" 17bdd1243dSDimitry Andric #include "llvm/IR/Module.h" 18bdd1243dSDimitry Andric #include "llvm/Support/VersionTuple.h" 1906c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 20bdd1243dSDimitry Andric 21bdd1243dSDimitry Andric using namespace llvm; 22bdd1243dSDimitry Andric using namespace llvm::dxil; 23bdd1243dSDimitry Andric 24bdd1243dSDimitry Andric ValidatorVersionMD::ValidatorVersionMD(Module &M) 25bdd1243dSDimitry Andric : Entry(M.getOrInsertNamedMetadata("dx.valver")) {} 26bdd1243dSDimitry Andric 27bdd1243dSDimitry Andric void ValidatorVersionMD::update(VersionTuple ValidatorVer) { 28bdd1243dSDimitry Andric auto &Ctx = Entry->getParent()->getContext(); 29bdd1243dSDimitry Andric IRBuilder<> B(Ctx); 30bdd1243dSDimitry Andric Metadata *MDVals[2]; 31bdd1243dSDimitry Andric MDVals[0] = ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMajor())); 32bdd1243dSDimitry Andric MDVals[1] = 33bdd1243dSDimitry Andric ConstantAsMetadata::get(B.getInt32(ValidatorVer.getMinor().value_or(0))); 34bdd1243dSDimitry Andric 35bdd1243dSDimitry Andric if (isEmpty()) 36bdd1243dSDimitry Andric Entry->addOperand(MDNode::get(Ctx, MDVals)); 37bdd1243dSDimitry Andric else 38bdd1243dSDimitry Andric Entry->setOperand(0, MDNode::get(Ctx, MDVals)); 39bdd1243dSDimitry Andric } 40bdd1243dSDimitry Andric 41bdd1243dSDimitry Andric bool ValidatorVersionMD::isEmpty() { return Entry->getNumOperands() == 0; } 42bdd1243dSDimitry Andric 43*0fca6ea1SDimitry Andric VersionTuple ValidatorVersionMD::getAsVersionTuple() { 44*0fca6ea1SDimitry Andric if (isEmpty()) 45*0fca6ea1SDimitry Andric return VersionTuple(1, 0); 46*0fca6ea1SDimitry Andric auto *ValVerMD = cast<MDNode>(Entry->getOperand(0)); 47*0fca6ea1SDimitry Andric auto *MajorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(0)); 48*0fca6ea1SDimitry Andric auto *MinorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(1)); 49*0fca6ea1SDimitry Andric return VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue()); 50*0fca6ea1SDimitry Andric } 51*0fca6ea1SDimitry Andric 52bdd1243dSDimitry Andric static StringRef getShortShaderStage(Triple::EnvironmentType Env) { 53bdd1243dSDimitry Andric switch (Env) { 54bdd1243dSDimitry Andric case Triple::Pixel: 55bdd1243dSDimitry Andric return "ps"; 56bdd1243dSDimitry Andric case Triple::Vertex: 57bdd1243dSDimitry Andric return "vs"; 58bdd1243dSDimitry Andric case Triple::Geometry: 59bdd1243dSDimitry Andric return "gs"; 60bdd1243dSDimitry Andric case Triple::Hull: 61bdd1243dSDimitry Andric return "hs"; 62bdd1243dSDimitry Andric case Triple::Domain: 63bdd1243dSDimitry Andric return "ds"; 64bdd1243dSDimitry Andric case Triple::Compute: 65bdd1243dSDimitry Andric return "cs"; 66bdd1243dSDimitry Andric case Triple::Library: 67bdd1243dSDimitry Andric return "lib"; 68bdd1243dSDimitry Andric case Triple::Mesh: 69bdd1243dSDimitry Andric return "ms"; 70bdd1243dSDimitry Andric case Triple::Amplification: 71bdd1243dSDimitry Andric return "as"; 72bdd1243dSDimitry Andric default: 73bdd1243dSDimitry Andric break; 74bdd1243dSDimitry Andric } 75bdd1243dSDimitry Andric llvm_unreachable("Unsupported environment for DXIL generation."); 76bdd1243dSDimitry Andric return ""; 77bdd1243dSDimitry Andric } 78bdd1243dSDimitry Andric 79bdd1243dSDimitry Andric void dxil::createShaderModelMD(Module &M) { 80bdd1243dSDimitry Andric NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.shaderModel"); 81bdd1243dSDimitry Andric Triple TT(M.getTargetTriple()); 82bdd1243dSDimitry Andric VersionTuple Ver = TT.getOSVersion(); 83bdd1243dSDimitry Andric LLVMContext &Ctx = M.getContext(); 84bdd1243dSDimitry Andric IRBuilder<> B(Ctx); 85bdd1243dSDimitry Andric 86bdd1243dSDimitry Andric Metadata *Vals[3]; 87bdd1243dSDimitry Andric Vals[0] = MDString::get(Ctx, getShortShaderStage(TT.getEnvironment())); 88bdd1243dSDimitry Andric Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor())); 89bdd1243dSDimitry Andric Vals[2] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0))); 90bdd1243dSDimitry Andric Entry->addOperand(MDNode::get(Ctx, Vals)); 91bdd1243dSDimitry Andric } 92bdd1243dSDimitry Andric 93*0fca6ea1SDimitry Andric void dxil::createDXILVersionMD(Module &M) { 94*0fca6ea1SDimitry Andric Triple TT(Triple::normalize(M.getTargetTriple())); 95*0fca6ea1SDimitry Andric VersionTuple Ver = TT.getDXILVersion(); 96*0fca6ea1SDimitry Andric LLVMContext &Ctx = M.getContext(); 97*0fca6ea1SDimitry Andric IRBuilder<> B(Ctx); 98*0fca6ea1SDimitry Andric NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version"); 99*0fca6ea1SDimitry Andric Metadata *Vals[2]; 100*0fca6ea1SDimitry Andric Vals[0] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor())); 101*0fca6ea1SDimitry Andric Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0))); 102*0fca6ea1SDimitry Andric Entry->addOperand(MDNode::get(Ctx, Vals)); 103*0fca6ea1SDimitry Andric } 104*0fca6ea1SDimitry Andric 105bdd1243dSDimitry Andric static uint32_t getShaderStage(Triple::EnvironmentType Env) { 106bdd1243dSDimitry Andric return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel; 107bdd1243dSDimitry Andric } 108bdd1243dSDimitry Andric 109bdd1243dSDimitry Andric namespace { 110bdd1243dSDimitry Andric 111bdd1243dSDimitry Andric struct EntryProps { 112bdd1243dSDimitry Andric Triple::EnvironmentType ShaderKind; 113bdd1243dSDimitry Andric // FIXME: support more shader profiles. 114bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57927. 115bdd1243dSDimitry Andric struct { 116bdd1243dSDimitry Andric unsigned NumThreads[3]; 117bdd1243dSDimitry Andric } CS; 118bdd1243dSDimitry Andric 119bdd1243dSDimitry Andric EntryProps(Function &F, Triple::EnvironmentType ModuleShaderKind) 120bdd1243dSDimitry Andric : ShaderKind(ModuleShaderKind) { 121bdd1243dSDimitry Andric 122bdd1243dSDimitry Andric if (ShaderKind == Triple::EnvironmentType::Library) { 123bdd1243dSDimitry Andric Attribute EntryAttr = F.getFnAttribute("hlsl.shader"); 124bdd1243dSDimitry Andric StringRef EntryProfile = EntryAttr.getValueAsString(); 125bdd1243dSDimitry Andric Triple T("", "", "", EntryProfile); 126bdd1243dSDimitry Andric ShaderKind = T.getEnvironment(); 127bdd1243dSDimitry Andric } 128bdd1243dSDimitry Andric 129bdd1243dSDimitry Andric if (ShaderKind == Triple::EnvironmentType::Compute) { 130bdd1243dSDimitry Andric auto NumThreadsStr = 131bdd1243dSDimitry Andric F.getFnAttribute("hlsl.numthreads").getValueAsString(); 132bdd1243dSDimitry Andric SmallVector<StringRef> NumThreads; 133bdd1243dSDimitry Andric NumThreadsStr.split(NumThreads, ','); 134bdd1243dSDimitry Andric assert(NumThreads.size() == 3 && "invalid numthreads"); 135bdd1243dSDimitry Andric auto Zip = 136bdd1243dSDimitry Andric llvm::zip(NumThreads, MutableArrayRef<unsigned>(CS.NumThreads)); 137bdd1243dSDimitry Andric for (auto It : Zip) { 138bdd1243dSDimitry Andric StringRef Str = std::get<0>(It); 139bdd1243dSDimitry Andric APInt V; 140bdd1243dSDimitry Andric [[maybe_unused]] bool Result = Str.getAsInteger(10, V); 141bdd1243dSDimitry Andric assert(!Result && "Failed to parse numthreads"); 142bdd1243dSDimitry Andric 143bdd1243dSDimitry Andric unsigned &Num = std::get<1>(It); 144bdd1243dSDimitry Andric Num = V.getLimitedValue(); 145bdd1243dSDimitry Andric } 146bdd1243dSDimitry Andric } 147bdd1243dSDimitry Andric } 148bdd1243dSDimitry Andric 149bdd1243dSDimitry Andric MDTuple *emitDXILEntryProps(uint64_t RawShaderFlag, LLVMContext &Ctx, 150bdd1243dSDimitry Andric bool IsLib) { 151bdd1243dSDimitry Andric std::vector<Metadata *> MDVals; 152bdd1243dSDimitry Andric 153bdd1243dSDimitry Andric if (RawShaderFlag != 0) 154bdd1243dSDimitry Andric appendShaderFlags(MDVals, RawShaderFlag, Ctx); 155bdd1243dSDimitry Andric 156bdd1243dSDimitry Andric // Add shader kind for lib entrys. 157bdd1243dSDimitry Andric if (IsLib && ShaderKind != Triple::EnvironmentType::Library) 158bdd1243dSDimitry Andric appendShaderKind(MDVals, Ctx); 159bdd1243dSDimitry Andric 160bdd1243dSDimitry Andric if (ShaderKind == Triple::EnvironmentType::Compute) 161bdd1243dSDimitry Andric appendNumThreads(MDVals, Ctx); 162bdd1243dSDimitry Andric // FIXME: support more props. 163bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57948. 164bdd1243dSDimitry Andric return MDNode::get(Ctx, MDVals); 165bdd1243dSDimitry Andric } 166bdd1243dSDimitry Andric 167bdd1243dSDimitry Andric static MDTuple *emitEntryPropsForEmptyEntry(uint64_t RawShaderFlag, 168bdd1243dSDimitry Andric LLVMContext &Ctx) { 169bdd1243dSDimitry Andric if (RawShaderFlag == 0) 170bdd1243dSDimitry Andric return nullptr; 171bdd1243dSDimitry Andric 172bdd1243dSDimitry Andric std::vector<Metadata *> MDVals; 173bdd1243dSDimitry Andric 174bdd1243dSDimitry Andric appendShaderFlags(MDVals, RawShaderFlag, Ctx); 175bdd1243dSDimitry Andric // FIXME: support more props. 176bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57948. 177bdd1243dSDimitry Andric return MDNode::get(Ctx, MDVals); 178bdd1243dSDimitry Andric } 179bdd1243dSDimitry Andric 180bdd1243dSDimitry Andric private: 181bdd1243dSDimitry Andric enum EntryPropsTag { 182bdd1243dSDimitry Andric ShaderFlagsTag = 0, 183bdd1243dSDimitry Andric GSStateTag, 184bdd1243dSDimitry Andric DSStateTag, 185bdd1243dSDimitry Andric HSStateTag, 186bdd1243dSDimitry Andric NumThreadsTag, 187bdd1243dSDimitry Andric AutoBindingSpaceTag, 188bdd1243dSDimitry Andric RayPayloadSizeTag, 189bdd1243dSDimitry Andric RayAttribSizeTag, 190bdd1243dSDimitry Andric ShaderKindTag, 191bdd1243dSDimitry Andric MSStateTag, 192bdd1243dSDimitry Andric ASStateTag, 193bdd1243dSDimitry Andric WaveSizeTag, 194bdd1243dSDimitry Andric EntryRootSigTag, 195bdd1243dSDimitry Andric }; 196bdd1243dSDimitry Andric 197bdd1243dSDimitry Andric void appendNumThreads(std::vector<Metadata *> &MDVals, LLVMContext &Ctx) { 198bdd1243dSDimitry Andric MDVals.emplace_back(ConstantAsMetadata::get( 199bdd1243dSDimitry Andric ConstantInt::get(Type::getInt32Ty(Ctx), NumThreadsTag))); 200bdd1243dSDimitry Andric 201bdd1243dSDimitry Andric std::vector<Metadata *> NumThreadVals; 202bdd1243dSDimitry Andric for (auto Num : ArrayRef<unsigned>(CS.NumThreads)) 203bdd1243dSDimitry Andric NumThreadVals.emplace_back(ConstantAsMetadata::get( 204bdd1243dSDimitry Andric ConstantInt::get(Type::getInt32Ty(Ctx), Num))); 205bdd1243dSDimitry Andric MDVals.emplace_back(MDNode::get(Ctx, NumThreadVals)); 206bdd1243dSDimitry Andric } 207bdd1243dSDimitry Andric 208bdd1243dSDimitry Andric static void appendShaderFlags(std::vector<Metadata *> &MDVals, 209bdd1243dSDimitry Andric uint64_t RawShaderFlag, LLVMContext &Ctx) { 210bdd1243dSDimitry Andric MDVals.emplace_back(ConstantAsMetadata::get( 211bdd1243dSDimitry Andric ConstantInt::get(Type::getInt32Ty(Ctx), ShaderFlagsTag))); 212bdd1243dSDimitry Andric MDVals.emplace_back(ConstantAsMetadata::get( 213bdd1243dSDimitry Andric ConstantInt::get(Type::getInt64Ty(Ctx), RawShaderFlag))); 214bdd1243dSDimitry Andric } 215bdd1243dSDimitry Andric 216bdd1243dSDimitry Andric void appendShaderKind(std::vector<Metadata *> &MDVals, LLVMContext &Ctx) { 217bdd1243dSDimitry Andric MDVals.emplace_back(ConstantAsMetadata::get( 218bdd1243dSDimitry Andric ConstantInt::get(Type::getInt32Ty(Ctx), ShaderKindTag))); 219bdd1243dSDimitry Andric MDVals.emplace_back(ConstantAsMetadata::get( 220bdd1243dSDimitry Andric ConstantInt::get(Type::getInt32Ty(Ctx), getShaderStage(ShaderKind)))); 221bdd1243dSDimitry Andric } 222bdd1243dSDimitry Andric }; 223bdd1243dSDimitry Andric 224bdd1243dSDimitry Andric class EntryMD { 225bdd1243dSDimitry Andric Function &F; 226bdd1243dSDimitry Andric LLVMContext &Ctx; 227bdd1243dSDimitry Andric EntryProps Props; 228bdd1243dSDimitry Andric 229bdd1243dSDimitry Andric public: 230bdd1243dSDimitry Andric EntryMD(Function &F, Triple::EnvironmentType ModuleShaderKind) 231bdd1243dSDimitry Andric : F(F), Ctx(F.getContext()), Props(F, ModuleShaderKind) {} 232bdd1243dSDimitry Andric 233bdd1243dSDimitry Andric MDTuple *emitEntryTuple(MDTuple *Resources, uint64_t RawShaderFlag) { 234bdd1243dSDimitry Andric // FIXME: add signature for profile other than CS. 235bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57928. 236bdd1243dSDimitry Andric MDTuple *Signatures = nullptr; 237*0fca6ea1SDimitry Andric return emitDXILEntryPointTuple( 238bdd1243dSDimitry Andric &F, F.getName().str(), Signatures, Resources, 239bdd1243dSDimitry Andric Props.emitDXILEntryProps(RawShaderFlag, Ctx, /*IsLib*/ false), Ctx); 240bdd1243dSDimitry Andric } 241bdd1243dSDimitry Andric 242bdd1243dSDimitry Andric MDTuple *emitEntryTupleForLib(uint64_t RawShaderFlag) { 243bdd1243dSDimitry Andric // FIXME: add signature for profile other than CS. 244bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57928. 245bdd1243dSDimitry Andric MDTuple *Signatures = nullptr; 246*0fca6ea1SDimitry Andric return emitDXILEntryPointTuple( 247bdd1243dSDimitry Andric &F, F.getName().str(), Signatures, 248bdd1243dSDimitry Andric /*entry in lib doesn't need resources metadata*/ nullptr, 249bdd1243dSDimitry Andric Props.emitDXILEntryProps(RawShaderFlag, Ctx, /*IsLib*/ true), Ctx); 250bdd1243dSDimitry Andric } 251bdd1243dSDimitry Andric 252bdd1243dSDimitry Andric // Library will have empty entry metadata which only store the resource table 253bdd1243dSDimitry Andric // metadata. 254bdd1243dSDimitry Andric static MDTuple *emitEmptyEntryForLib(MDTuple *Resources, 255bdd1243dSDimitry Andric uint64_t RawShaderFlag, 256bdd1243dSDimitry Andric LLVMContext &Ctx) { 257*0fca6ea1SDimitry Andric return emitDXILEntryPointTuple( 258bdd1243dSDimitry Andric nullptr, "", nullptr, Resources, 259bdd1243dSDimitry Andric EntryProps::emitEntryPropsForEmptyEntry(RawShaderFlag, Ctx), Ctx); 260bdd1243dSDimitry Andric } 261bdd1243dSDimitry Andric 262bdd1243dSDimitry Andric private: 263*0fca6ea1SDimitry Andric static MDTuple *emitDXILEntryPointTuple(Function *Fn, const std::string &Name, 264bdd1243dSDimitry Andric MDTuple *Signatures, 265bdd1243dSDimitry Andric MDTuple *Resources, 266bdd1243dSDimitry Andric MDTuple *Properties, 267bdd1243dSDimitry Andric LLVMContext &Ctx) { 268bdd1243dSDimitry Andric Metadata *MDVals[5]; 269bdd1243dSDimitry Andric MDVals[0] = Fn ? ValueAsMetadata::get(Fn) : nullptr; 270bdd1243dSDimitry Andric MDVals[1] = MDString::get(Ctx, Name.c_str()); 271bdd1243dSDimitry Andric MDVals[2] = Signatures; 272bdd1243dSDimitry Andric MDVals[3] = Resources; 273bdd1243dSDimitry Andric MDVals[4] = Properties; 274bdd1243dSDimitry Andric return MDNode::get(Ctx, MDVals); 275bdd1243dSDimitry Andric } 276bdd1243dSDimitry Andric }; 277bdd1243dSDimitry Andric } // namespace 278bdd1243dSDimitry Andric 279bdd1243dSDimitry Andric void dxil::createEntryMD(Module &M, const uint64_t ShaderFlags) { 280bdd1243dSDimitry Andric SmallVector<Function *> EntryList; 281bdd1243dSDimitry Andric for (auto &F : M.functions()) { 282bdd1243dSDimitry Andric if (!F.hasFnAttribute("hlsl.shader")) 283bdd1243dSDimitry Andric continue; 284bdd1243dSDimitry Andric EntryList.emplace_back(&F); 285bdd1243dSDimitry Andric } 286bdd1243dSDimitry Andric 287bdd1243dSDimitry Andric auto &Ctx = M.getContext(); 288bdd1243dSDimitry Andric // FIXME: generate metadata for resource. 289bdd1243dSDimitry Andric // See https://github.com/llvm/llvm-project/issues/57926. 290bdd1243dSDimitry Andric MDTuple *MDResources = nullptr; 291bdd1243dSDimitry Andric if (auto *NamedResources = M.getNamedMetadata("dx.resources")) 292bdd1243dSDimitry Andric MDResources = dyn_cast<MDTuple>(NamedResources->getOperand(0)); 293bdd1243dSDimitry Andric 294bdd1243dSDimitry Andric std::vector<MDNode *> Entries; 295bdd1243dSDimitry Andric Triple T = Triple(M.getTargetTriple()); 296bdd1243dSDimitry Andric switch (T.getEnvironment()) { 297bdd1243dSDimitry Andric case Triple::EnvironmentType::Library: { 298bdd1243dSDimitry Andric // Add empty entry to put resource metadata. 299bdd1243dSDimitry Andric MDTuple *EmptyEntry = 300bdd1243dSDimitry Andric EntryMD::emitEmptyEntryForLib(MDResources, ShaderFlags, Ctx); 301bdd1243dSDimitry Andric Entries.emplace_back(EmptyEntry); 302bdd1243dSDimitry Andric 303bdd1243dSDimitry Andric for (Function *Entry : EntryList) { 304bdd1243dSDimitry Andric EntryMD MD(*Entry, T.getEnvironment()); 305bdd1243dSDimitry Andric Entries.emplace_back(MD.emitEntryTupleForLib(0)); 306bdd1243dSDimitry Andric } 307bdd1243dSDimitry Andric } break; 308bdd1243dSDimitry Andric case Triple::EnvironmentType::Compute: 309bdd1243dSDimitry Andric case Triple::EnvironmentType::Amplification: 310bdd1243dSDimitry Andric case Triple::EnvironmentType::Mesh: 311bdd1243dSDimitry Andric case Triple::EnvironmentType::Vertex: 312bdd1243dSDimitry Andric case Triple::EnvironmentType::Hull: 313bdd1243dSDimitry Andric case Triple::EnvironmentType::Domain: 314bdd1243dSDimitry Andric case Triple::EnvironmentType::Geometry: 315bdd1243dSDimitry Andric case Triple::EnvironmentType::Pixel: { 316bdd1243dSDimitry Andric assert(EntryList.size() == 1 && 317bdd1243dSDimitry Andric "non-lib profiles should only have one entry"); 318bdd1243dSDimitry Andric EntryMD MD(*EntryList.front(), T.getEnvironment()); 319bdd1243dSDimitry Andric Entries.emplace_back(MD.emitEntryTuple(MDResources, ShaderFlags)); 320bdd1243dSDimitry Andric } break; 321bdd1243dSDimitry Andric default: 322bdd1243dSDimitry Andric assert(0 && "invalid profile"); 323bdd1243dSDimitry Andric break; 324bdd1243dSDimitry Andric } 325bdd1243dSDimitry Andric 326bdd1243dSDimitry Andric NamedMDNode *EntryPointsNamedMD = 327bdd1243dSDimitry Andric M.getOrInsertNamedMetadata("dx.entryPoints"); 328bdd1243dSDimitry Andric for (auto *Entry : Entries) 329bdd1243dSDimitry Andric EntryPointsNamedMD->addOperand(Entry); 330bdd1243dSDimitry Andric } 331