diff options
author | Ian Romanick <[email protected]> | 2017-09-19 15:59:00 -0500 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2017-10-02 14:46:10 -0700 |
commit | d5361d9f01a3e3f1480e7804252fd23a3cc1dd7f (patch) | |
tree | 6c55d8ff0757872c10ac2f8d27dd5c7cad1e50ba /src/compiler | |
parent | 3e5cd2aba9317ba4e3eb812b8b88523a9371f86a (diff) |
glsl/ast: Generate a more compact expression to disable execution of default case
Instead of generating a sequence like:
run_default = true;
if (i == 3) // some label that appears after default
run_default = false;
if (i == 4) // some label that appears after default
run_default = false;
...
if (run_default) {
...
}
generate something like:
run_default = !((i == 3) || (i == 4) || ...);
if (run_default) {
...
}
This eliminates one use of conditional assignment, and it enables the
elimination of another.
Signed-off-by: Ian Romanick <[email protected]>
Reviewed-by: Alejandro PiƱeiro <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/glsl/ast_to_hir.cpp | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index de2e460fa10..cbd5746648d 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -6579,27 +6579,11 @@ ast_case_statement_list::hir(exec_list *instructions, * if default should be chosen or not. */ if (!default_case.is_empty()) { - - ir_rvalue *const true_val = new (state) ir_constant(true); - ir_dereference_variable *deref_run_default_var = - new(state) ir_dereference_variable(state->switch_state.run_default); - - /* Choose to run default case initially, following conditional - * assignments might change this. - */ - ir_assignment *const init_var = - new(state) ir_assignment(deref_run_default_var, true_val); - instructions->push_tail(init_var); - - /* Default case was the last one, no checks required. */ - if (after_default.is_empty()) { - instructions->append_list(&default_case); - return NULL; - } - struct hash_entry *entry; ir_factory body(instructions, state); + ir_expression *cmp = NULL; + hash_table_foreach(state->switch_state.labels_ht, entry) { const struct case_label *const l = (struct case_label *) entry->data; @@ -6613,12 +6597,17 @@ ast_case_statement_list::hir(exec_list *instructions, ? body.constant(unsigned(l->value)) : body.constant(int(l->value)); - body.emit(assign(state->switch_state.run_default, - body.constant(false), - equal(cnst, state->switch_state.test_var))); + cmp = cmp == NULL + ? equal(cnst, state->switch_state.test_var) + : logic_or(cmp, equal(cnst, state->switch_state.test_var)); } } + if (cmp != NULL) + body.emit(assign(state->switch_state.run_default, logic_not(cmp))); + else + body.emit(assign(state->switch_state.run_default, body.constant(true))); + /* Append default case and all cases after it. */ instructions->append_list(&default_case); instructions->append_list(&after_default); |