summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2017-09-19 15:59:00 -0500
committerIan Romanick <[email protected]>2017-10-02 14:46:10 -0700
commitd5361d9f01a3e3f1480e7804252fd23a3cc1dd7f (patch)
tree6c55d8ff0757872c10ac2f8d27dd5c7cad1e50ba /src
parent3e5cd2aba9317ba4e3eb812b8b88523a9371f86a (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')
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp31
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);