Skip to content

[DirectX] Set Shader Flag DisableOptimizations. #123136

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

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions llvm/include/llvm/Analysis/DXILMetadataAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct ModuleMetadataInfo {
Triple::EnvironmentType ShaderProfile{Triple::UnknownEnvironment};
VersionTuple ValidatorVersion{};
SmallVector<EntryProperties> EntryPropertyVec{};
bool DisableOptimizations{false};
void print(raw_ostream &OS) const;
};

Expand Down
31 changes: 31 additions & 0 deletions llvm/lib/Analysis/DXILMetadataAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,37 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) {
}
MMDAI.EntryPropertyVec.push_back(EFP);
}

// Set shader flags based on Module properties
SmallVector<llvm::Module::ModuleFlagEntry> FlagEntries;
SmallVector<llvm::Module::ModuleFlagEntry> NewFlagEntries;
M.getModuleFlagsMetadata(FlagEntries);
for (const auto &Flag : FlagEntries) {
if ((Flag.Behavior == Module::ModFlagBehavior::Override) &&
(Flag.Key->getString().compare("dx.disable_optimizations") == 0)) {
const auto *V = mdconst::extract<llvm::ConstantInt>(Flag.Val);
if (V->isOne())
MMDAI.DisableOptimizations = true;
} 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()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do this here? We have code in DXILPrepare that cleans the module flags.

@bogner, I think the reason the dx.disable_optimizations named metadata wasn't causing issues is because DXIL doesn't use custom module flags at all, so in DXILPrepare we just strip out any non-standard LLVM 3.7 module flags, which will clean this up.

Copy link
Contributor Author

@bharadwajy bharadwajy Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do this here? We have code in DXILPrepare that cleans the module flags.

@bogner, I think the reason the dx.disable_optimizations named metadata wasn't causing issues is because DXIL doesn't use custom module flags at all, so in DXILPrepare we just strip out any non-standard LLVM 3.7 module flags, which will clean this up.

@llvm-beanz I proposed a PR to decorate shader entry functions with the attribute optnone as an alternative to using dx.disable_optimizations named metadata - per feedback above.

The idea is to eliminate creation of dx.disable_optimizations metadata and key off the optnone attribute on shader entry functions to set the shader flag DisableOptimizations as implemented here with an expectation of converting it to a follow-on PR to #125937.

I'd appreciate feedback on #125937 in this context as well as the preferred choice compared to this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it now needs an update to adjust to #125937 landing.

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;
}

Expand Down
15 changes: 12 additions & 3 deletions llvm/lib/Target/DirectX/DXILShaderFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -180,9 +184,10 @@ AnalysisKey ShaderFlagsAnalysis::Key;
ModuleShaderFlags ShaderFlagsAnalysis::run(Module &M,
ModuleAnalysisManager &AM) {
DXILResourceTypeMap &DRTM = AM.getResult<DXILResourceTypeAnalysis>(M);
const ModuleMetadataInfo MMDI = AM.getResult<DXILMetadataAnalysis>(M);

ModuleShaderFlags MSFI;
MSFI.initialize(M, DRTM);
MSFI.initialize(M, DRTM, MMDI);

return MSFI;
}
Expand Down Expand Up @@ -212,20 +217,24 @@ PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M,
bool ShaderFlagsAnalysisWrapper::runOnModule(Module &M) {
DXILResourceTypeMap &DRTM =
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
const ModuleMetadataInfo MMDI =
getAnalysis<DXILMetadataAnalysisWrapperPass>().getModuleMetadata();

MSFI.initialize(M, DRTM);
MSFI.initialize(M, DRTM, MMDI);
return false;
}

void ShaderFlagsAnalysisWrapper::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequiredTransitive<DXILResourceTypeWrapperPass>();
AU.addRequired<DXILMetadataAnalysisWrapperPass>();
}

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)
4 changes: 3 additions & 1 deletion llvm/lib/Target/DirectX/DXILShaderFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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; }

Expand Down
27 changes: 27 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
; 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
}

; CHECK-NOT: llvm.module.flags
!llvm.module.flags = !{!0}

; CHECK-NOT: "dx.disable_optimizations"
!0 = !{i32 4, !"dx.disable_optimizations", i32 1}


2 changes: 1 addition & 1 deletion llvm/test/CodeGen/DirectX/llc-pipeline.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down