1*bdd1243dSDimitry Andric //===- DXILShaderFlags.cpp - DXIL Shader Flags helper objects -------------===// 2*bdd1243dSDimitry Andric // 3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*bdd1243dSDimitry Andric // 7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 8*bdd1243dSDimitry Andric /// 9*bdd1243dSDimitry Andric /// \file This file contains helper objects and APIs for working with DXIL 10*bdd1243dSDimitry Andric /// Shader Flags. 11*bdd1243dSDimitry Andric /// 12*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===// 13*bdd1243dSDimitry Andric 14*bdd1243dSDimitry Andric #include "DXILShaderFlags.h" 15*bdd1243dSDimitry Andric #include "DirectX.h" 16*bdd1243dSDimitry Andric #include "llvm/IR/Instruction.h" 17*bdd1243dSDimitry Andric #include "llvm/IR/Module.h" 18*bdd1243dSDimitry Andric #include "llvm/Support/FormatVariadic.h" 19*bdd1243dSDimitry Andric 20*bdd1243dSDimitry Andric using namespace llvm; 21*bdd1243dSDimitry Andric using namespace llvm::dxil; 22*bdd1243dSDimitry Andric 23*bdd1243dSDimitry Andric static void updateFlags(ComputedShaderFlags &Flags, const Instruction &I) { 24*bdd1243dSDimitry Andric Type *Ty = I.getType(); 25*bdd1243dSDimitry Andric if (Ty->isDoubleTy()) { 26*bdd1243dSDimitry Andric Flags.Doubles = true; 27*bdd1243dSDimitry Andric switch (I.getOpcode()) { 28*bdd1243dSDimitry Andric case Instruction::FDiv: 29*bdd1243dSDimitry Andric case Instruction::UIToFP: 30*bdd1243dSDimitry Andric case Instruction::SIToFP: 31*bdd1243dSDimitry Andric case Instruction::FPToUI: 32*bdd1243dSDimitry Andric case Instruction::FPToSI: 33*bdd1243dSDimitry Andric Flags.DX11_1_DoubleExtensions = true; 34*bdd1243dSDimitry Andric break; 35*bdd1243dSDimitry Andric } 36*bdd1243dSDimitry Andric } 37*bdd1243dSDimitry Andric } 38*bdd1243dSDimitry Andric 39*bdd1243dSDimitry Andric ComputedShaderFlags ComputedShaderFlags::computeFlags(Module &M) { 40*bdd1243dSDimitry Andric ComputedShaderFlags Flags; 41*bdd1243dSDimitry Andric for (const auto &F : M) 42*bdd1243dSDimitry Andric for (const auto &BB : F) 43*bdd1243dSDimitry Andric for (const auto &I : BB) 44*bdd1243dSDimitry Andric updateFlags(Flags, I); 45*bdd1243dSDimitry Andric return Flags; 46*bdd1243dSDimitry Andric } 47*bdd1243dSDimitry Andric 48*bdd1243dSDimitry Andric void ComputedShaderFlags::print(raw_ostream &OS) const { 49*bdd1243dSDimitry Andric uint64_t FlagVal = (uint64_t) * this; 50*bdd1243dSDimitry Andric OS << formatv("; Shader Flags Value: {0:x8}\n;\n", FlagVal); 51*bdd1243dSDimitry Andric if (FlagVal == 0) 52*bdd1243dSDimitry Andric return; 53*bdd1243dSDimitry Andric OS << "; Note: shader requires additional functionality:\n"; 54*bdd1243dSDimitry Andric #define SHADER_FLAG(bit, FlagName, Str) \ 55*bdd1243dSDimitry Andric if (FlagName) \ 56*bdd1243dSDimitry Andric OS << "; " Str "\n"; 57*bdd1243dSDimitry Andric #include "llvm/BinaryFormat/DXContainerConstants.def" 58*bdd1243dSDimitry Andric OS << ";\n"; 59*bdd1243dSDimitry Andric } 60*bdd1243dSDimitry Andric 61*bdd1243dSDimitry Andric AnalysisKey ShaderFlagsAnalysis::Key; 62*bdd1243dSDimitry Andric 63*bdd1243dSDimitry Andric ComputedShaderFlags ShaderFlagsAnalysis::run(Module &M, 64*bdd1243dSDimitry Andric ModuleAnalysisManager &AM) { 65*bdd1243dSDimitry Andric return ComputedShaderFlags::computeFlags(M); 66*bdd1243dSDimitry Andric } 67*bdd1243dSDimitry Andric 68*bdd1243dSDimitry Andric PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M, 69*bdd1243dSDimitry Andric ModuleAnalysisManager &AM) { 70*bdd1243dSDimitry Andric ComputedShaderFlags Flags = AM.getResult<ShaderFlagsAnalysis>(M); 71*bdd1243dSDimitry Andric Flags.print(OS); 72*bdd1243dSDimitry Andric return PreservedAnalyses::all(); 73*bdd1243dSDimitry Andric } 74*bdd1243dSDimitry Andric 75*bdd1243dSDimitry Andric char ShaderFlagsAnalysisWrapper::ID = 0; 76*bdd1243dSDimitry Andric 77*bdd1243dSDimitry Andric INITIALIZE_PASS(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis", 78*bdd1243dSDimitry Andric "DXIL Shader Flag Analysis", true, true) 79