From 1dda593f3034839b3323b1517bf2afe3cb7d35d6 Mon Sep 17 00:00:00 2001 From: "S. Bharadwaj Yadavalli" Date: Wed, 15 Jan 2025 15:56:37 -0500 Subject: [PATCH 1/2] [DirectX] Set Shader Flag DisableOptimizations. Disabling optimizations using the option -Od to clang-dxc results in generation of named metadata "dx.disable_optimizations". - Detect metadata "dx.disable_optimizations" as part of Metadata Analysis pass and set a new bool field ModuleMetadatainfo::DisableOptimization accordingly. - Add DXILMetadataAnalysis as required pass for the pass ShaderFlags that sets shader flags mask. - Set shader flag DisableOptimization based on the value of ModuleMetadatainfo::DisableOptimization. Updated llc-pipeline.ll to reflect changes in output resulting from addition of Metadata Analysis pass as required by ShaderFlags pass. --- .../llvm/Analysis/DXILMetadataAnalysis.h | 1 + llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 16 ++++++++++++ llvm/lib/Target/DirectX/DXILShaderFlags.cpp | 15 ++++++++--- llvm/lib/Target/DirectX/DXILShaderFlags.h | 4 ++- .../DirectX/ShaderFlags/disable-opt.ll | 25 +++++++++++++++++++ llvm/test/CodeGen/DirectX/llc-pipeline.ll | 2 +- 6 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll diff --git a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h index cb535ac14f1c6..93a926c8991a8 100644 --- a/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h +++ b/llvm/include/llvm/Analysis/DXILMetadataAnalysis.h @@ -37,6 +37,7 @@ struct ModuleMetadataInfo { Triple::EnvironmentType ShaderProfile{Triple::UnknownEnvironment}; VersionTuple ValidatorVersion{}; SmallVector EntryPropertyVec{}; + bool DisableOptimizations{false}; void print(raw_ostream &OS) const; }; diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index a7f666a3f8b48..426559c64f876 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -68,6 +68,22 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { } MMDAI.EntryPropertyVec.push_back(EFP); } + + // Set shader flags based on Module properties + SmallVector FlagEntries; + M.getModuleFlagsMetadata(FlagEntries); + for (const auto &Flag : FlagEntries) { + if (Flag.Behavior != Module::ModFlagBehavior::Override) + continue; + if (Flag.Key->getString().compare("dx.disable_optimizations") == 0) { + const auto *V = mdconst::extract(Flag.Val); + if (V->isOne()) { + MMDAI.DisableOptimizations = true; + break; + } + } + } + return MMDAI; } diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp index 6a15bac153d85..f50824c556768 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp @@ -96,7 +96,8 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, } /// Construct ModuleShaderFlags for module Module M -void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM) { +void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, + const ModuleMetadataInfo &MMDI) { CallGraph CG(M); // Compute Shader Flags Mask for all functions using post-order visit of SCC @@ -142,6 +143,9 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM) { // Merge SCCSF with that of F FunctionFlags[F].merge(SCCSF); } + + // Set shader flags based on Module properties based on module metadata + CombinedSFMask.DisableOptimizations = MMDI.DisableOptimizations; } void ComputedShaderFlags::print(raw_ostream &OS) const { @@ -180,9 +184,10 @@ AnalysisKey ShaderFlagsAnalysis::Key; ModuleShaderFlags ShaderFlagsAnalysis::run(Module &M, ModuleAnalysisManager &AM) { DXILResourceTypeMap &DRTM = AM.getResult(M); + const ModuleMetadataInfo MMDI = AM.getResult(M); ModuleShaderFlags MSFI; - MSFI.initialize(M, DRTM); + MSFI.initialize(M, DRTM, MMDI); return MSFI; } @@ -212,14 +217,17 @@ PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M, bool ShaderFlagsAnalysisWrapper::runOnModule(Module &M) { DXILResourceTypeMap &DRTM = getAnalysis().getResourceTypeMap(); + const ModuleMetadataInfo MMDI = + getAnalysis().getModuleMetadata(); - MSFI.initialize(M, DRTM); + MSFI.initialize(M, DRTM, MMDI); return false; } void ShaderFlagsAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive(); + AU.addRequired(); } char ShaderFlagsAnalysisWrapper::ID = 0; @@ -227,5 +235,6 @@ char ShaderFlagsAnalysisWrapper::ID = 0; INITIALIZE_PASS_BEGIN(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis", "DXIL Shader Flag Analysis", true, true) INITIALIZE_PASS_DEPENDENCY(DXILResourceTypeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DXILMetadataAnalysisWrapperPass) INITIALIZE_PASS_END(ShaderFlagsAnalysisWrapper, "dx-shader-flag-analysis", "DXIL Shader Flag Analysis", true, true) diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h index e6c6d56402c1a..abf7cc86259ed 100644 --- a/llvm/lib/Target/DirectX/DXILShaderFlags.h +++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h @@ -14,6 +14,7 @@ #ifndef LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H #define LLVM_TARGET_DIRECTX_DXILSHADERFLAGS_H +#include "llvm/Analysis/DXILMetadataAnalysis.h" #include "llvm/IR/Function.h" #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" @@ -83,7 +84,8 @@ struct ComputedShaderFlags { }; struct ModuleShaderFlags { - void initialize(Module &, DXILResourceTypeMap &DRTM); + void initialize(Module &, DXILResourceTypeMap &DRTM, + const ModuleMetadataInfo &MMDI); const ComputedShaderFlags &getFunctionFlags(const Function *) const; const ComputedShaderFlags &getCombinedFlags() const { return CombinedSFMask; } diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll new file mode 100644 index 0000000000000..ee42b5b758ca0 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll @@ -0,0 +1,25 @@ +; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s + +target triple = "dxilv1.6-unknown-shadermodel6.6-library" + +; CHECK: ; Combined Shader Flags for Module +; CHECK-NEXT: ; Shader Flags Value: 0x00000001 + +; CHECK: ; Note: extra DXIL module flags: +; CHECK-NEXT: ; D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION + +; CHECK: ; Shader Flags for Module Functions + +target triple = "dxilv1.6-unknown-shadermodel6.6-library" + +; CHECK: ; Function main : 0x00000000 +define void @main() { +entry: + ret void +} + +!llvm.module.flags = !{!0} + +!0 = !{i32 4, !"dx.disable_optimizations", i32 1} + + diff --git a/llvm/test/CodeGen/DirectX/llc-pipeline.ll b/llvm/test/CodeGen/DirectX/llc-pipeline.ll index b071557249414..03b2150bbc1dc 100644 --- a/llvm/test/CodeGen/DirectX/llc-pipeline.ll +++ b/llvm/test/CodeGen/DirectX/llc-pipeline.ll @@ -23,8 +23,8 @@ ; CHECK-NEXT: Scalarize vector operations ; CHECK-NEXT: DXIL Resource Binding Analysis ; CHECK-NEXT: DXIL resource Information -; CHECK-NEXT: DXIL Shader Flag Analysis ; CHECK-NEXT: DXIL Module Metadata analysis +; CHECK-NEXT: DXIL Shader Flag Analysis ; CHECK-NEXT: DXIL Translate Metadata ; CHECK-NEXT: DXIL Op Lowering ; CHECK-NEXT: DXIL Prepare Module From ca014db48fb1476942fc1d60325ad82feac25313 Mon Sep 17 00:00:00 2001 From: "S. Bharadwaj Yadavalli" Date: Wed, 29 Jan 2025 19:04:14 -0500 Subject: [PATCH 2/2] Delete metadata dx.disable_optimizations, if it exists, from module after its presence has been noted in ModuleMetadata Analysis pass. This ensures that this metadata that is not part of DXIL specification is not emitted in the final output. Update disable-opt.ll to verify dx.disable_optimizations metadata is deleted. --- llvm/lib/Analysis/DXILMetadataAnalysis.cpp | 29 ++++++++++++++----- .../DirectX/ShaderFlags/disable-opt.ll | 2 ++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp index 426559c64f876..a04ae53512133 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -71,17 +71,32 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { // Set shader flags based on Module properties SmallVector FlagEntries; + SmallVector NewFlagEntries; M.getModuleFlagsMetadata(FlagEntries); for (const auto &Flag : FlagEntries) { - if (Flag.Behavior != Module::ModFlagBehavior::Override) - continue; - if (Flag.Key->getString().compare("dx.disable_optimizations") == 0) { + if ((Flag.Behavior == Module::ModFlagBehavior::Override) && + (Flag.Key->getString().compare("dx.disable_optimizations") == 0)) { const auto *V = mdconst::extract(Flag.Val); - if (V->isOne()) { + if (V->isOne()) MMDAI.DisableOptimizations = true; - break; - } - } + } else + // Collect all Module Flags other than dx.disable_optimizations. + NewFlagEntries.push_back(Flag); + } + + // "dx.disable_optimizations" is not included in the metadata specified in + // DXIL specification. Hence it needs to be deleted such that it is not + // emitted in the final DXIL output, now that its intent is captured in MMDAI, + // if present. + + if (NewFlagEntries.size() != FlagEntries.size()) { + NamedMDNode *OrigMDFlags = M.getModuleFlagsMetadata(); + // Delete all Module flags + OrigMDFlags->eraseFromParent(); + // Repopulate Module flags using the list that excludes + // dx.delete_optimizations. + for (const auto &Flag : NewFlagEntries) + M.addModuleFlag(Flag.Behavior, Flag.Key->getString(), Flag.Val); } return MMDAI; diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll index ee42b5b758ca0..a5b08860463d1 100644 --- a/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll @@ -18,8 +18,10 @@ entry: ret void } +; CHECK-NOT: llvm.module.flags !llvm.module.flags = !{!0} +; CHECK-NOT: "dx.disable_optimizations" !0 = !{i32 4, !"dx.disable_optimizations", i32 1}