st/gbm: automake: do not export gbm_gallium_drm_device_create
[mesa.git] / src / glsl / lower_vec_index_to_cond_assign.cpp
index 9c0d92e6143c85b7c01b1dbe042b38db9df0f60e..fe6a3f208a165aca748565e180fa20a737bc18d0 100644 (file)
@@ -41,6 +41,8 @@
 #include "ir_optimization.h"
 #include "glsl_types.h"
 
+namespace {
+
 /**
  * Visitor class for replacing expressions with ir_constant values.
  */
@@ -52,12 +54,13 @@ public:
       progress = false;
    }
 
-   ir_rvalue *convert_vec_index_to_cond_assign(ir_rvalue *val);
    ir_rvalue *convert_vec_index_to_cond_assign(void *mem_ctx,
                                                ir_rvalue *orig_vector,
                                                ir_rvalue *orig_index,
                                                const glsl_type *type);
 
+   ir_rvalue *convert_vector_extract_to_cond_assign(ir_rvalue *ir);
+
    virtual ir_visitor_status visit_enter(ir_expression *);
    virtual ir_visitor_status visit_enter(ir_swizzle *);
    virtual ir_visitor_status visit_leave(ir_assignment *);
@@ -68,6 +71,8 @@ public:
    bool progress;
 };
 
+} /* anonymous namespace */
+
 ir_rvalue *
 ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(void *mem_ctx,
                                                                       ir_rvalue *orig_vector,
@@ -140,22 +145,16 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(void *mem_
 }
 
 ir_rvalue *
-ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(ir_rvalue *ir)
+ir_vec_index_to_cond_assign_visitor::convert_vector_extract_to_cond_assign(ir_rvalue *ir)
 {
-   ir_dereference_array *orig_deref = ir->as_dereference_array();
+   ir_expression *const expr = ir->as_expression();
 
-   if (!orig_deref)
+   if (expr == NULL || expr->operation != ir_binop_vector_extract)
       return ir;
 
-   if (orig_deref->array->type->is_matrix() ||
-       orig_deref->array->type->is_array())
-      return ir;
-
-   assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
-
    return convert_vec_index_to_cond_assign(ralloc_parent(ir),
-                                           orig_deref->array,
-                                           orig_deref->array_index,
+                                           expr->operands[0],
+                                           expr->operands[1],
                                            ir->type);
 }
 
@@ -165,7 +164,7 @@ ir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir)
    unsigned int i;
 
    for (i = 0; i < ir->get_num_operands(); i++) {
-      ir->operands[i] = convert_vec_index_to_cond_assign(ir->operands[i]);
+      ir->operands[i] = convert_vector_extract_to_cond_assign(ir->operands[i]);
    }
 
    return visit_continue;
@@ -178,7 +177,7 @@ ir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir)
     * the result of indexing a vector is.  But maybe at some point we'll end up
     * using swizzling of scalars for vector construction.
     */
-   ir->val = convert_vec_index_to_cond_assign(ir->val);
+   ir->val = convert_vector_extract_to_cond_assign(ir->val);
 
    return visit_continue;
 }
