-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[DirectX] Set Shader Flag DisableOptimizations #126813
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 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,8 @@ | |
#include "llvm/ADT/SmallVector.h" | ||
#include "llvm/Analysis/CallGraph.h" | ||
#include "llvm/Analysis/DXILResource.h" | ||
#include "llvm/IR/Attributes.h" | ||
#include "llvm/IR/DiagnosticInfo.h" | ||
#include "llvm/IR/Instruction.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/IR/IntrinsicInst.h" | ||
|
@@ -96,7 +98,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 +145,20 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM) { | |
// Merge SCCSF with that of F | ||
FunctionFlags[F].merge(SCCSF); | ||
} | ||
|
||
// Set DisableOptimizations flag based on the presence of OptimizeNone | ||
// attribute of entry functions. | ||
if (MMDI.EntryPropertyVec.size() > 0) { | ||
CombinedSFMask.DisableOptimizations = | ||
MMDI.EntryPropertyVec[0].Entry->hasFnAttribute( | ||
llvm::Attribute::OptimizeNone); | ||
// Ensure all entry functions have the same optimization attribute | ||
for (auto EF : MMDI.EntryPropertyVec) | ||
if (CombinedSFMask.DisableOptimizations != | ||
EF.Entry->hasFnAttribute(llvm::Attribute::OptimizeNone)) | ||
EF.Entry->getContext().diagnose(DiagnosticInfoUnsupported( | ||
*(EF.Entry), "Inconsistent optnone attribute ")); | ||
} | ||
} | ||
|
||
void ComputedShaderFlags::print(raw_ostream &OS) const { | ||
|
@@ -180,9 +197,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; | ||
} | ||
|
@@ -212,20 +230,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>(); | ||
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. This change causes DXIL Module Metadata analysis pass to run before DXIL Shader Flag Analysis because it is now needed I think before we never intended to fetch fn attributes since you were using 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.
Yes, that was the proposed mechanism in PR #123136. This PR supersedes that following the feedback there.
The list of entry function information collected by Metadata Analysis pass is leveraged in this pass to look at Entry functions can be collected during the call graph traversal in this pass to query for |
||
} | ||
|
||
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) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
|
||
|
||
; 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 | ||
; CHECK: ; Function main : 0x00000000 | ||
; The test source in this file generated from the following command: | ||
; clang -cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -O0 -o - <<EOF | ||
; [numthreads(1,1,1)] | ||
; [shader("compute")] | ||
; void main() {} | ||
; EOF | ||
|
||
; ModuleID = '-' | ||
source_filename = "-" | ||
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" | ||
target triple = "dxilv1.0-pc-shadermodel6.0-compute" | ||
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. Best to remove these when they aren't relevant to the test at hand. |
||
|
||
; Function Attrs: convergent noinline norecurse optnone | ||
define void @main() #0 { | ||
entry: | ||
ret void | ||
} | ||
|
||
; Function Attrs: alwaysinline convergent mustprogress norecurse nounwind | ||
define noundef i32 @_Z3foov() #1 { | ||
entry: | ||
ret i32 0 | ||
} | ||
|
||
attributes #0 = { convergent noinline norecurse optnone "approx-func-fp-math"="true" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
attributes #1 = { alwaysinline convergent mustprogress norecurse nounwind "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
|
||
!llvm.module.flags = !{!0} | ||
!dx.valver = !{!1} | ||
|
||
!0 = !{i32 1, !"wchar_size", i32 4} | ||
!1 = !{i32 1, i32 8} | ||
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. We shouldn't need the module.flags and valver metadata for these tests |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
|
||
|
||
; 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 | ||
; CHECK: ; Function main : 0x00000000 | ||
; The test source in this file generated from the following command: | ||
; clang -cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O0 -o - <<EOF | ||
|
||
; [numthreads(1,1,1)] | ||
; [shader("compute")] | ||
; void main() {} | ||
|
||
; int foo() {return 0;} | ||
; EOF | ||
|
||
; ModuleID = '-' | ||
source_filename = "-" | ||
target datalayout = "e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:32-f64:64-n8:16:32:64" | ||
target triple = "dxilv1.3-pc-shadermodel6.3-library" | ||
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. Same here |
||
|
||
; Function Attrs: convergent mustprogress noinline norecurse nounwind optnone | ||
define internal void @_Z4mainv() #0 { | ||
entry: | ||
ret void | ||
} | ||
|
||
; Function Attrs: convergent noinline norecurse optnone | ||
define void @main() #1 { | ||
entry: | ||
call void @_Z4mainv() | ||
ret void | ||
} | ||
|
||
; Function Attrs: convergent mustprogress noinline norecurse nounwind optnone | ||
define noundef i32 @_Z3foov() #0 { | ||
entry: | ||
ret i32 0 | ||
} | ||
|
||
attributes #0 = { convergent mustprogress noinline norecurse nounwind optnone "approx-func-fp-math"="true" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
attributes #1 = { convergent noinline norecurse optnone "approx-func-fp-math"="true" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
|
||
!llvm.module.flags = !{!0} | ||
!dx.valver = !{!1} | ||
|
||
!0 = !{i32 1, !"wchar_size", i32 4} | ||
!1 = !{i32 1, i32 8} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
; RUN: not opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
|
||
target triple = "dxilv1.3-pc-shadermodel6.3-library" | ||
|
||
; All entry functions of a library shader need to either have optnone | ||
; or not have the attribute | ||
; CHECK: error: | ||
; CHECK-SAME: in function entry_two | ||
; CHECK-SAME: Inconsistent optnone attribute | ||
; Function Attrs: convergent noinline norecurse optnone | ||
define void @entry_one() #0 { | ||
entry: | ||
ret void | ||
} | ||
|
||
; Function Attrs: convergent noinline norecurse | ||
define void @entry_two() #1 { | ||
entry: | ||
ret void | ||
} | ||
|
||
attributes #0 = { convergent noinline norecurse optnone "approx-func-fp-math"="true" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
attributes #1 = { convergent noinline norecurse "approx-func-fp-math"="true" "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" } | ||
|
||
!llvm.module.flags = !{!0, !1} | ||
!dx.valver = !{!2} | ||
|
||
!0 = !{i32 1, !"wchar_size", i32 4} | ||
!1 = !{i32 4, !"dx.disable_optimizations", i32 1} | ||
!2 = !{i32 1, i32 8} |
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.
Should be
const auto &
orconst EntryProperties &
rather than forcing copies here. Also what is "EF" an abbreviation of? It doesn't seem to have anything to do with what this variable represents. I'd probably call this "Props" or something like that.