[spv-out] omit extra switch case blocks where possible

This commit is contained in:
teoxoy
2022-11-15 14:39:39 +01:00
committed by Jim Blandy
parent be70a2ec03
commit eccdc0aeb1
2 changed files with 49 additions and 38 deletions

View File

@@ -1680,26 +1680,36 @@ impl<'w> BlockContext<'w> {
spirv::SelectionControl::NONE,
));
let default_id = self.gen_id();
let mut default_id = None;
// id of previous empty fall-through case
let mut last_id = None;
let mut raw_cases = Vec::with_capacity(cases.len());
let mut case_ids = Vec::with_capacity(cases.len());
for case in cases.iter() {
let label_id = last_id.take().unwrap_or_else(|| self.gen_id());
if case.fall_through && case.body.is_empty() {
last_id = Some(label_id);
}
case_ids.push(label_id);
match case.value {
crate::SwitchValue::Integer(value) => {
let label_id = self.gen_id();
raw_cases.push(super::instructions::Case {
value: value as Word,
label_id,
});
case_ids.push(label_id);
}
crate::SwitchValue::Default => {
case_ids.push(default_id);
default_id = Some(label_id);
}
}
}
let default_id = default_id.unwrap();
self.function.consume(
block,
Instruction::switch(selector_id, default_id, &raw_cases),
@@ -1710,7 +1720,12 @@ impl<'w> BlockContext<'w> {
..loop_context
};
for (i, (case, label_id)) in cases.iter().zip(case_ids.iter()).enumerate() {
for (i, (case, label_id)) in cases
.iter()
.zip(case_ids.iter())
.filter(|&(case, _)| !(case.fall_through && case.body.is_empty()))
.enumerate()
{
let case_finish_id = if case.fall_through {
case_ids[i + 1]
} else {

View File

@@ -1,7 +1,7 @@
; SPIR-V
; Version: 1.1
; Generator: rspirv
; Bound: 71
; Bound: 69
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
@@ -45,11 +45,11 @@ OpFunctionEnd
OpBranch %22
%22 = OpLabel
OpSelectionMerge %23 None
OpSwitch %5 %24 0 %25
%25 = OpLabel
OpBranch %23
OpSwitch %5 %25 0 %24
%24 = OpLabel
OpBranch %23
%25 = OpLabel
OpBranch %23
%23 = OpLabel
OpReturn
OpFunctionEnd
@@ -64,10 +64,10 @@ OpLoopMerge %31 %33 None
OpBranch %32
%32 = OpLabel
OpSelectionMerge %34 None
OpSwitch %27 %35 1 %36
%36 = OpLabel
OpBranch %33
OpSwitch %27 %36 1 %35
%35 = OpLabel
OpBranch %33
%36 = OpLabel
OpBranch %34
%34 = OpLabel
OpBranch %33
@@ -92,51 +92,47 @@ OpBranch %50
%50 = OpLabel
%52 = OpLoad %4 %37
OpSelectionMerge %53 None
OpSwitch %52 %54 1 %55 2 %56 3 %57 4 %58 5 %59 6 %60
%55 = OpLabel
OpSwitch %52 %58 1 %54 2 %55 3 %56 4 %56 5 %57 6 %58
%54 = OpLabel
OpStore %37 %5
OpBranch %53
%56 = OpLabel
%55 = OpLabel
OpStore %37 %3
OpBranch %53
%57 = OpLabel
OpBranch %58
%58 = OpLabel
%56 = OpLabel
OpStore %37 %6
OpBranch %53
%59 = OpLabel
%57 = OpLabel
OpStore %37 %7
OpBranch %53
%54 = OpLabel
OpBranch %60
%60 = OpLabel
%58 = OpLabel
OpStore %37 %8
OpBranch %53
%53 = OpLabel
OpSelectionMerge %61 None
OpSwitch %9 %62 0 %63
%63 = OpLabel
OpBranch %61
%62 = OpLabel
OpBranch %61
OpSelectionMerge %59 None
OpSwitch %9 %61 0 %60
%60 = OpLabel
OpBranch %59
%61 = OpLabel
%64 = OpLoad %4 %37
OpSelectionMerge %65 None
OpSwitch %64 %66 1 %67 2 %68 3 %69 4 %70
%67 = OpLabel
OpBranch %59
%59 = OpLabel
%62 = OpLoad %4 %37
OpSelectionMerge %63 None
OpSwitch %62 %68 1 %64 2 %65 3 %66 4 %67
%64 = OpLabel
OpStore %37 %5
OpBranch %65
%68 = OpLabel
OpBranch %63
%65 = OpLabel
OpStore %37 %3
OpReturn
%69 = OpLabel
%66 = OpLabel
OpStore %37 %6
OpReturn
%70 = OpLabel
%67 = OpLabel
OpReturn
%66 = OpLabel
%68 = OpLabel
OpStore %37 %7
OpReturn
%65 = OpLabel
%63 = OpLabel
OpReturn
OpFunctionEnd