1bdd1243dSDimitry Andric //===- DXILShaderFlags.cpp - DXIL Shader Flags 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 and APIs for working with DXIL 10bdd1243dSDimitry Andric /// Shader Flags. 11bdd1243dSDimitry Andric /// 12bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 13bdd1243dSDimitry Andric 14bdd1243dSDimitry Andric #include "DXILShaderFlags.h" 15bdd1243dSDimitry Andric #include "DirectX.h" 16bdd1243dSDimitry Andric #include "llvm/IR/Instruction.h" 17bdd1243dSDimitry Andric #include "llvm/IR/Module.h" 18bdd1243dSDimitry Andric #include "llvm/Support/FormatVariadic.h" 19bdd1243dSDimitry Andric 20bdd1243dSDimitry Andric using namespace llvm; 21bdd1243dSDimitry Andric using namespace llvm::dxil; 22bdd1243dSDimitry Andric 23bdd1243dSDimitry Andric static void updateFlags(ComputedShaderFlags &Flags, const Instruction &I) { 24bdd1243dSDimitry Andric Type *Ty = I.getType(); 25bdd1243dSDimitry Andric if (Ty->isDoubleTy()) { 26bdd1243dSDimitry Andric Flags.Doubles = true; 27bdd1243dSDimitry Andric switch (I.getOpcode()) { 28bdd1243dSDimitry Andric case Instruction::FDiv: 29bdd1243dSDimitry Andric case Instruction::UIToFP: 30bdd1243dSDimitry Andric case Instruction::SIToFP: 31bdd1243dSDimitry Andric case Instruction::FPToUI: 32bdd1243dSDimitry Andric case Instruction::FPToSI: 33bdd1243dSDimitry Andric Flags.DX11_1_DoubleExtensions = true; 34bdd1243dSDimitry Andric break; 35bdd1243dSDimitry Andric } 36bdd1243dSDimitry Andric } 37bdd1243dSDimitry Andric } 38bdd1243dSDimitry Andric 39bdd1243dSDimitry Andric ComputedShaderFlags ComputedShaderFlags::computeFlags(Module &M) { 40bdd1243dSDimitry Andric ComputedShaderFlags Flags; 41bdd1243dSDimitry Andric for (const auto &F : M) 42bdd1243dSDimitry Andric for (const auto &BB : F) 43bdd1243dSDimitry Andric for (const auto &I : BB) 44bdd1243dSDimitry Andric updateFlags(Flags, I); 45bdd1243dSDimitry Andric return Flags; 46bdd1243dSDimitry Andric } 47bdd1243dSDimitry Andric 48bdd1243dSDimitry Andric void ComputedShaderFlags::print(raw_ostream &OS) const { 49bdd1243dSDimitry Andric uint64_t FlagVal = (uint64_t) * this; 50bdd1243dSDimitry Andric OS << formatv("; Shader Flags Value: {0:x8}\n;\n", FlagVal); 51bdd1243dSDimitry Andric if (FlagVal == 0) 52bdd1243dSDimitry Andric return; 53bdd1243dSDimitry Andric OS << "; Note: shader requires additional functionality:\n"; 54*0fca6ea1SDimitry Andric #define SHADER_FEATURE_FLAG(FeatureBit, DxilModuleNum, FlagName, Str) \ 55bdd1243dSDimitry Andric if (FlagName) \ 56*0fca6ea1SDimitry Andric (OS << ";").indent(7) << Str << "\n"; 57*0fca6ea1SDimitry Andric #include "llvm/BinaryFormat/DXContainerConstants.def" 58*0fca6ea1SDimitry Andric OS << "; Note: extra DXIL module flags:\n"; 59*0fca6ea1SDimitry Andric #define DXIL_MODULE_FLAG(DxilModuleBit, FlagName, Str) \ 60*0fca6ea1SDimitry Andric if (FlagName) \ 61*0fca6ea1SDimitry Andric (OS << ";").indent(7) << Str << "\n"; 62bdd1243dSDimitry Andric #include "llvm/BinaryFormat/DXContainerConstants.def" 63bdd1243dSDimitry Andric OS << ";\n"; 64bdd1243dSDimitry Andric } 65bdd1243dSDimitry Andric 66bdd1243dSDimitry Andric AnalysisKey ShaderFlagsAnalysis::Key; 67bdd1243dSDimitry Andric 68bdd1243dSDimitry Andric ComputedShaderFlags ShaderFlagsAnalysis::run(Module &M, 69bdd1243dSDimitry Andric ModuleAnalysisManager &AM) { 70bdd1243dSDimitry Andric return ComputedShaderFlags::computeFlags(M); 71bdd1243dSDimitry Andric } 72bdd1243dSDimitry Andric 73bdd1243dSDimitry Andric PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M, 74bdd1243dSDimitry Andric ModuleAnalysisManager &AM) { 75bdd1243dSDimitry Andric ComputedShaderFlags Flags = AM.getResult<ShaderFlagsAnalysis>(M); 76bdd1243dSDimitry Andric Flags.print(OS); 77bdd1243dSDimitry Andric return PreservedAnalyses::all(); 78bdd1243dSDimitry Andric } 79bdd1243dSDimitry Andric 80bdd1243dSDimitry Andric char ShaderFlagsAnalysisWrapper::ID = 0; 81bdd1243dSDimitry Andric 82bdd1243dSDimitry Andric INITIALIZE_PASS(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis", 83bdd1243dSDimitry Andric "DXIL Shader Flag Analysis", true, true) 84