@@ -186,100 +185,21 @@ ir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir)
 ir_visitor_status
 ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
 {
-   ir_variable *index, *var;
-   ir_dereference_variable *deref;
-   ir_assignment *assign;
-   unsigned i;
-
-   ir->rhs = convert_vec_index_to_cond_assign(ir->rhs);
-   if (ir->condition)
-      ir->condition = convert_vec_index_to_cond_assign(ir->condition);
-
-   /* Last, handle the LHS */
-   ir_dereference_array *orig_deref = ir->lhs->as_dereference_array();
-
-   if (!orig_deref ||
-       orig_deref->array->type->is_matrix() ||
-       orig_deref->array->type->is_array())
-      return visit_continue;
-
-   void *mem_ctx = ralloc_parent(ir);
-
-   assert(orig_deref->array_index->type->base_type == GLSL_TYPE_INT);
-
-   exec_list list;
-
-   /* Store the index to a temporary to avoid reusing its tree. */
-   index = new(ir) ir_variable(glsl_type::int_type, "vec_index_tmp_i",
-                              ir_var_temporary);
-   list.push_tail(index);
-   deref = new(ir) ir_dereference_variable(index);
-   assign = new(ir) ir_assignment(deref, orig_deref->array_index, NULL);
-   list.push_tail(assign);
-
-   /* Store the RHS to a temporary to avoid reusing its tree. */
-   var = new(ir) ir_variable(ir->rhs->type, "vec_index_tmp_v",
-                            ir_var_temporary);
-   list.push_tail(var);
-   deref = new(ir) ir_dereference_variable(var);
-   assign = new(ir) ir_assignment(deref, ir->rhs, NULL);
-   list.push_tail(assign);
-
-   /* Generate a single comparison condition "mask" for all of the components
-    * in the vector.
-    */
-   ir_rvalue *const cond_deref =
-      compare_index_block(&list, index, 0,
-                         orig_deref->array->type->vector_elements,
-                         mem_ctx);
-
-   /* Generate a conditional move of each vector element to the temp. */
-   for (i = 0; i < orig_deref->array->type->vector_elements; i++) {
-      ir_rvalue *condition_swizzle =
-        new(ir) ir_swizzle(cond_deref->clone(ir, NULL), i, 0, 0, 0, 1);
-
+   ir->rhs = convert_vector_extract_to_cond_assign(ir->rhs);
 
-      /* Just clone the rest of the deref chain when trying to get at the
-       * underlying variable.
-       */
-      ir_rvalue *swizzle =
-        new(ir) ir_swizzle(orig_deref->array->clone(mem_ctx, NULL),
-                           i, 0, 0, 0, 1);
-
-      deref = new(ir) ir_dereference_variable(var);
-      assign = new(ir) ir_assignment(swizzle, deref, condition_swizzle);
-      list.push_tail(assign);
+   if (ir->condition) {
+      ir->condition = convert_vector_extract_to_cond_assign(ir->condition);
    }
 
-   /* If the original assignment has a condition, respect that original
-    * condition!  This is acomplished by wrapping the new conditional
-    * assignments in an if-statement that uses the original condition.
-    */
-   if (ir->condition != NULL) {
-      /* No need to clone the condition because the IR that it hangs on is
-       * going to be removed from the instruction sequence.
-       */
-      ir_if *if_stmt = new(mem_ctx) ir_if(ir->condition);
-
-      list.move_nodes_to(&if_stmt->then_instructions);
-      ir->insert_before(if_stmt);
-   } else {
-      ir->insert_before(&list);
-   }
-
-   ir->remove();
-
-   this->progress = true;
-
    return visit_continue;
 }
 
 ir_visitor_status
 ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir)
 {
-   foreach_iter(exec_list_iterator, iter, *ir) {
-      ir_rvalue *param = (ir_rvalue *)iter.get();
-      ir_rvalue *new_param = convert_vec_index_to_cond_assign(param);
+   foreach_list_safe(n, &ir->actual_parameters) {
+      ir_rvalue *param = (ir_rvalue *) n;
+      ir_rvalue *new_param = convert_vector_extract_to_cond_assign(param);
 
       if (new_param != param) {
         param->replace_with(new_param);
@@ -293,7 +213,7 @@ ir_visitor_status
 ir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir)
 {
    if (ir->value) {
-      ir->value = convert_vec_index_to_cond_assign(ir->value);
+      ir->value = convert_vector_extract_to_cond_assign(ir->value);
    }
 
    return visit_continue;
@@ -302,7 +222,7 @@ ir_vec_index_to_cond_assign_visitor::visit_enter(ir_return *ir)
 ir_visitor_status
 ir_vec_index_to_cond_assign_visitor::visit_enter(ir_if *ir)
 {
-   ir->condition = convert_vec_index_to_cond_assign(ir->condition);
+   ir->condition = convert_vector_extract_to_cond_assign(ir->condition);
 
    return visit_continue;
 }