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
updateFlags(ComputedShaderFlags & Flags,const Instruction & I)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
computeFlags(Module & M)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
print(raw_ostream & OS) const48*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
run(Module & M,ModuleAnalysisManager & AM)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
run(Module & M,ModuleAnalysisManager & AM)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