xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/DirectX/DXILShaderFlags.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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