glsl: Fix type-deduction for and/or/xor expressions
[mesa.git] / src / glsl / opt_constant_folding.cpp
index d69ca75fe03090f9a27f960040eddad40baa1397..072fefe9ab818c9b52de08dc9817dbed02f63000 100644 (file)
@@ -32,6 +32,8 @@
 #include "ir_optimization.h"
 #include "glsl_types.h"
 
+namespace {
+
 /**
  * Visitor class for replacing expressions with ir_constant values.
  */
@@ -56,6 +58,8 @@ public:
    bool progress;
 };
 
+} /* unnamed namespace */
+
 void
 ir_constant_folding_visitor::handle_rvalue(ir_rvalue **rvalue)
 {
@@ -117,12 +121,14 @@ ir_constant_folding_visitor::visit_enter(ir_assignment *ir)
 ir_visitor_status
 ir_constant_folding_visitor::visit_enter(ir_call *ir)
 {
-   exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
+   /* Attempt to constant fold parameters */
+   exec_list_iterator sig_iter = ir->callee->parameters.iterator();
    foreach_iter(exec_list_iterator, iter, *ir) {
       ir_rvalue *param_rval = (ir_rvalue *)iter.get();
       ir_variable *sig_param = (ir_variable *)sig_iter.get();
 
-      if (sig_param->mode == ir_var_in) {
+      if (sig_param->mode == ir_var_function_in
+          || sig_param->mode == ir_var_const_in) {
         ir_rvalue *new_param = param_rval;
 
         handle_rvalue(&new_param);
@@ -133,6 +139,15 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir)
       sig_iter.next();
    }
 
+   /* Next, see if the call can be replaced with an assignment of a constant */
+   ir_constant *const_val = ir->constant_expression_value();
+
+   if (const_val != NULL) {
+      ir_assignment *assignment =
+        new(ralloc_parent(ir)) ir_assignment(ir->return_deref, const_val);
+      ir->replace_with(assignment);
+   }
+
    return visit_continue_with_parent;
 }