glsl: Update expression types after rebalancing the tree.
authorMatt Turner <mattst88@gmail.com>
Thu, 10 Jul 2014 18:00:25 +0000 (11:00 -0700)
committerMatt Turner <mattst88@gmail.com>
Tue, 15 Jul 2014 17:12:29 +0000 (10:12 -0700)
If we saw a tree that looked like

            vec3
           /   \
         vec3 float
        /   \
      vec3 float
     /   \
   vec3 float

We would see that all of the expression types were vec3, and then
rebalance to

           vec3
        /        \
      vec3       vec3 <-- should be float
     /   \      /    \
   vec3 float float float

This patch adds code to visit the rebalanced tree and update the
expression types from the bottom up.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=80880
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glsl/opt_rebalance_tree.cpp

index 773aab3..daabdc9 100644 (file)
@@ -60,6 +60,7 @@
 #include "ir_visitor.h"
 #include "ir_rvalue_visitor.h"
 #include "ir_optimization.h"
+#include "main/macros.h" /* for MAX2 */
 
 /* The DSW algorithm generates a degenerate tree (really, a linked list) in
  * tree_to_vine(). We'd rather not leave a binary expression with only one
@@ -261,6 +262,20 @@ handle_expression(ir_expression *expr)
    return expr;
 }
 
+static void
+update_types(ir_instruction *ir, void *)
+{
+   ir_expression *expr = ir->as_expression();
+   if (!expr)
+      return;
+
+   expr->type =
+      glsl_type::get_instance(expr->type->base_type,
+                              MAX2(expr->operands[0]->type->components(),
+                                   expr->operands[1]->type->components()),
+                              1);
+}
+
 void
 ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
 {
@@ -285,6 +300,8 @@ ir_rebalance_visitor::handle_rvalue(ir_rvalue **rvalue)
    if (new_rvalue == *rvalue)
       return;
 
+   visit_tree(new_rvalue, NULL, NULL, update_types);
+
    *rvalue = new_rvalue;
    this->progress = true;
 }