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..a04ae53512133 100644 --- a/llvm/lib/Analysis/DXILMetadataAnalysis.cpp +++ b/llvm/lib/Analysis/DXILMetadataAnalysis.cpp @@ -68,6 +68,37 @@ static ModuleMetadataInfo collectMetadataInfo(Module &M) { } MMDAI.EntryPropertyVec.push_back(EFP); } + + // 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) && + (Flag.Key->getString().compare("dx.disable_optimizations") == 0)) { + const auto *V = mdconst::extract(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()) { + 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/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..a5b08860463d1 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ShaderFlags/disable-opt.ll @@ -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} + + 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