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
updateFlags(ComputedShaderFlags & Flags,const Instruction & I)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
computeFlags(Module & M)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
print(raw_ostream & OS) const48bdd1243dSDimitry 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
run(Module & M,ModuleAnalysisManager & AM)68bdd1243dSDimitry Andric ComputedShaderFlags ShaderFlagsAnalysis::run(Module &M,
69bdd1243dSDimitry Andric ModuleAnalysisManager &AM) {
70bdd1243dSDimitry Andric return ComputedShaderFlags::computeFlags(M);
71bdd1243dSDimitry Andric }
72bdd1243dSDimitry Andric
run(Module & M,ModuleAnalysisManager & AM)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