-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[DirectX] Infrastructure to collect shader flags for each function #112967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
3da01ee
397f70b
ae373d4
c02053a
47ab4c5
fa8ec60
a4f1e51
a6d84b2
31b0770
3427781
56af02a
f8e501f
c6b3390
70e46e0
07734f7
a0d2a31
2cee00a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -13,36 +13,88 @@ | |||||
|
|
||||||
| #include "DXILShaderFlags.h" | ||||||
| #include "DirectX.h" | ||||||
| #include "llvm/ADT/STLExtras.h" | ||||||
| #include "llvm/IR/DiagnosticInfo.h" | ||||||
| #include "llvm/IR/DiagnosticPrinter.h" | ||||||
| #include "llvm/IR/Instruction.h" | ||||||
| #include "llvm/IR/Module.h" | ||||||
| #include "llvm/Support/FormatVariadic.h" | ||||||
| #include "llvm/Support/raw_ostream.h" | ||||||
|
|
||||||
| using namespace llvm; | ||||||
| using namespace llvm::dxil; | ||||||
|
|
||||||
| static void updateFlags(ComputedShaderFlags &Flags, const Instruction &I) { | ||||||
| namespace { | ||||||
| /// A simple Wrapper DiagnosticInfo that generates Module-level diagnostic | ||||||
| /// for ShaderFlagsAnalysis pass | ||||||
| class DiagnosticInfoShaderFlags : public DiagnosticInfo { | ||||||
| private: | ||||||
| const Twine &Msg; | ||||||
|
||||||
| const Module &Mod; | ||||||
|
|
||||||
| public: | ||||||
| /// \p M is the module for which the diagnostic is being emitted. \p Msg is | ||||||
| /// the message to show. Note that this class does not copy this message, so | ||||||
| /// this reference must be valid for the whole life time of the diagnostic. | ||||||
| DiagnosticInfoShaderFlags(const Module &M, const Twine &Msg, | ||||||
| DiagnosticSeverity Severity = DS_Error) | ||||||
| : DiagnosticInfo(DK_Unsupported, Severity), Msg(Msg), Mod(M) {} | ||||||
|
|
||||||
| void print(DiagnosticPrinter &DP) const override { | ||||||
| DP << Mod.getName() << ": " << Msg << '\n'; | ||||||
| } | ||||||
| }; | ||||||
| } // namespace | ||||||
|
|
||||||
| static void updateFlags(ComputedShaderFlags &CSF, const Instruction &I) { | ||||||
| Type *Ty = I.getType(); | ||||||
| if (Ty->isDoubleTy()) { | ||||||
| Flags.Doubles = true; | ||||||
| bool DoubleTyInUse = Ty->isDoubleTy(); | ||||||
| for (Value *Op : I.operands()) { | ||||||
| DoubleTyInUse |= Op->getType()->isDoubleTy(); | ||||||
| } | ||||||
|
|
||||||
| if (DoubleTyInUse) { | ||||||
| CSF.Doubles = true; | ||||||
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| switch (I.getOpcode()) { | ||||||
| case Instruction::FDiv: | ||||||
| case Instruction::UIToFP: | ||||||
| case Instruction::SIToFP: | ||||||
| case Instruction::FPToUI: | ||||||
| case Instruction::FPToSI: | ||||||
| Flags.DX11_1_DoubleExtensions = true; | ||||||
| // TODO: To be set if I is a call to DXIL intrinsic DXIL::Opcode::Fma | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have an issue for this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||
| CSF.DX11_1_DoubleExtensions = true; | ||||||
| break; | ||||||
| } | ||||||
| } | ||||||
| } | ||||||
|
|
||||||
| ComputedShaderFlags ComputedShaderFlags::computeFlags(Module &M) { | ||||||
| ComputedShaderFlags Flags; | ||||||
| for (const auto &F : M) | ||||||
| static bool compareFuncSFPairs(const FuncShaderFlagsMask &First, | ||||||
| const FuncShaderFlagsMask &Second) { | ||||||
| return (First.first->getName().compare(Second.first->getName()) < 0); | ||||||
damyanp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| } | ||||||
|
|
||||||
| static DXILModuleShaderFlagsInfo computeFlags(Module &M) { | ||||||
| DXILModuleShaderFlagsInfo MSFI; | ||||||
damyanp marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| for (auto &F : M) { | ||||||
| if (F.isDeclaration()) | ||||||
| continue; | ||||||
| // Each of the functions in a module are unique. Hence no prior shader flags | ||||||
| // mask of the function should be present. | ||||||
| if (MSFI.hasShaderFlagsMask(&F)) { | ||||||
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| M.getContext().diagnose( | ||||||
| DiagnosticInfoShaderFlags(M, "Shader Flags mask for Function '" + | ||||||
| F.getName() + "' already exists")); | ||||||
| } | ||||||
| ComputedShaderFlags CSF{}; | ||||||
|
||||||
| ComputedShaderFlags CSF{}; | |
| ComputedShaderFlags CSF; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: ComputedShaderFlags has a default constructor to zero itself out, the empty initializer list is unnecessary.
Changed.
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
bogner marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #ifndef LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H | ||
| #define LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H | ||
|
|
||
| #include "llvm/IR/Function.h" | ||
| #include "llvm/IR/PassManager.h" | ||
| #include "llvm/Pass.h" | ||
| #include "llvm/Support/Compiler.h" | ||
|
|
@@ -60,21 +61,34 @@ struct ComputedShaderFlags { | |
| return FeatureFlags; | ||
| } | ||
|
|
||
| static ComputedShaderFlags computeFlags(Module &M); | ||
| void print(raw_ostream &OS = dbgs()) const; | ||
| LLVM_DUMP_METHOD void dump() const { print(); } | ||
| }; | ||
|
|
||
| using FuncShaderFlagsMask = std::pair<Function const *, ComputedShaderFlags>; | ||
| using FunctionShaderFlagsVec = SmallVector<FuncShaderFlagsMask>; | ||
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| struct DXILModuleShaderFlagsInfo { | ||
|
||
| // Shader Flag mask representing module-level properties | ||
| ComputedShaderFlags ModuleFlags; | ||
| // Vector of Function-Shader Flag mask pairs representing properties of each | ||
| // of the functions in the module | ||
| FunctionShaderFlagsVec FuncShaderFlagsVec; | ||
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
bharadwajy marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const ComputedShaderFlags getShaderFlagsMask(const Function *Func) const; | ||
| bool hasShaderFlagsMask(const Function *Func) const; | ||
| void print(raw_ostream &OS = dbgs()) const; | ||
bogner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| class ShaderFlagsAnalysis : public AnalysisInfoMixin<ShaderFlagsAnalysis> { | ||
| friend AnalysisInfoMixin<ShaderFlagsAnalysis>; | ||
| static AnalysisKey Key; | ||
|
|
||
| public: | ||
| ShaderFlagsAnalysis() = default; | ||
|
|
||
| using Result = ComputedShaderFlags; | ||
| using Result = DXILModuleShaderFlagsInfo; | ||
|
|
||
| ComputedShaderFlags run(Module &M, ModuleAnalysisManager &AM); | ||
| DXILModuleShaderFlagsInfo run(Module &M, ModuleAnalysisManager &AM); | ||
| }; | ||
|
|
||
| /// Printer pass for ShaderFlagsAnalysis results. | ||
|
|
@@ -92,19 +106,16 @@ class ShaderFlagsAnalysisPrinter | |
| /// This is required because the passes that will depend on this are codegen | ||
| /// passes which run through the legacy pass manager. | ||
| class ShaderFlagsAnalysisWrapper : public ModulePass { | ||
| ComputedShaderFlags Flags; | ||
| DXILModuleShaderFlagsInfo MSFI; | ||
|
|
||
| public: | ||
| static char ID; | ||
|
|
||
| ShaderFlagsAnalysisWrapper() : ModulePass(ID) {} | ||
|
|
||
| const ComputedShaderFlags &getShaderFlags() { return Flags; } | ||
| const DXILModuleShaderFlagsInfo &getShaderFlags() { return MSFI; } | ||
|
|
||
| bool runOnModule(Module &M) override { | ||
| Flags = ComputedShaderFlags::computeFlags(M); | ||
| return false; | ||
| } | ||
| bool runOnModule(Module &M) override; | ||
|
|
||
| void getAnalysisUsage(AnalysisUsage &AU) const override { | ||
| AU.setPreservesAll(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| ; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC | ||
bogner marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| target triple = "dxil-pc-shadermodel6.7-library" | ||
| define double @div(double %a, double %b) #0 { | ||
| %res = fdiv double %a, %b | ||
| ret double %res | ||
| } | ||
|
|
||
| attributes #0 = { convergent norecurse nounwind "hlsl.export"} | ||
|
|
||
| ; DXC: - Name: SFI0 | ||
| ; DXC-NEXT: Size: 8 | ||
| ; DXC-NEXT: Flags: | ||
| ; DXC-NEXT: Doubles: true | ||
| ; DXC-NOT: {{[A-Za-z]+: +true}} | ||
| ; DXC: DX11_1_DoubleExtensions: true | ||
| ; DXC-NOT: {{[A-Za-z]+: +true}} | ||
| ; DXC: NextUnusedBit: false | ||
|
||
| ; DXC: ... | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have an issue tracking this?