103e6675fSS. Bharadwaj Yadavalli //=- DXILMetadataAnalysis.cpp - Representation of Module metadata -*- C++ -*=// 203e6675fSS. Bharadwaj Yadavalli // 303e6675fSS. Bharadwaj Yadavalli // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 403e6675fSS. Bharadwaj Yadavalli // See https://llvm.org/LICENSE.txt for license information. 503e6675fSS. Bharadwaj Yadavalli // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 603e6675fSS. Bharadwaj Yadavalli // 703e6675fSS. Bharadwaj Yadavalli //===----------------------------------------------------------------------===// 803e6675fSS. Bharadwaj Yadavalli 903e6675fSS. Bharadwaj Yadavalli #include "llvm/Analysis/DXILMetadataAnalysis.h" 1003e6675fSS. Bharadwaj Yadavalli #include "llvm/ADT/APInt.h" 118aa8c059SS. Bharadwaj Yadavalli #include "llvm/ADT/StringExtras.h" 128aa8c059SS. Bharadwaj Yadavalli #include "llvm/ADT/StringRef.h" 1303e6675fSS. Bharadwaj Yadavalli #include "llvm/IR/Constants.h" 1403e6675fSS. Bharadwaj Yadavalli #include "llvm/IR/Instructions.h" 1503e6675fSS. Bharadwaj Yadavalli #include "llvm/IR/Metadata.h" 1603e6675fSS. Bharadwaj Yadavalli #include "llvm/IR/Module.h" 1703e6675fSS. Bharadwaj Yadavalli #include "llvm/InitializePasses.h" 188aa8c059SS. Bharadwaj Yadavalli #include "llvm/Support/ErrorHandling.h" 1903e6675fSS. Bharadwaj Yadavalli 2003e6675fSS. Bharadwaj Yadavalli #define DEBUG_TYPE "dxil-metadata-analysis" 2103e6675fSS. Bharadwaj Yadavalli 2203e6675fSS. Bharadwaj Yadavalli using namespace llvm; 2303e6675fSS. Bharadwaj Yadavalli using namespace dxil; 2403e6675fSS. Bharadwaj Yadavalli 2503e6675fSS. Bharadwaj Yadavalli static ModuleMetadataInfo collectMetadataInfo(Module &M) { 2603e6675fSS. Bharadwaj Yadavalli ModuleMetadataInfo MMDAI; 2703e6675fSS. Bharadwaj Yadavalli Triple TT(Triple(M.getTargetTriple())); 2803e6675fSS. Bharadwaj Yadavalli MMDAI.DXILVersion = TT.getDXILVersion(); 2903e6675fSS. Bharadwaj Yadavalli MMDAI.ShaderModelVersion = TT.getOSVersion(); 30*3734fa8cSS. Bharadwaj Yadavalli MMDAI.ShaderProfile = TT.getEnvironment(); 3174f5ee4fSS. Bharadwaj Yadavalli NamedMDNode *ValidatorVerNode = M.getNamedMetadata("dx.valver"); 3274f5ee4fSS. Bharadwaj Yadavalli if (ValidatorVerNode) { 3374f5ee4fSS. Bharadwaj Yadavalli auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand(0)); 3474f5ee4fSS. Bharadwaj Yadavalli auto *MajorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(0)); 3574f5ee4fSS. Bharadwaj Yadavalli auto *MinorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(1)); 3674f5ee4fSS. Bharadwaj Yadavalli MMDAI.ValidatorVersion = 3774f5ee4fSS. Bharadwaj Yadavalli VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue()); 3874f5ee4fSS. Bharadwaj Yadavalli } 398aa8c059SS. Bharadwaj Yadavalli 408aa8c059SS. Bharadwaj Yadavalli // For all HLSL Shader functions 418aa8c059SS. Bharadwaj Yadavalli for (auto &F : M.functions()) { 428aa8c059SS. Bharadwaj Yadavalli if (!F.hasFnAttribute("hlsl.shader")) 438aa8c059SS. Bharadwaj Yadavalli continue; 448aa8c059SS. Bharadwaj Yadavalli 45*3734fa8cSS. Bharadwaj Yadavalli EntryProperties EFP(&F); 468aa8c059SS. Bharadwaj Yadavalli // Get "hlsl.shader" attribute 478aa8c059SS. Bharadwaj Yadavalli Attribute EntryAttr = F.getFnAttribute("hlsl.shader"); 488aa8c059SS. Bharadwaj Yadavalli assert(EntryAttr.isValid() && 498aa8c059SS. Bharadwaj Yadavalli "Invalid value specified for HLSL function attribute hlsl.shader"); 508aa8c059SS. Bharadwaj Yadavalli StringRef EntryProfile = EntryAttr.getValueAsString(); 518aa8c059SS. Bharadwaj Yadavalli Triple T("", "", "", EntryProfile); 528aa8c059SS. Bharadwaj Yadavalli EFP.ShaderStage = T.getEnvironment(); 538aa8c059SS. Bharadwaj Yadavalli // Get numthreads attribute value, if one exists 548aa8c059SS. Bharadwaj Yadavalli StringRef NumThreadsStr = 558aa8c059SS. Bharadwaj Yadavalli F.getFnAttribute("hlsl.numthreads").getValueAsString(); 568aa8c059SS. Bharadwaj Yadavalli if (!NumThreadsStr.empty()) { 578aa8c059SS. Bharadwaj Yadavalli SmallVector<StringRef> NumThreadsVec; 588aa8c059SS. Bharadwaj Yadavalli NumThreadsStr.split(NumThreadsVec, ','); 598aa8c059SS. Bharadwaj Yadavalli assert(NumThreadsVec.size() == 3 && "Invalid numthreads specified"); 608aa8c059SS. Bharadwaj Yadavalli // Read in the three component values of numthreads 618aa8c059SS. Bharadwaj Yadavalli [[maybe_unused]] bool Success = 628aa8c059SS. Bharadwaj Yadavalli llvm::to_integer(NumThreadsVec[0], EFP.NumThreadsX, 10); 638aa8c059SS. Bharadwaj Yadavalli assert(Success && "Failed to parse X component of numthreads"); 648aa8c059SS. Bharadwaj Yadavalli Success = llvm::to_integer(NumThreadsVec[1], EFP.NumThreadsY, 10); 658aa8c059SS. Bharadwaj Yadavalli assert(Success && "Failed to parse Y component of numthreads"); 668aa8c059SS. Bharadwaj Yadavalli Success = llvm::to_integer(NumThreadsVec[2], EFP.NumThreadsZ, 10); 678aa8c059SS. Bharadwaj Yadavalli assert(Success && "Failed to parse Z component of numthreads"); 688aa8c059SS. Bharadwaj Yadavalli } 698aa8c059SS. Bharadwaj Yadavalli MMDAI.EntryPropertyVec.push_back(EFP); 708aa8c059SS. Bharadwaj Yadavalli } 7103e6675fSS. Bharadwaj Yadavalli return MMDAI; 7203e6675fSS. Bharadwaj Yadavalli } 7303e6675fSS. Bharadwaj Yadavalli 7403e6675fSS. Bharadwaj Yadavalli void ModuleMetadataInfo::print(raw_ostream &OS) const { 7503e6675fSS. Bharadwaj Yadavalli OS << "Shader Model Version : " << ShaderModelVersion.getAsString() << "\n"; 7603e6675fSS. Bharadwaj Yadavalli OS << "DXIL Version : " << DXILVersion.getAsString() << "\n"; 77*3734fa8cSS. Bharadwaj Yadavalli OS << "Target Shader Stage : " 78*3734fa8cSS. Bharadwaj Yadavalli << Triple::getEnvironmentTypeName(ShaderProfile) << "\n"; 7974f5ee4fSS. Bharadwaj Yadavalli OS << "Validator Version : " << ValidatorVersion.getAsString() << "\n"; 808aa8c059SS. Bharadwaj Yadavalli for (const auto &EP : EntryPropertyVec) { 818aa8c059SS. Bharadwaj Yadavalli OS << " " << EP.Entry->getName() << "\n"; 828aa8c059SS. Bharadwaj Yadavalli OS << " Function Shader Stage : " 838aa8c059SS. Bharadwaj Yadavalli << Triple::getEnvironmentTypeName(EP.ShaderStage) << "\n"; 848aa8c059SS. Bharadwaj Yadavalli OS << " NumThreads: " << EP.NumThreadsX << "," << EP.NumThreadsY << "," 858aa8c059SS. Bharadwaj Yadavalli << EP.NumThreadsZ << "\n"; 868aa8c059SS. Bharadwaj Yadavalli } 8703e6675fSS. Bharadwaj Yadavalli } 8803e6675fSS. Bharadwaj Yadavalli 8903e6675fSS. Bharadwaj Yadavalli //===----------------------------------------------------------------------===// 9003e6675fSS. Bharadwaj Yadavalli // DXILMetadataAnalysis and DXILMetadataAnalysisPrinterPass 9103e6675fSS. Bharadwaj Yadavalli 9203e6675fSS. Bharadwaj Yadavalli // Provide an explicit template instantiation for the static ID. 9303e6675fSS. Bharadwaj Yadavalli AnalysisKey DXILMetadataAnalysis::Key; 9403e6675fSS. Bharadwaj Yadavalli 9503e6675fSS. Bharadwaj Yadavalli llvm::dxil::ModuleMetadataInfo 9603e6675fSS. Bharadwaj Yadavalli DXILMetadataAnalysis::run(Module &M, ModuleAnalysisManager &AM) { 9703e6675fSS. Bharadwaj Yadavalli return collectMetadataInfo(M); 9803e6675fSS. Bharadwaj Yadavalli } 9903e6675fSS. Bharadwaj Yadavalli 10003e6675fSS. Bharadwaj Yadavalli PreservedAnalyses 10103e6675fSS. Bharadwaj Yadavalli DXILMetadataAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) { 10203e6675fSS. Bharadwaj Yadavalli llvm::dxil::ModuleMetadataInfo &Data = AM.getResult<DXILMetadataAnalysis>(M); 10303e6675fSS. Bharadwaj Yadavalli 10403e6675fSS. Bharadwaj Yadavalli Data.print(OS); 10503e6675fSS. Bharadwaj Yadavalli return PreservedAnalyses::all(); 10603e6675fSS. Bharadwaj Yadavalli } 10703e6675fSS. Bharadwaj Yadavalli 10803e6675fSS. Bharadwaj Yadavalli //===----------------------------------------------------------------------===// 10903e6675fSS. Bharadwaj Yadavalli // DXILMetadataAnalysisWrapperPass 11003e6675fSS. Bharadwaj Yadavalli 11103e6675fSS. Bharadwaj Yadavalli DXILMetadataAnalysisWrapperPass::DXILMetadataAnalysisWrapperPass() 11203e6675fSS. Bharadwaj Yadavalli : ModulePass(ID) { 11303e6675fSS. Bharadwaj Yadavalli initializeDXILMetadataAnalysisWrapperPassPass( 11403e6675fSS. Bharadwaj Yadavalli *PassRegistry::getPassRegistry()); 11503e6675fSS. Bharadwaj Yadavalli } 11603e6675fSS. Bharadwaj Yadavalli 11703e6675fSS. Bharadwaj Yadavalli DXILMetadataAnalysisWrapperPass::~DXILMetadataAnalysisWrapperPass() = default; 11803e6675fSS. Bharadwaj Yadavalli 11903e6675fSS. Bharadwaj Yadavalli void DXILMetadataAnalysisWrapperPass::getAnalysisUsage( 12003e6675fSS. Bharadwaj Yadavalli AnalysisUsage &AU) const { 12103e6675fSS. Bharadwaj Yadavalli AU.setPreservesAll(); 12203e6675fSS. Bharadwaj Yadavalli } 12303e6675fSS. Bharadwaj Yadavalli 12403e6675fSS. Bharadwaj Yadavalli bool DXILMetadataAnalysisWrapperPass::runOnModule(Module &M) { 12503e6675fSS. Bharadwaj Yadavalli MetadataInfo.reset(new ModuleMetadataInfo(collectMetadataInfo(M))); 12603e6675fSS. Bharadwaj Yadavalli return false; 12703e6675fSS. Bharadwaj Yadavalli } 12803e6675fSS. Bharadwaj Yadavalli 12903e6675fSS. Bharadwaj Yadavalli void DXILMetadataAnalysisWrapperPass::releaseMemory() { MetadataInfo.reset(); } 13003e6675fSS. Bharadwaj Yadavalli 13103e6675fSS. Bharadwaj Yadavalli void DXILMetadataAnalysisWrapperPass::print(raw_ostream &OS, 13203e6675fSS. Bharadwaj Yadavalli const Module *) const { 13303e6675fSS. Bharadwaj Yadavalli if (!MetadataInfo) { 13403e6675fSS. Bharadwaj Yadavalli OS << "No module metadata info has been built!\n"; 13503e6675fSS. Bharadwaj Yadavalli return; 13603e6675fSS. Bharadwaj Yadavalli } 13703e6675fSS. Bharadwaj Yadavalli MetadataInfo->print(dbgs()); 13803e6675fSS. Bharadwaj Yadavalli } 13903e6675fSS. Bharadwaj Yadavalli 14003e6675fSS. Bharadwaj Yadavalli #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 14103e6675fSS. Bharadwaj Yadavalli LLVM_DUMP_METHOD 14203e6675fSS. Bharadwaj Yadavalli void DXILMetadataAnalysisWrapperPass::dump() const { print(dbgs(), nullptr); } 14303e6675fSS. Bharadwaj Yadavalli #endif 14403e6675fSS. Bharadwaj Yadavalli 14503e6675fSS. Bharadwaj Yadavalli INITIALIZE_PASS(DXILMetadataAnalysisWrapperPass, "dxil-metadata-analysis", 14603e6675fSS. Bharadwaj Yadavalli "DXIL Module Metadata analysis", false, true) 14703e6675fSS. Bharadwaj Yadavalli char DXILMetadataAnalysisWrapperPass::ID = 0; 148