181ee3855SJustin Bogner //===- DXILTranslateMetadata.cpp - Pass to emit DXIL metadata -------------===// 20c7f7f1bSpython3kgae // 30c7f7f1bSpython3kgae // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40c7f7f1bSpython3kgae // See https://llvm.org/LICENSE.txt for license information. 50c7f7f1bSpython3kgae // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60c7f7f1bSpython3kgae // 70c7f7f1bSpython3kgae //===----------------------------------------------------------------------===// 80c7f7f1bSpython3kgae 981ee3855SJustin Bogner #include "DXILTranslateMetadata.h" 10618e5006SChris Bieneman #include "DXILResource.h" 1122018555SXiang Li #include "DXILResourceAnalysis.h" 12b8615079SXiang Li #include "DXILShaderFlags.h" 130c7f7f1bSpython3kgae #include "DirectX.h" 143734fa8cSS. Bharadwaj Yadavalli #include "llvm/ADT/SmallVector.h" 153734fa8cSS. Bharadwaj Yadavalli #include "llvm/ADT/Twine.h" 16eb2929d3SXiang Li #include "llvm/Analysis/DXILMetadataAnalysis.h" 17daa79232SJustin Bogner #include "llvm/Analysis/DXILResource.h" 18*380bb51bSjoaosaffran #include "llvm/IR/BasicBlock.h" 190c7f7f1bSpython3kgae #include "llvm/IR/Constants.h" 203734fa8cSS. Bharadwaj Yadavalli #include "llvm/IR/DiagnosticInfo.h" 213734fa8cSS. Bharadwaj Yadavalli #include "llvm/IR/DiagnosticPrinter.h" 223734fa8cSS. Bharadwaj Yadavalli #include "llvm/IR/Function.h" 233734fa8cSS. Bharadwaj Yadavalli #include "llvm/IR/IRBuilder.h" 243734fa8cSS. Bharadwaj Yadavalli #include "llvm/IR/LLVMContext.h" 25*380bb51bSjoaosaffran #include "llvm/IR/MDBuilder.h" 26c6c13d4eSpython3kgae #include "llvm/IR/Metadata.h" 270c7f7f1bSpython3kgae #include "llvm/IR/Module.h" 28daa79232SJustin Bogner #include "llvm/InitializePasses.h" 290c7f7f1bSpython3kgae #include "llvm/Pass.h" 303734fa8cSS. Bharadwaj Yadavalli #include "llvm/Support/ErrorHandling.h" 313734fa8cSS. Bharadwaj Yadavalli #include "llvm/Support/VersionTuple.h" 3262c7f035SArchibald Elliott #include "llvm/TargetParser/Triple.h" 333734fa8cSS. Bharadwaj Yadavalli #include <cstdint> 340c7f7f1bSpython3kgae 350c7f7f1bSpython3kgae using namespace llvm; 36b8615079SXiang Li using namespace llvm::dxil; 370c7f7f1bSpython3kgae 383734fa8cSS. Bharadwaj Yadavalli namespace { 393734fa8cSS. Bharadwaj Yadavalli /// A simple Wrapper DiagnosticInfo that generates Module-level diagnostic 403734fa8cSS. Bharadwaj Yadavalli /// for TranslateMetadata pass 413734fa8cSS. Bharadwaj Yadavalli class DiagnosticInfoTranslateMD : public DiagnosticInfo { 423734fa8cSS. Bharadwaj Yadavalli private: 433734fa8cSS. Bharadwaj Yadavalli const Twine &Msg; 443734fa8cSS. Bharadwaj Yadavalli const Module &Mod; 453734fa8cSS. Bharadwaj Yadavalli 463734fa8cSS. Bharadwaj Yadavalli public: 473734fa8cSS. Bharadwaj Yadavalli /// \p M is the module for which the diagnostic is being emitted. \p Msg is 483734fa8cSS. Bharadwaj Yadavalli /// the message to show. Note that this class does not copy this message, so 493734fa8cSS. Bharadwaj Yadavalli /// this reference must be valid for the whole life time of the diagnostic. 503734fa8cSS. Bharadwaj Yadavalli DiagnosticInfoTranslateMD(const Module &M, const Twine &Msg, 513734fa8cSS. Bharadwaj Yadavalli DiagnosticSeverity Severity = DS_Error) 523734fa8cSS. Bharadwaj Yadavalli : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {} 533734fa8cSS. Bharadwaj Yadavalli 543734fa8cSS. Bharadwaj Yadavalli void print(DiagnosticPrinter &DP) const override { 553734fa8cSS. Bharadwaj Yadavalli DP << Mod.getName() << ": " << Msg << '\n'; 563734fa8cSS. Bharadwaj Yadavalli } 573734fa8cSS. Bharadwaj Yadavalli }; 583734fa8cSS. Bharadwaj Yadavalli 593734fa8cSS. Bharadwaj Yadavalli enum class EntryPropsTag { 603734fa8cSS. Bharadwaj Yadavalli ShaderFlags = 0, 613734fa8cSS. Bharadwaj Yadavalli GSState, 623734fa8cSS. Bharadwaj Yadavalli DSState, 633734fa8cSS. Bharadwaj Yadavalli HSState, 643734fa8cSS. Bharadwaj Yadavalli NumThreads, 653734fa8cSS. Bharadwaj Yadavalli AutoBindingSpace, 663734fa8cSS. Bharadwaj Yadavalli RayPayloadSize, 673734fa8cSS. Bharadwaj Yadavalli RayAttribSize, 683734fa8cSS. Bharadwaj Yadavalli ShaderKind, 693734fa8cSS. Bharadwaj Yadavalli MSState, 703734fa8cSS. Bharadwaj Yadavalli ASStateTag, 713734fa8cSS. Bharadwaj Yadavalli WaveSize, 723734fa8cSS. Bharadwaj Yadavalli EntryRootSig, 733734fa8cSS. Bharadwaj Yadavalli }; 743734fa8cSS. Bharadwaj Yadavalli 753734fa8cSS. Bharadwaj Yadavalli } // namespace 763734fa8cSS. Bharadwaj Yadavalli 773eca15cbSJustin Bogner static NamedMDNode *emitResourceMetadata(Module &M, DXILBindingMap &DBM, 783eca15cbSJustin Bogner DXILResourceTypeMap &DRTM, 7958eec851SJustin Bogner const dxil::Resources &MDResources) { 80daa79232SJustin Bogner LLVMContext &Context = M.getContext(); 81daa79232SJustin Bogner 820e2466f6SJustin Bogner for (ResourceBindingInfo &RI : DBM) 830e2466f6SJustin Bogner if (!RI.hasSymbol()) 840e2466f6SJustin Bogner RI.createSymbol(M, DRTM[RI.getHandleTy()].createElementStruct()); 850e2466f6SJustin Bogner 86daa79232SJustin Bogner SmallVector<Metadata *> SRVs, UAVs, CBufs, Smps; 873eca15cbSJustin Bogner for (const ResourceBindingInfo &RI : DBM.srvs()) 883eca15cbSJustin Bogner SRVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); 893eca15cbSJustin Bogner for (const ResourceBindingInfo &RI : DBM.uavs()) 903eca15cbSJustin Bogner UAVs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); 913eca15cbSJustin Bogner for (const ResourceBindingInfo &RI : DBM.cbuffers()) 923eca15cbSJustin Bogner CBufs.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); 933eca15cbSJustin Bogner for (const ResourceBindingInfo &RI : DBM.samplers()) 943eca15cbSJustin Bogner Smps.push_back(RI.getAsMetadata(M, DRTM[RI.getHandleTy()])); 95daa79232SJustin Bogner 96daa79232SJustin Bogner Metadata *SRVMD = SRVs.empty() ? nullptr : MDNode::get(Context, SRVs); 97daa79232SJustin Bogner Metadata *UAVMD = UAVs.empty() ? nullptr : MDNode::get(Context, UAVs); 98daa79232SJustin Bogner Metadata *CBufMD = CBufs.empty() ? nullptr : MDNode::get(Context, CBufs); 99daa79232SJustin Bogner Metadata *SmpMD = Smps.empty() ? nullptr : MDNode::get(Context, Smps); 1003eca15cbSJustin Bogner bool HasResources = !DBM.empty(); 10158eec851SJustin Bogner 10258eec851SJustin Bogner if (MDResources.hasUAVs()) { 103daa79232SJustin Bogner assert(!UAVMD && "Old and new UAV representations can't coexist"); 10458eec851SJustin Bogner UAVMD = MDResources.writeUAVs(M); 10558eec851SJustin Bogner HasResources = true; 10658eec851SJustin Bogner } 10758eec851SJustin Bogner 10858eec851SJustin Bogner if (MDResources.hasCBuffers()) { 109daa79232SJustin Bogner assert(!CBufMD && "Old and new cbuffer representations can't coexist"); 11058eec851SJustin Bogner CBufMD = MDResources.writeCBuffers(M); 11158eec851SJustin Bogner HasResources = true; 11258eec851SJustin Bogner } 11358eec851SJustin Bogner 11458eec851SJustin Bogner if (!HasResources) 1153734fa8cSS. Bharadwaj Yadavalli return nullptr; 11658eec851SJustin Bogner 11758eec851SJustin Bogner NamedMDNode *ResourceMD = M.getOrInsertNamedMetadata("dx.resources"); 11858eec851SJustin Bogner ResourceMD->addOperand( 11958eec851SJustin Bogner MDNode::get(M.getContext(), {SRVMD, UAVMD, CBufMD, SmpMD})); 1203734fa8cSS. Bharadwaj Yadavalli 1213734fa8cSS. Bharadwaj Yadavalli return ResourceMD; 1223734fa8cSS. Bharadwaj Yadavalli } 1233734fa8cSS. Bharadwaj Yadavalli 1243734fa8cSS. Bharadwaj Yadavalli static StringRef getShortShaderStage(Triple::EnvironmentType Env) { 1253734fa8cSS. Bharadwaj Yadavalli switch (Env) { 1263734fa8cSS. Bharadwaj Yadavalli case Triple::Pixel: 1273734fa8cSS. Bharadwaj Yadavalli return "ps"; 1283734fa8cSS. Bharadwaj Yadavalli case Triple::Vertex: 1293734fa8cSS. Bharadwaj Yadavalli return "vs"; 1303734fa8cSS. Bharadwaj Yadavalli case Triple::Geometry: 1313734fa8cSS. Bharadwaj Yadavalli return "gs"; 1323734fa8cSS. Bharadwaj Yadavalli case Triple::Hull: 1333734fa8cSS. Bharadwaj Yadavalli return "hs"; 1343734fa8cSS. Bharadwaj Yadavalli case Triple::Domain: 1353734fa8cSS. Bharadwaj Yadavalli return "ds"; 1363734fa8cSS. Bharadwaj Yadavalli case Triple::Compute: 1373734fa8cSS. Bharadwaj Yadavalli return "cs"; 1383734fa8cSS. Bharadwaj Yadavalli case Triple::Library: 1393734fa8cSS. Bharadwaj Yadavalli return "lib"; 1403734fa8cSS. Bharadwaj Yadavalli case Triple::Mesh: 1413734fa8cSS. Bharadwaj Yadavalli return "ms"; 1423734fa8cSS. Bharadwaj Yadavalli case Triple::Amplification: 1433734fa8cSS. Bharadwaj Yadavalli return "as"; 1443734fa8cSS. Bharadwaj Yadavalli default: 1453734fa8cSS. Bharadwaj Yadavalli break; 1463734fa8cSS. Bharadwaj Yadavalli } 1473734fa8cSS. Bharadwaj Yadavalli llvm_unreachable("Unsupported environment for DXIL generation."); 1483734fa8cSS. Bharadwaj Yadavalli } 1493734fa8cSS. Bharadwaj Yadavalli 1503734fa8cSS. Bharadwaj Yadavalli static uint32_t getShaderStage(Triple::EnvironmentType Env) { 1513734fa8cSS. Bharadwaj Yadavalli return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel; 1523734fa8cSS. Bharadwaj Yadavalli } 1533734fa8cSS. Bharadwaj Yadavalli 1543734fa8cSS. Bharadwaj Yadavalli static SmallVector<Metadata *> 1553734fa8cSS. Bharadwaj Yadavalli getTagValueAsMetadata(EntryPropsTag Tag, uint64_t Value, LLVMContext &Ctx) { 1563734fa8cSS. Bharadwaj Yadavalli SmallVector<Metadata *> MDVals; 1573734fa8cSS. Bharadwaj Yadavalli MDVals.emplace_back(ConstantAsMetadata::get( 1583734fa8cSS. Bharadwaj Yadavalli ConstantInt::get(Type::getInt32Ty(Ctx), static_cast<int>(Tag)))); 1593734fa8cSS. Bharadwaj Yadavalli switch (Tag) { 1603734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::ShaderFlags: 1613734fa8cSS. Bharadwaj Yadavalli MDVals.emplace_back(ConstantAsMetadata::get( 1623734fa8cSS. Bharadwaj Yadavalli ConstantInt::get(Type::getInt64Ty(Ctx), Value))); 1633734fa8cSS. Bharadwaj Yadavalli break; 1643734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::ShaderKind: 1653734fa8cSS. Bharadwaj Yadavalli MDVals.emplace_back(ConstantAsMetadata::get( 1663734fa8cSS. Bharadwaj Yadavalli ConstantInt::get(Type::getInt32Ty(Ctx), Value))); 1673734fa8cSS. Bharadwaj Yadavalli break; 1683734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::GSState: 1693734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::DSState: 1703734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::HSState: 1713734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::NumThreads: 1723734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::AutoBindingSpace: 1733734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::RayPayloadSize: 1743734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::RayAttribSize: 1753734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::MSState: 1763734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::ASStateTag: 1773734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::WaveSize: 1783734fa8cSS. Bharadwaj Yadavalli case EntryPropsTag::EntryRootSig: 1793734fa8cSS. Bharadwaj Yadavalli llvm_unreachable("NYI: Unhandled entry property tag"); 1803734fa8cSS. Bharadwaj Yadavalli } 1813734fa8cSS. Bharadwaj Yadavalli return MDVals; 1823734fa8cSS. Bharadwaj Yadavalli } 1833734fa8cSS. Bharadwaj Yadavalli 1843734fa8cSS. Bharadwaj Yadavalli static MDTuple * 1853734fa8cSS. Bharadwaj Yadavalli getEntryPropAsMetadata(const EntryProperties &EP, uint64_t EntryShaderFlags, 1863734fa8cSS. Bharadwaj Yadavalli const Triple::EnvironmentType ShaderProfile) { 1873734fa8cSS. Bharadwaj Yadavalli SmallVector<Metadata *> MDVals; 1883734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = EP.Entry->getContext(); 1893734fa8cSS. Bharadwaj Yadavalli if (EntryShaderFlags != 0) 1903734fa8cSS. Bharadwaj Yadavalli MDVals.append(getTagValueAsMetadata(EntryPropsTag::ShaderFlags, 1913734fa8cSS. Bharadwaj Yadavalli EntryShaderFlags, Ctx)); 1923734fa8cSS. Bharadwaj Yadavalli 1933734fa8cSS. Bharadwaj Yadavalli if (EP.Entry != nullptr) { 1943734fa8cSS. Bharadwaj Yadavalli // FIXME: support more props. 1953734fa8cSS. Bharadwaj Yadavalli // See https://github.com/llvm/llvm-project/issues/57948. 1963734fa8cSS. Bharadwaj Yadavalli // Add shader kind for lib entries. 1973734fa8cSS. Bharadwaj Yadavalli if (ShaderProfile == Triple::EnvironmentType::Library && 1983734fa8cSS. Bharadwaj Yadavalli EP.ShaderStage != Triple::EnvironmentType::Library) 1993734fa8cSS. Bharadwaj Yadavalli MDVals.append(getTagValueAsMetadata(EntryPropsTag::ShaderKind, 2003734fa8cSS. Bharadwaj Yadavalli getShaderStage(EP.ShaderStage), Ctx)); 2013734fa8cSS. Bharadwaj Yadavalli 2023734fa8cSS. Bharadwaj Yadavalli if (EP.ShaderStage == Triple::EnvironmentType::Compute) { 2033734fa8cSS. Bharadwaj Yadavalli MDVals.emplace_back(ConstantAsMetadata::get(ConstantInt::get( 2043734fa8cSS. Bharadwaj Yadavalli Type::getInt32Ty(Ctx), static_cast<int>(EntryPropsTag::NumThreads)))); 2053734fa8cSS. Bharadwaj Yadavalli Metadata *NumThreadVals[] = {ConstantAsMetadata::get(ConstantInt::get( 2063734fa8cSS. Bharadwaj Yadavalli Type::getInt32Ty(Ctx), EP.NumThreadsX)), 2073734fa8cSS. Bharadwaj Yadavalli ConstantAsMetadata::get(ConstantInt::get( 2083734fa8cSS. Bharadwaj Yadavalli Type::getInt32Ty(Ctx), EP.NumThreadsY)), 2093734fa8cSS. Bharadwaj Yadavalli ConstantAsMetadata::get(ConstantInt::get( 2103734fa8cSS. Bharadwaj Yadavalli Type::getInt32Ty(Ctx), EP.NumThreadsZ))}; 2113734fa8cSS. Bharadwaj Yadavalli MDVals.emplace_back(MDNode::get(Ctx, NumThreadVals)); 2123734fa8cSS. Bharadwaj Yadavalli } 2133734fa8cSS. Bharadwaj Yadavalli } 2143734fa8cSS. Bharadwaj Yadavalli if (MDVals.empty()) 2153734fa8cSS. Bharadwaj Yadavalli return nullptr; 2163734fa8cSS. Bharadwaj Yadavalli return MDNode::get(Ctx, MDVals); 2173734fa8cSS. Bharadwaj Yadavalli } 2183734fa8cSS. Bharadwaj Yadavalli 2193734fa8cSS. Bharadwaj Yadavalli MDTuple *constructEntryMetadata(const Function *EntryFn, MDTuple *Signatures, 2203734fa8cSS. Bharadwaj Yadavalli MDNode *Resources, MDTuple *Properties, 2213734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx) { 2223734fa8cSS. Bharadwaj Yadavalli // Each entry point metadata record specifies: 2233734fa8cSS. Bharadwaj Yadavalli // * reference to the entry point function global symbol 2243734fa8cSS. Bharadwaj Yadavalli // * unmangled name 2253734fa8cSS. Bharadwaj Yadavalli // * list of signatures 2263734fa8cSS. Bharadwaj Yadavalli // * list of resources 2273734fa8cSS. Bharadwaj Yadavalli // * list of tag-value pairs of shader capabilities and other properties 2283734fa8cSS. Bharadwaj Yadavalli Metadata *MDVals[5]; 2293734fa8cSS. Bharadwaj Yadavalli MDVals[0] = 2303734fa8cSS. Bharadwaj Yadavalli EntryFn ? ValueAsMetadata::get(const_cast<Function *>(EntryFn)) : nullptr; 2313734fa8cSS. Bharadwaj Yadavalli MDVals[1] = MDString::get(Ctx, EntryFn ? EntryFn->getName() : ""); 2323734fa8cSS. Bharadwaj Yadavalli MDVals[2] = Signatures; 2333734fa8cSS. Bharadwaj Yadavalli MDVals[3] = Resources; 2343734fa8cSS. Bharadwaj Yadavalli MDVals[4] = Properties; 2353734fa8cSS. Bharadwaj Yadavalli return MDNode::get(Ctx, MDVals); 2363734fa8cSS. Bharadwaj Yadavalli } 2373734fa8cSS. Bharadwaj Yadavalli 2383734fa8cSS. Bharadwaj Yadavalli static MDTuple *emitEntryMD(const EntryProperties &EP, MDTuple *Signatures, 2393734fa8cSS. Bharadwaj Yadavalli MDNode *MDResources, 2403734fa8cSS. Bharadwaj Yadavalli const uint64_t EntryShaderFlags, 2413734fa8cSS. Bharadwaj Yadavalli const Triple::EnvironmentType ShaderProfile) { 2423734fa8cSS. Bharadwaj Yadavalli MDTuple *Properties = 2433734fa8cSS. Bharadwaj Yadavalli getEntryPropAsMetadata(EP, EntryShaderFlags, ShaderProfile); 2443734fa8cSS. Bharadwaj Yadavalli return constructEntryMetadata(EP.Entry, Signatures, MDResources, Properties, 2453734fa8cSS. Bharadwaj Yadavalli EP.Entry->getContext()); 2463734fa8cSS. Bharadwaj Yadavalli } 2473734fa8cSS. Bharadwaj Yadavalli 2483734fa8cSS. Bharadwaj Yadavalli static void emitValidatorVersionMD(Module &M, const ModuleMetadataInfo &MMDI) { 2493734fa8cSS. Bharadwaj Yadavalli if (MMDI.ValidatorVersion.empty()) 2503734fa8cSS. Bharadwaj Yadavalli return; 2513734fa8cSS. Bharadwaj Yadavalli 2523734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = M.getContext(); 2533734fa8cSS. Bharadwaj Yadavalli IRBuilder<> IRB(Ctx); 2543734fa8cSS. Bharadwaj Yadavalli Metadata *MDVals[2]; 2553734fa8cSS. Bharadwaj Yadavalli MDVals[0] = 2563734fa8cSS. Bharadwaj Yadavalli ConstantAsMetadata::get(IRB.getInt32(MMDI.ValidatorVersion.getMajor())); 2573734fa8cSS. Bharadwaj Yadavalli MDVals[1] = ConstantAsMetadata::get( 2583734fa8cSS. Bharadwaj Yadavalli IRB.getInt32(MMDI.ValidatorVersion.getMinor().value_or(0))); 2593734fa8cSS. Bharadwaj Yadavalli NamedMDNode *ValVerNode = M.getOrInsertNamedMetadata("dx.valver"); 2603734fa8cSS. Bharadwaj Yadavalli // Set validator version obtained from DXIL Metadata Analysis pass 2613734fa8cSS. Bharadwaj Yadavalli ValVerNode->clearOperands(); 2623734fa8cSS. Bharadwaj Yadavalli ValVerNode->addOperand(MDNode::get(Ctx, MDVals)); 2633734fa8cSS. Bharadwaj Yadavalli } 2643734fa8cSS. Bharadwaj Yadavalli 2653734fa8cSS. Bharadwaj Yadavalli static void emitShaderModelVersionMD(Module &M, 2663734fa8cSS. Bharadwaj Yadavalli const ModuleMetadataInfo &MMDI) { 2673734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = M.getContext(); 2683734fa8cSS. Bharadwaj Yadavalli IRBuilder<> IRB(Ctx); 2693734fa8cSS. Bharadwaj Yadavalli Metadata *SMVals[3]; 2703734fa8cSS. Bharadwaj Yadavalli VersionTuple SM = MMDI.ShaderModelVersion; 2713734fa8cSS. Bharadwaj Yadavalli SMVals[0] = MDString::get(Ctx, getShortShaderStage(MMDI.ShaderProfile)); 2723734fa8cSS. Bharadwaj Yadavalli SMVals[1] = ConstantAsMetadata::get(IRB.getInt32(SM.getMajor())); 2733734fa8cSS. Bharadwaj Yadavalli SMVals[2] = ConstantAsMetadata::get(IRB.getInt32(SM.getMinor().value_or(0))); 2743734fa8cSS. Bharadwaj Yadavalli NamedMDNode *SMMDNode = M.getOrInsertNamedMetadata("dx.shaderModel"); 2753734fa8cSS. Bharadwaj Yadavalli SMMDNode->addOperand(MDNode::get(Ctx, SMVals)); 2763734fa8cSS. Bharadwaj Yadavalli } 2773734fa8cSS. Bharadwaj Yadavalli 2783734fa8cSS. Bharadwaj Yadavalli static void emitDXILVersionTupleMD(Module &M, const ModuleMetadataInfo &MMDI) { 2793734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = M.getContext(); 2803734fa8cSS. Bharadwaj Yadavalli IRBuilder<> IRB(Ctx); 2813734fa8cSS. Bharadwaj Yadavalli VersionTuple DXILVer = MMDI.DXILVersion; 2823734fa8cSS. Bharadwaj Yadavalli Metadata *DXILVals[2]; 2833734fa8cSS. Bharadwaj Yadavalli DXILVals[0] = ConstantAsMetadata::get(IRB.getInt32(DXILVer.getMajor())); 2843734fa8cSS. Bharadwaj Yadavalli DXILVals[1] = 2853734fa8cSS. Bharadwaj Yadavalli ConstantAsMetadata::get(IRB.getInt32(DXILVer.getMinor().value_or(0))); 2863734fa8cSS. Bharadwaj Yadavalli NamedMDNode *DXILVerMDNode = M.getOrInsertNamedMetadata("dx.version"); 2873734fa8cSS. Bharadwaj Yadavalli DXILVerMDNode->addOperand(MDNode::get(Ctx, DXILVals)); 2883734fa8cSS. Bharadwaj Yadavalli } 2893734fa8cSS. Bharadwaj Yadavalli 2903734fa8cSS. Bharadwaj Yadavalli static MDTuple *emitTopLevelLibraryNode(Module &M, MDNode *RMD, 2913734fa8cSS. Bharadwaj Yadavalli uint64_t ShaderFlags) { 2923734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = M.getContext(); 2933734fa8cSS. Bharadwaj Yadavalli MDTuple *Properties = nullptr; 2943734fa8cSS. Bharadwaj Yadavalli if (ShaderFlags != 0) { 2953734fa8cSS. Bharadwaj Yadavalli SmallVector<Metadata *> MDVals; 2963734fa8cSS. Bharadwaj Yadavalli MDVals.append( 2973734fa8cSS. Bharadwaj Yadavalli getTagValueAsMetadata(EntryPropsTag::ShaderFlags, ShaderFlags, Ctx)); 2983734fa8cSS. Bharadwaj Yadavalli Properties = MDNode::get(Ctx, MDVals); 2993734fa8cSS. Bharadwaj Yadavalli } 3003734fa8cSS. Bharadwaj Yadavalli // Library has an entry metadata with resource table metadata and all other 3013734fa8cSS. Bharadwaj Yadavalli // MDNodes as null. 3023734fa8cSS. Bharadwaj Yadavalli return constructEntryMetadata(nullptr, nullptr, RMD, Properties, Ctx); 30358eec851SJustin Bogner } 30458eec851SJustin Bogner 305*380bb51bSjoaosaffran // TODO: We might need to refactor this to be more generic, 306*380bb51bSjoaosaffran // in case we need more metadata to be replaced. 307*380bb51bSjoaosaffran static void translateBranchMetadata(Module &M) { 308*380bb51bSjoaosaffran for (Function &F : M) { 309*380bb51bSjoaosaffran for (BasicBlock &BB : F) { 310*380bb51bSjoaosaffran Instruction *BBTerminatorInst = BB.getTerminator(); 311*380bb51bSjoaosaffran 312*380bb51bSjoaosaffran MDNode *HlslControlFlowMD = 313*380bb51bSjoaosaffran BBTerminatorInst->getMetadata("hlsl.controlflow.hint"); 314*380bb51bSjoaosaffran 315*380bb51bSjoaosaffran if (!HlslControlFlowMD) 316*380bb51bSjoaosaffran continue; 317*380bb51bSjoaosaffran 318*380bb51bSjoaosaffran assert(HlslControlFlowMD->getNumOperands() == 2 && 319*380bb51bSjoaosaffran "invalid operands for hlsl.controlflow.hint"); 320*380bb51bSjoaosaffran 321*380bb51bSjoaosaffran MDBuilder MDHelper(M.getContext()); 322*380bb51bSjoaosaffran ConstantInt *Op1 = 323*380bb51bSjoaosaffran mdconst::extract<ConstantInt>(HlslControlFlowMD->getOperand(1)); 324*380bb51bSjoaosaffran 325*380bb51bSjoaosaffran SmallVector<llvm::Metadata *, 2> Vals( 326*380bb51bSjoaosaffran ArrayRef<Metadata *>{MDHelper.createString("dx.controlflow.hints"), 327*380bb51bSjoaosaffran MDHelper.createConstant(Op1)}); 328*380bb51bSjoaosaffran 329*380bb51bSjoaosaffran MDNode *MDNode = llvm::MDNode::get(M.getContext(), Vals); 330*380bb51bSjoaosaffran 331*380bb51bSjoaosaffran BBTerminatorInst->setMetadata("dx.controlflow.hints", MDNode); 332*380bb51bSjoaosaffran BBTerminatorInst->setMetadata("hlsl.controlflow.hint", nullptr); 333*380bb51bSjoaosaffran } 334*380bb51bSjoaosaffran } 335*380bb51bSjoaosaffran } 336*380bb51bSjoaosaffran 3373eca15cbSJustin Bogner static void translateMetadata(Module &M, DXILBindingMap &DBM, 3383eca15cbSJustin Bogner DXILResourceTypeMap &DRTM, 3393734fa8cSS. Bharadwaj Yadavalli const Resources &MDResources, 34096547decSS. Bharadwaj Yadavalli const ModuleShaderFlags &ShaderFlags, 3413734fa8cSS. Bharadwaj Yadavalli const ModuleMetadataInfo &MMDI) { 3423734fa8cSS. Bharadwaj Yadavalli LLVMContext &Ctx = M.getContext(); 3433734fa8cSS. Bharadwaj Yadavalli IRBuilder<> IRB(Ctx); 3443734fa8cSS. Bharadwaj Yadavalli SmallVector<MDNode *> EntryFnMDNodes; 34581ee3855SJustin Bogner 3463734fa8cSS. Bharadwaj Yadavalli emitValidatorVersionMD(M, MMDI); 3473734fa8cSS. Bharadwaj Yadavalli emitShaderModelVersionMD(M, MMDI); 3483734fa8cSS. Bharadwaj Yadavalli emitDXILVersionTupleMD(M, MMDI); 3493eca15cbSJustin Bogner NamedMDNode *NamedResourceMD = 3503eca15cbSJustin Bogner emitResourceMetadata(M, DBM, DRTM, MDResources); 3513734fa8cSS. Bharadwaj Yadavalli auto *ResourceMD = 3523734fa8cSS. Bharadwaj Yadavalli (NamedResourceMD != nullptr) ? NamedResourceMD->getOperand(0) : nullptr; 3533734fa8cSS. Bharadwaj Yadavalli // FIXME: Add support to construct Signatures 3543734fa8cSS. Bharadwaj Yadavalli // See https://github.com/llvm/llvm-project/issues/57928 3553734fa8cSS. Bharadwaj Yadavalli MDTuple *Signatures = nullptr; 35681ee3855SJustin Bogner 35796547decSS. Bharadwaj Yadavalli if (MMDI.ShaderProfile == Triple::EnvironmentType::Library) { 35896547decSS. Bharadwaj Yadavalli // Get the combined shader flag mask of all functions in the library to be 35996547decSS. Bharadwaj Yadavalli // used as shader flags mask value associated with top-level library entry 36096547decSS. Bharadwaj Yadavalli // metadata. 36196547decSS. Bharadwaj Yadavalli uint64_t CombinedMask = ShaderFlags.getCombinedFlags(); 3623734fa8cSS. Bharadwaj Yadavalli EntryFnMDNodes.emplace_back( 36396547decSS. Bharadwaj Yadavalli emitTopLevelLibraryNode(M, ResourceMD, CombinedMask)); 36496547decSS. Bharadwaj Yadavalli } else if (MMDI.EntryPropertyVec.size() > 1) { 3653734fa8cSS. Bharadwaj Yadavalli M.getContext().diagnose(DiagnosticInfoTranslateMD( 3663734fa8cSS. Bharadwaj Yadavalli M, "Non-library shader: One and only one entry expected")); 3673734fa8cSS. Bharadwaj Yadavalli } 3683734fa8cSS. Bharadwaj Yadavalli 3693734fa8cSS. Bharadwaj Yadavalli for (const EntryProperties &EntryProp : MMDI.EntryPropertyVec) { 37096547decSS. Bharadwaj Yadavalli const ComputedShaderFlags &EntrySFMask = 37196547decSS. Bharadwaj Yadavalli ShaderFlags.getFunctionFlags(EntryProp.Entry); 37296547decSS. Bharadwaj Yadavalli 37396547decSS. Bharadwaj Yadavalli // If ShaderProfile is Library, mask is already consolidated in the 37496547decSS. Bharadwaj Yadavalli // top-level library node. Hence it is not emitted. 37596547decSS. Bharadwaj Yadavalli uint64_t EntryShaderFlags = 0; 3763734fa8cSS. Bharadwaj Yadavalli if (MMDI.ShaderProfile != Triple::EnvironmentType::Library) { 37796547decSS. Bharadwaj Yadavalli EntryShaderFlags = EntrySFMask; 3783734fa8cSS. Bharadwaj Yadavalli if (EntryProp.ShaderStage != MMDI.ShaderProfile) { 3793734fa8cSS. Bharadwaj Yadavalli M.getContext().diagnose(DiagnosticInfoTranslateMD( 3803734fa8cSS. Bharadwaj Yadavalli M, 3813734fa8cSS. Bharadwaj Yadavalli "Shader stage '" + 3823734fa8cSS. Bharadwaj Yadavalli Twine(getShortShaderStage(EntryProp.ShaderStage) + 3833734fa8cSS. Bharadwaj Yadavalli "' for entry '" + Twine(EntryProp.Entry->getName()) + 3843734fa8cSS. Bharadwaj Yadavalli "' different from specified target profile '" + 3853734fa8cSS. Bharadwaj Yadavalli Twine(Triple::getEnvironmentTypeName(MMDI.ShaderProfile) + 3863734fa8cSS. Bharadwaj Yadavalli "'")))); 3873734fa8cSS. Bharadwaj Yadavalli } 3883734fa8cSS. Bharadwaj Yadavalli } 3893734fa8cSS. Bharadwaj Yadavalli EntryFnMDNodes.emplace_back(emitEntryMD(EntryProp, Signatures, ResourceMD, 3903734fa8cSS. Bharadwaj Yadavalli EntryShaderFlags, 3913734fa8cSS. Bharadwaj Yadavalli MMDI.ShaderProfile)); 3923734fa8cSS. Bharadwaj Yadavalli } 3933734fa8cSS. Bharadwaj Yadavalli 3943734fa8cSS. Bharadwaj Yadavalli NamedMDNode *EntryPointsNamedMD = 3953734fa8cSS. Bharadwaj Yadavalli M.getOrInsertNamedMetadata("dx.entryPoints"); 3963734fa8cSS. Bharadwaj Yadavalli for (auto *Entry : EntryFnMDNodes) 3973734fa8cSS. Bharadwaj Yadavalli EntryPointsNamedMD->addOperand(Entry); 39881ee3855SJustin Bogner } 39981ee3855SJustin Bogner 40081ee3855SJustin Bogner PreservedAnalyses DXILTranslateMetadata::run(Module &M, 40181ee3855SJustin Bogner ModuleAnalysisManager &MAM) { 4023eca15cbSJustin Bogner DXILBindingMap &DBM = MAM.getResult<DXILResourceBindingAnalysis>(M); 4033eca15cbSJustin Bogner DXILResourceTypeMap &DRTM = MAM.getResult<DXILResourceTypeAnalysis>(M); 40481ee3855SJustin Bogner const dxil::Resources &MDResources = MAM.getResult<DXILResourceMDAnalysis>(M); 40596547decSS. Bharadwaj Yadavalli const ModuleShaderFlags &ShaderFlags = MAM.getResult<ShaderFlagsAnalysis>(M); 4063734fa8cSS. Bharadwaj Yadavalli const dxil::ModuleMetadataInfo MMDI = MAM.getResult<DXILMetadataAnalysis>(M); 40781ee3855SJustin Bogner 4083eca15cbSJustin Bogner translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI); 409*380bb51bSjoaosaffran translateBranchMetadata(M); 41081ee3855SJustin Bogner 41181ee3855SJustin Bogner return PreservedAnalyses::all(); 41281ee3855SJustin Bogner } 41381ee3855SJustin Bogner 4140c7f7f1bSpython3kgae namespace { 41581ee3855SJustin Bogner class DXILTranslateMetadataLegacy : public ModulePass { 4160c7f7f1bSpython3kgae public: 4170c7f7f1bSpython3kgae static char ID; // Pass identification, replacement for typeid 41881ee3855SJustin Bogner explicit DXILTranslateMetadataLegacy() : ModulePass(ID) {} 4190c7f7f1bSpython3kgae 4208107810cSJustin Bogner StringRef getPassName() const override { return "DXIL Translate Metadata"; } 4210c7f7f1bSpython3kgae 42222018555SXiang Li void getAnalysisUsage(AnalysisUsage &AU) const override { 4233eca15cbSJustin Bogner AU.addRequired<DXILResourceTypeWrapperPass>(); 4243eca15cbSJustin Bogner AU.addRequired<DXILResourceBindingWrapperPass>(); 4251c5f6cfcSJustin Bogner AU.addRequired<DXILResourceMDWrapper>(); 426b8615079SXiang Li AU.addRequired<ShaderFlagsAnalysisWrapper>(); 427eb2929d3SXiang Li AU.addRequired<DXILMetadataAnalysisWrapperPass>(); 4283eca15cbSJustin Bogner AU.addPreserved<DXILResourceBindingWrapperPass>(); 4293734fa8cSS. Bharadwaj Yadavalli AU.addPreserved<DXILResourceMDWrapper>(); 4303734fa8cSS. Bharadwaj Yadavalli AU.addPreserved<DXILMetadataAnalysisWrapperPass>(); 431bfd05102SJustin Bogner AU.addPreserved<ShaderFlagsAnalysisWrapper>(); 43222018555SXiang Li } 43322018555SXiang Li 43481ee3855SJustin Bogner bool runOnModule(Module &M) override { 4353eca15cbSJustin Bogner DXILBindingMap &DBM = 4363eca15cbSJustin Bogner getAnalysis<DXILResourceBindingWrapperPass>().getBindingMap(); 4373eca15cbSJustin Bogner DXILResourceTypeMap &DRTM = 4383eca15cbSJustin Bogner getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap(); 43981ee3855SJustin Bogner const dxil::Resources &MDResources = 44081ee3855SJustin Bogner getAnalysis<DXILResourceMDWrapper>().getDXILResource(); 44196547decSS. Bharadwaj Yadavalli const ModuleShaderFlags &ShaderFlags = 44281ee3855SJustin Bogner getAnalysis<ShaderFlagsAnalysisWrapper>().getShaderFlags(); 4433734fa8cSS. Bharadwaj Yadavalli dxil::ModuleMetadataInfo MMDI = 4443734fa8cSS. Bharadwaj Yadavalli getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata(); 44581ee3855SJustin Bogner 4463eca15cbSJustin Bogner translateMetadata(M, DBM, DRTM, MDResources, ShaderFlags, MMDI); 447*380bb51bSjoaosaffran translateBranchMetadata(M); 44881ee3855SJustin Bogner return true; 44981ee3855SJustin Bogner } 4500c7f7f1bSpython3kgae }; 4510c7f7f1bSpython3kgae 4520c7f7f1bSpython3kgae } // namespace 4530c7f7f1bSpython3kgae 45481ee3855SJustin Bogner char DXILTranslateMetadataLegacy::ID = 0; 4554959bfa0SChris Bieneman 45681ee3855SJustin Bogner ModulePass *llvm::createDXILTranslateMetadataLegacyPass() { 45781ee3855SJustin Bogner return new DXILTranslateMetadataLegacy(); 4580c7f7f1bSpython3kgae } 4590c7f7f1bSpython3kgae 46081ee3855SJustin Bogner INITIALIZE_PASS_BEGIN(DXILTranslateMetadataLegacy, "dxil-translate-metadata", 4618107810cSJustin Bogner "DXIL Translate Metadata", false, false) 4623eca15cbSJustin Bogner INITIALIZE_PASS_DEPENDENCY(DXILResourceBindingWrapperPass) 4631c5f6cfcSJustin Bogner INITIALIZE_PASS_DEPENDENCY(DXILResourceMDWrapper) 464b8615079SXiang Li INITIALIZE_PASS_DEPENDENCY(ShaderFlagsAnalysisWrapper) 4653734fa8cSS. Bharadwaj Yadavalli INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass) 46681ee3855SJustin Bogner INITIALIZE_PASS_END(DXILTranslateMetadataLegacy, "dxil-translate-metadata", 4678107810cSJustin Bogner "DXIL Translate Metadata", false, false) 468