brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · bd77cba Raw
161 lines · cpp
1//=- DXILMetadataAnalysis.cpp - Representation of Module metadata -*- C++ -*=//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/Analysis/DXILMetadataAnalysis.h"10#include "llvm/ADT/APInt.h"11#include "llvm/ADT/StringExtras.h"12#include "llvm/ADT/StringRef.h"13#include "llvm/IR/Constants.h"14#include "llvm/IR/Instructions.h"15#include "llvm/IR/Metadata.h"16#include "llvm/IR/Module.h"17#include "llvm/InitializePasses.h"18#include "llvm/Support/ErrorHandling.h"19 20#define DEBUG_TYPE "dxil-metadata-analysis"21 22using namespace llvm;23using namespace dxil;24 25static ModuleMetadataInfo collectMetadataInfo(Module &M) {26  ModuleMetadataInfo MMDAI;27  const Triple &TT = M.getTargetTriple();28  MMDAI.DXILVersion = TT.getDXILVersion();29  MMDAI.ShaderModelVersion = TT.getOSVersion();30  MMDAI.ShaderProfile = TT.getEnvironment();31  NamedMDNode *ValidatorVerNode = M.getNamedMetadata("dx.valver");32  if (ValidatorVerNode) {33    auto *ValVerMD = cast<MDNode>(ValidatorVerNode->getOperand(0));34    auto *MajorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(0));35    auto *MinorMD = mdconst::extract<ConstantInt>(ValVerMD->getOperand(1));36    MMDAI.ValidatorVersion =37        VersionTuple(MajorMD->getZExtValue(), MinorMD->getZExtValue());38  }39 40  // For all HLSL Shader functions41  for (auto &F : M.functions()) {42    if (!F.hasFnAttribute("hlsl.shader"))43      continue;44 45    EntryProperties EFP(&F);46    // Get "hlsl.shader" attribute47    Attribute EntryAttr = F.getFnAttribute("hlsl.shader");48    assert(EntryAttr.isValid() &&49           "Invalid value specified for HLSL function attribute hlsl.shader");50    StringRef EntryProfile = EntryAttr.getValueAsString();51    Triple T("", "", "", EntryProfile);52    EFP.ShaderStage = T.getEnvironment();53    // Get numthreads attribute value, if one exists54    StringRef NumThreadsStr =55        F.getFnAttribute("hlsl.numthreads").getValueAsString();56    if (!NumThreadsStr.empty()) {57      SmallVector<StringRef> NumThreadsVec;58      NumThreadsStr.split(NumThreadsVec, ',');59      assert(NumThreadsVec.size() == 3 && "Invalid numthreads specified");60      // Read in the three component values of numthreads61      [[maybe_unused]] bool Success =62          llvm::to_integer(NumThreadsVec[0], EFP.NumThreadsX, 10);63      assert(Success && "Failed to parse X component of numthreads");64      Success = llvm::to_integer(NumThreadsVec[1], EFP.NumThreadsY, 10);65      assert(Success && "Failed to parse Y component of numthreads");66      Success = llvm::to_integer(NumThreadsVec[2], EFP.NumThreadsZ, 10);67      assert(Success && "Failed to parse Z component of numthreads");68    }69    // Get wavesize attribute value, if one exists70    StringRef WaveSizeStr =71        F.getFnAttribute("hlsl.wavesize").getValueAsString();72    if (!WaveSizeStr.empty()) {73      SmallVector<StringRef> WaveSizeVec;74      WaveSizeStr.split(WaveSizeVec, ',');75      assert(WaveSizeVec.size() == 3 && "Invalid wavesize specified");76      // Read in the three component values of numthreads77      [[maybe_unused]] bool Success =78          llvm::to_integer(WaveSizeVec[0], EFP.WaveSizeMin, 10);79      assert(Success && "Failed to parse Min component of wavesize");80      Success = llvm::to_integer(WaveSizeVec[1], EFP.WaveSizeMax, 10);81      assert(Success && "Failed to parse Max component of wavesize");82      Success = llvm::to_integer(WaveSizeVec[2], EFP.WaveSizePref, 10);83      assert(Success && "Failed to parse Preferred component of wavesize");84    }85    MMDAI.EntryPropertyVec.push_back(EFP);86  }87  return MMDAI;88}89 90void ModuleMetadataInfo::print(raw_ostream &OS) const {91  OS << "Shader Model Version : " << ShaderModelVersion.getAsString() << "\n";92  OS << "DXIL Version : " << DXILVersion.getAsString() << "\n";93  OS << "Target Shader Stage : "94     << Triple::getEnvironmentTypeName(ShaderProfile) << "\n";95  OS << "Validator Version : " << ValidatorVersion.getAsString() << "\n";96  for (const auto &EP : EntryPropertyVec) {97    OS << " " << EP.Entry->getName() << "\n";98    OS << "  Function Shader Stage : "99       << Triple::getEnvironmentTypeName(EP.ShaderStage) << "\n";100    OS << "  NumThreads: " << EP.NumThreadsX << "," << EP.NumThreadsY << ","101       << EP.NumThreadsZ << "\n";102  }103}104 105//===----------------------------------------------------------------------===//106// DXILMetadataAnalysis and DXILMetadataAnalysisPrinterPass107 108// Provide an explicit template instantiation for the static ID.109AnalysisKey DXILMetadataAnalysis::Key;110 111llvm::dxil::ModuleMetadataInfo112DXILMetadataAnalysis::run(Module &M, ModuleAnalysisManager &AM) {113  return collectMetadataInfo(M);114}115 116PreservedAnalyses117DXILMetadataAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {118  llvm::dxil::ModuleMetadataInfo &Data = AM.getResult<DXILMetadataAnalysis>(M);119 120  Data.print(OS);121  return PreservedAnalyses::all();122}123 124//===----------------------------------------------------------------------===//125// DXILMetadataAnalysisWrapperPass126 127DXILMetadataAnalysisWrapperPass::DXILMetadataAnalysisWrapperPass()128    : ModulePass(ID) {}129 130DXILMetadataAnalysisWrapperPass::~DXILMetadataAnalysisWrapperPass() = default;131 132void DXILMetadataAnalysisWrapperPass::getAnalysisUsage(133    AnalysisUsage &AU) const {134  AU.setPreservesAll();135}136 137bool DXILMetadataAnalysisWrapperPass::runOnModule(Module &M) {138  MetadataInfo.reset(new ModuleMetadataInfo(collectMetadataInfo(M)));139  return false;140}141 142void DXILMetadataAnalysisWrapperPass::releaseMemory() { MetadataInfo.reset(); }143 144void DXILMetadataAnalysisWrapperPass::print(raw_ostream &OS,145                                            const Module *) const {146  if (!MetadataInfo) {147    OS << "No module metadata info has been built!\n";148    return;149  }150  MetadataInfo->print(dbgs());151}152 153#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)154LLVM_DUMP_METHOD155void DXILMetadataAnalysisWrapperPass::dump() const { print(dbgs(), nullptr); }156#endif157 158INITIALIZE_PASS(DXILMetadataAnalysisWrapperPass, "dxil-metadata-analysis",159                "DXIL Module Metadata analysis", false, true)160char DXILMetadataAnalysisWrapperPass::ID = 0;161