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