glsl: Delete dead discard conditions in constant folding.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 24 Feb 2015 09:00:22 +0000 (01:00 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 24 Feb 2015 23:24:52 +0000 (15:24 -0800)
opt_constant_folding() already detects conditional assignments where the
condition is constant, and either deletes the assignment or the
condition.

Make it handle discards in the same fashion.

Spotted happening in the wild in Tropico 5 shaders.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
src/glsl/opt_constant_folding.cpp

index 74b855e5e948ebbc822d4d8b7413dde21517aa32..4aae3f0ddf2809d2816be05af6c7d04901021921 100644 (file)
@@ -50,6 +50,7 @@ public:
       /* empty */
    }
 
+   virtual ir_visitor_status visit_enter(ir_discard *ir);
    virtual ir_visitor_status visit_enter(ir_assignment *ir);
    virtual ir_visitor_status visit_enter(ir_call *ir);
 
@@ -93,6 +94,29 @@ ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue)
    }
 }
 
+ir_visitor_status
+ir_constant_folding_visitor::visit_enter(ir_discard *ir)
+{
+   if (ir->condition) {
+      ir->condition->accept(this);
+      handle_rvalue(&ir->condition);
+
+      ir_constant *const_val = ir->condition->as_constant();
+      /* If the condition is constant, either remove the condition or
+       * remove the never-executed assignment.
+       */
+      if (const_val) {
+         if (const_val->value.b[0])
+            ir->condition = NULL;
+         else
+            ir->remove();
+         this->progress = true;
+      }
+   }
+
+   return visit_continue_with_parent;
+}
+
 ir_visitor_status
 ir_constant_folding_visitor::visit_enter(ir_assignment *ir)
 {