glsl/ast: Generate a more compact expression to disable execution of default case
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 19 Sep 2017 20:59:00 +0000 (15:59 -0500)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 2 Oct 2017 21:46:10 +0000 (14:46 -0700)
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 <ian.d.romanick@intel.com>
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
src/compiler/glsl/ast_to_hir.cpp

index de2e460fa10303da6512072ef14c1a58ca1b1c30..cbd5746648d0ff670dff774252cb5be1831cd50e 100644 (file)
@@ -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);