glsl2: Catch pointless copies in copy propagation.
authorEric Anholt <eric@anholt.net>
Thu, 5 Aug 2010 06:23:15 +0000 (23:23 -0700)
committerEric Anholt <eric@anholt.net>
Thu, 5 Aug 2010 16:17:45 +0000 (09:17 -0700)
We wouldn't want to go rewriting dereferences to variables to point at
the same variable it did before.  While I didn't find a way to trigger
that, a shader in Yo Frankie managed to produce a self-assignment by
passing a constant to a function doing self assignment like this.

Cleans up the IR for glsl-deadcode-self-assign.shader_test

src/glsl/ir_copy_propagation.cpp

index 26588a352c821b5227e53bdb18d4ebd61a6b0031..1d28392d7c38e2e9cb532c15909878fcb6325f51 100644 (file)
@@ -213,7 +213,7 @@ kill_invalidated_copies(ir_assignment *ir, exec_list *acp)
  * Adds an entry to the available copy list if it's a plain assignment
  * of a variable to a variable.
  */
-static void
+static bool
 add_copy(void *ctx, ir_assignment *ir, exec_list *acp)
 {
    acp_entry *entry;
@@ -221,16 +221,28 @@ add_copy(void *ctx, ir_assignment *ir, exec_list *acp)
    if (ir->condition) {
       ir_constant *condition = ir->condition->as_constant();
       if (!condition || !condition->value.b[0])
-        return;
+        return false;
    }
 
    ir_variable *lhs_var = ir->whole_variable_written();
    ir_variable *rhs_var = ir->rhs->whole_variable_referenced();
 
    if ((lhs_var != NULL) && (rhs_var != NULL)) {
-      entry = new(ctx) acp_entry(lhs_var, rhs_var);
-      acp->push_tail(entry);
+      if (lhs_var == rhs_var) {
+        /* This is a dumb assignment, but we've conveniently noticed
+         * it here.  Removing it now would mess up the loop iteration
+         * calling us.  Just flag it to not execute, and someone else
+         * will clean up the mess.
+         */
+        ir->condition = new(talloc_parent(ir)) ir_constant(false);
+        return true;
+      } else {
+        entry = new(ctx) acp_entry(lhs_var, rhs_var);
+        acp->push_tail(entry);
+      }
    }
+
+   return false;
 }
 
 static void
@@ -253,7 +265,7 @@ copy_propagation_basic_block(ir_instruction *first,
       if (ir_assign) {
         kill_invalidated_copies(ir_assign, &acp);
 
-        add_copy(ctx, ir_assign, &acp);
+        progress = add_copy(ctx, ir_assign, &acp) || progress;
       }
       if (ir == last)
         break;