[Mesa-dev] [PATCH 1/8] glsl: calculate number of operands in an expression once

Thomas Helland thomashelland90 at gmail.com
Tue Aug 8 19:59:34 UTC 2017


I'm not quite sure if the increase in size of the base ir class
versus the reduced overhead and added code is worth it?
Some numbers would be nice. A comment below

2017-08-07 2:18 GMT+00:00 Timothy Arceri <tarceri at itsqueeze.com>:
> Extra validation is added to ir_validate to make sure this is
> always updated to the correct numer of operands, as passes like
> lower_instructions modify the instructions directly rather then
> generating a new one.
> ---
>  src/compiler/glsl/glsl_to_nir.cpp                  |  4 +--
>  src/compiler/glsl/ir.cpp                           | 20 +++++++++++++-
>  src/compiler/glsl/ir.h                             | 13 +++++++++
>  src/compiler/glsl/ir_builder_print_visitor.cpp     |  8 +++---
>  src/compiler/glsl/ir_clone.cpp                     |  2 +-
>  src/compiler/glsl/ir_constant_expression.cpp       |  2 +-
>  src/compiler/glsl/ir_equals.cpp                    |  2 +-
>  src/compiler/glsl/ir_hv_accept.cpp                 |  2 +-
>  src/compiler/glsl/ir_print_visitor.cpp             |  2 +-
>  src/compiler/glsl/ir_rvalue_visitor.cpp            |  2 +-
>  src/compiler/glsl/ir_validate.cpp                  |  8 ++++++
>  src/compiler/glsl/lower_instructions.cpp           | 32 ++++++++++++++++++++++
>  src/compiler/glsl/lower_int64.cpp                  |  4 +--
>  src/compiler/glsl/lower_mat_op_to_vec.cpp          |  8 +++---
>  src/compiler/glsl/lower_ubo_reference.cpp          |  2 +-
>  .../glsl/lower_vec_index_to_cond_assign.cpp        |  2 +-
>  src/compiler/glsl/lower_vector.cpp                 |  2 +-
>  src/compiler/glsl/opt_algebraic.cpp                |  4 +--
>  src/compiler/glsl/opt_constant_folding.cpp         |  2 +-
>  src/compiler/glsl/opt_tree_grafting.cpp            |  2 +-
>  src/mesa/program/ir_to_mesa.cpp                    |  4 +--
>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp         |  6 ++--
>  22 files changed, 102 insertions(+), 31 deletions(-)
>
> diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
> index 331438a183..e5166855e8 100644
> --- a/src/compiler/glsl/glsl_to_nir.cpp
> +++ b/src/compiler/glsl/glsl_to_nir.cpp
> @@ -1487,25 +1487,25 @@ nir_visitor::visit(ir_expression *ir)
>        }
>
>        return;
>     }
>
>     default:
>        break;
>     }
>
>     nir_ssa_def *srcs[4];
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++)
> +   for (unsigned i = 0; i < ir->num_operands; i++)
>        srcs[i] = evaluate_rvalue(ir->operands[i]);
>
>     glsl_base_type types[4];
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++)
> +   for (unsigned i = 0; i < ir->num_operands; i++)
>        if (supports_ints)
>           types[i] = ir->operands[i]->type->base_type;
>        else
>           types[i] = GLSL_TYPE_FLOAT;
>
>     glsl_base_type out_type;
>     if (supports_ints)
>        out_type = ir->type->base_type;
>     else
>        out_type = GLSL_TYPE_FLOAT;
> diff --git a/src/compiler/glsl/ir.cpp b/src/compiler/glsl/ir.cpp
> index 78889bd6d3..d501e19c01 100644
> --- a/src/compiler/glsl/ir.cpp
> +++ b/src/compiler/glsl/ir.cpp
> @@ -196,38 +196,46 @@ ir_expression::ir_expression(int op, const struct glsl_type *type,
>                              ir_rvalue *op0, ir_rvalue *op1,
>                              ir_rvalue *op2, ir_rvalue *op3)
>     : ir_rvalue(ir_type_expression)
>  {
>     this->type = type;
>     this->operation = ir_expression_operation(op);
>     this->operands[0] = op0;
>     this->operands[1] = op1;
>     this->operands[2] = op2;
>     this->operands[3] = op3;
> +   init_num_operands();
> +
>  #ifndef NDEBUG
> -   int num_operands = get_num_operands(this->operation);
>     for (int i = num_operands; i < 4; i++) {
>        assert(this->operands[i] == NULL);
>     }
> +
> +   for (unsigned i = 0; i < num_operands; i++) {
> +      assert(this->operands[i] != NULL);
> +   }
>  #endif
>  }
>

It would be nice if the upper for loop iterator used unsigned
for consistency with the variable and the other loop.
The same accounts for the other occurence further down.

But otherwise things looks ok and the patch is:

Reviewed-by: Thomas Helland<thomashelland90 at gmail.com>

>  ir_expression::ir_expression(int op, ir_rvalue *op0)
>     : ir_rvalue(ir_type_expression)
>  {
>     this->operation = ir_expression_operation(op);
>     this->operands[0] = op0;
>     this->operands[1] = NULL;
>     this->operands[2] = NULL;
>     this->operands[3] = NULL;
>
>     assert(op <= ir_last_unop);
> +   init_num_operands();
> +   assert(num_operands == 1);
> +   assert(this->operands[0]);
>
>     switch (this->operation) {
>     case ir_unop_bit_not:
>     case ir_unop_logic_not:
>     case ir_unop_neg:
>     case ir_unop_abs:
>     case ir_unop_sign:
>     case ir_unop_rcp:
>     case ir_unop_rsq:
>     case ir_unop_sqrt:
> @@ -418,20 +426,25 @@ ir_expression::ir_expression(int op, ir_rvalue *op0)
>  ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
>     : ir_rvalue(ir_type_expression)
>  {
>     this->operation = ir_expression_operation(op);
>     this->operands[0] = op0;
>     this->operands[1] = op1;
>     this->operands[2] = NULL;
>     this->operands[3] = NULL;
>
>     assert(op > ir_last_unop);
> +   init_num_operands();
> +   assert(num_operands == 2);
> +   for (unsigned i = 0; i < num_operands; i++) {
> +      assert(this->operands[i] != NULL);
> +   }
>
>     switch (this->operation) {
>     case ir_binop_all_equal:
>     case ir_binop_any_nequal:
>        this->type = glsl_type::bool_type;
>        break;
>
>     case ir_binop_add:
>     case ir_binop_sub:
>     case ir_binop_min:
> @@ -512,20 +525,25 @@ ir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
>                               ir_rvalue *op2)
>     : ir_rvalue(ir_type_expression)
>  {
>     this->operation = ir_expression_operation(op);
>     this->operands[0] = op0;
>     this->operands[1] = op1;
>     this->operands[2] = op2;
>     this->operands[3] = NULL;
>
>     assert(op > ir_last_binop && op <= ir_last_triop);
> +   init_num_operands();
> +   assert(num_operands == 3);
> +   for (unsigned i = 0; i < num_operands; i++) {
> +      assert(this->operands[i] != NULL);
> +   }
>
>     switch (this->operation) {
>     case ir_triop_fma:
>     case ir_triop_lrp:
>     case ir_triop_bitfield_extract:
>     case ir_triop_vector_insert:
>        this->type = op0->type;
>        break;
>
>     case ir_triop_csel:
> diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
> index 840c06e10a..377e03657d 100644
> --- a/src/compiler/glsl/ir.h
> +++ b/src/compiler/glsl/ir.h
> @@ -1572,22 +1572,35 @@ public:
>
>     virtual void accept(ir_visitor *v)
>     {
>        v->visit(this);
>     }
>
>     virtual ir_visitor_status accept(ir_hierarchical_visitor *);
>
>     virtual ir_variable *variable_referenced() const;
>
> +   /**
> +    * Determine the number of operands used by an expression
> +    */
> +   void init_num_operands()
> +   {
> +      if (operation == ir_quadop_vector) {
> +         num_operands = this->type->vector_elements;
> +      } else {
> +         num_operands = get_num_operands(operation);
> +      }
> +   }
> +
>     ir_expression_operation operation;
>     ir_rvalue *operands[4];
> +   unsigned num_operands;
>  };
>
>
>  /**
>   * HIR instruction representing a high-level function call, containing a list
>   * of parameters and returning a value in the supplied temporary.
>   */
>  class ir_call : public ir_instruction {
>  public:
>     ir_call(ir_function_signature *callee,
> diff --git a/src/compiler/glsl/ir_builder_print_visitor.cpp b/src/compiler/glsl/ir_builder_print_visitor.cpp
> index 02f15e74ee..3e30c5d7af 100644
> --- a/src/compiler/glsl/ir_builder_print_visitor.cpp
> +++ b/src/compiler/glsl/ir_builder_print_visitor.cpp
> @@ -110,21 +110,21 @@ is_simple_operand(const ir_rvalue *ir, unsigned depth = 1)
>
>     case ir_type_swizzle: {
>        const ir_swizzle *swiz = (ir_swizzle *) ir;
>        return swiz->mask.num_components == 1 &&
>               is_simple_operand(swiz->val, depth);
>     }
>
>     case ir_type_expression: {
>        const ir_expression *expr = (ir_expression *) ir;
>
> -      for (unsigned i = 0; i < expr->get_num_operands(); i++) {
> +      for (unsigned i = 0; i < expr->num_operands; i++) {
>           if (!is_simple_operand(expr->operands[i], depth - 1))
>              return false;
>        }
>
>        return true;
>     }
>
>     default:
>        return false;
>     }
> @@ -478,21 +478,21 @@ ir_builder_print_visitor::visit_leave(ir_swizzle *ir)
>
>  ir_visitor_status
>  ir_builder_print_visitor::visit_enter(ir_assignment *ir)
>  {
>     ir_expression *const rhs_expr = ir->rhs->as_expression();
>
>     if (!is_simple_operand(ir->rhs) && rhs_expr == NULL)
>        return visit_continue;
>
>     if (rhs_expr != NULL) {
> -      const unsigned num_op = rhs_expr->get_num_operands();
> +      const unsigned num_op = rhs_expr->num_operands;
>
>        for (unsigned i = 0; i < num_op; i++) {
>           if (is_simple_operand(rhs_expr->operands[i]))
>              continue;
>
>           rhs_expr->operands[i]->accept(this);
>        }
>     }
>
>     ir_visitor_status s;
> @@ -531,21 +531,21 @@ ir_builder_print_visitor::visit_leave(ir_assignment *ir)
>                       (unsigned)(uintptr_t) he_lhs->data,
>                       (unsigned)(uintptr_t) he_rhs->data,
>                       ir->write_mask);
>
>     return visit_continue;
>  }
>
>  void
>  ir_builder_print_visitor::print_without_declaration(const ir_expression *ir)
>  {
> -   const unsigned num_op = ir->get_num_operands();
> +   const unsigned num_op = ir->num_operands;
>
>     static const char *const arity[] = {
>        "", "unop", "binop", "triop", "quadop"
>     };
>
>     switch (ir->operation) {
>     case ir_unop_neg:
>     case ir_binop_add:
>     case ir_binop_sub:
>     case ir_binop_mul:
> @@ -587,21 +587,21 @@ ir_builder_print_visitor::print_without_declaration(const ir_expression *ir)
>        if (i < num_op - 1)
>           print_without_indent(", ");
>     }
>
>     print_without_indent(")");
>  }
>
>  ir_visitor_status
>  ir_builder_print_visitor::visit_enter(ir_expression *ir)
>  {
> -   const unsigned num_op = ir->get_num_operands();
> +   const unsigned num_op = ir->num_operands;
>
>     for (unsigned i = 0; i < num_op; i++) {
>        if (is_simple_operand(ir->operands[i]))
>           continue;
>
>        ir->operands[i]->accept(this);
>     }
>
>     const unsigned my_index = next_ir_index++;
>
> diff --git a/src/compiler/glsl/ir_clone.cpp b/src/compiler/glsl/ir_clone.cpp
> index a64c7afa94..941e0865cb 100644
> --- a/src/compiler/glsl/ir_clone.cpp
> +++ b/src/compiler/glsl/ir_clone.cpp
> @@ -153,21 +153,21 @@ ir_call::clone(void *mem_ctx, struct hash_table *ht) const
>
>     return new(mem_ctx) ir_call(this->callee, new_return_ref, &new_parameters);
>  }
>
>  ir_expression *
>  ir_expression::clone(void *mem_ctx, struct hash_table *ht) const
>  {
>     ir_rvalue *op[ARRAY_SIZE(this->operands)] = { NULL, };
>     unsigned int i;
>
> -   for (i = 0; i < get_num_operands(); i++) {
> +   for (i = 0; i < num_operands; i++) {
>        op[i] = this->operands[i]->clone(mem_ctx, ht);
>     }
>
>     return new(mem_ctx) ir_expression(this->operation, this->type,
>                                      op[0], op[1], op[2], op[3]);
>  }
>
>  ir_dereference_variable *
>  ir_dereference_variable::clone(void *mem_ctx, struct hash_table *ht) const
>  {
> diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp
> index cd3cd1bb59..d4a8b7d020 100644
> --- a/src/compiler/glsl/ir_constant_expression.cpp
> +++ b/src/compiler/glsl/ir_constant_expression.cpp
> @@ -631,21 +631,21 @@ ir_constant *
>  ir_expression::constant_expression_value(struct hash_table *variable_context)
>  {
>     if (this->type->is_error())
>        return NULL;
>
>     ir_constant *op[ARRAY_SIZE(this->operands)] = { NULL, };
>     ir_constant_data data;
>
>     memset(&data, 0, sizeof(data));
>
> -   for (unsigned operand = 0; operand < this->get_num_operands(); operand++) {
> +   for (unsigned operand = 0; operand < this->num_operands; operand++) {
>        op[operand] = this->operands[operand]->constant_expression_value(variable_context);
>        if (!op[operand])
>           return NULL;
>     }
>
>     if (op[1] != NULL)
>        switch (this->operation) {
>        case ir_binop_lshift:
>        case ir_binop_rshift:
>        case ir_binop_ldexp:
> diff --git a/src/compiler/glsl/ir_equals.cpp b/src/compiler/glsl/ir_equals.cpp
> index 81980eb50a..f7359e2390 100644
> --- a/src/compiler/glsl/ir_equals.cpp
> +++ b/src/compiler/glsl/ir_equals.cpp
> @@ -195,17 +195,17 @@ ir_expression::equals(const ir_instruction *ir, enum ir_node_type ignore) const
>     const ir_expression *other = ir->as_expression();
>     if (!other)
>        return false;
>
>     if (type != other->type)
>        return false;
>
>     if (operation != other->operation)
>        return false;
>
> -   for (unsigned i = 0; i < get_num_operands(); i++) {
> +   for (unsigned i = 0; i < num_operands; i++) {
>        if (!operands[i]->equals(other->operands[i], ignore))
>           return false;
>     }
>
>     return true;
>  }
> diff --git a/src/compiler/glsl/ir_hv_accept.cpp b/src/compiler/glsl/ir_hv_accept.cpp
> index 7bbc2163d3..bf3f3d4f04 100644
> --- a/src/compiler/glsl/ir_hv_accept.cpp
> +++ b/src/compiler/glsl/ir_hv_accept.cpp
> @@ -130,21 +130,21 @@ ir_function::accept(ir_hierarchical_visitor *v)
>
>
>  ir_visitor_status
>  ir_expression::accept(ir_hierarchical_visitor *v)
>  {
>     ir_visitor_status s = v->visit_enter(this);
>
>     if (s != visit_continue)
>        return (s == visit_continue_with_parent) ? visit_continue : s;
>
> -   for (unsigned i = 0; i < this->get_num_operands(); i++) {
> +   for (unsigned i = 0; i < this->num_operands; i++) {
>        switch (this->operands[i]->accept(v)) {
>        case visit_continue:
>          break;
>
>        case visit_continue_with_parent:
>          // I wish for Java's labeled break-statement here.
>          goto done;
>
>        case visit_stop:
>          return visit_stop;
> diff --git a/src/compiler/glsl/ir_print_visitor.cpp b/src/compiler/glsl/ir_print_visitor.cpp
> index 86ddea6886..a32a410919 100644
> --- a/src/compiler/glsl/ir_print_visitor.cpp
> +++ b/src/compiler/glsl/ir_print_visitor.cpp
> @@ -284,21 +284,21 @@ void ir_print_visitor::visit(ir_function *ir)
>
>
>  void ir_print_visitor::visit(ir_expression *ir)
>  {
>     fprintf(f, "(expression ");
>
>     print_type(f, ir->type);
>
>     fprintf(f, " %s ", ir_expression_operation_strings[ir->operation]);
>
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++) {
> +   for (unsigned i = 0; i < ir->num_operands; i++) {
>        ir->operands[i]->accept(this);
>     }
>
>     fprintf(f, ") ");
>  }
>
>
>  void ir_print_visitor::visit(ir_texture *ir)
>  {
>     fprintf(f, "(%s ", ir->opcode_string());
> diff --git a/src/compiler/glsl/ir_rvalue_visitor.cpp b/src/compiler/glsl/ir_rvalue_visitor.cpp
> index d052606f4d..72dd6201ec 100644
> --- a/src/compiler/glsl/ir_rvalue_visitor.cpp
> +++ b/src/compiler/glsl/ir_rvalue_visitor.cpp
> @@ -32,21 +32,21 @@
>  #include "ir.h"
>  #include "ir_visitor.h"
>  #include "ir_rvalue_visitor.h"
>  #include "compiler/glsl_types.h"
>
>  ir_visitor_status
>  ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir)
>  {
>     unsigned int operand;
>
> -   for (operand = 0; operand < ir->get_num_operands(); operand++) {
> +   for (operand = 0; operand < ir->num_operands; operand++) {
>        handle_rvalue(&ir->operands[operand]);
>     }
>
>     return visit_continue;
>  }
>
>  ir_visitor_status
>  ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir)
>  {
>     handle_rvalue(&ir->coordinate);
> diff --git a/src/compiler/glsl/ir_validate.cpp b/src/compiler/glsl/ir_validate.cpp
> index 6e2f3e5b50..b6c3d89f50 100644
> --- a/src/compiler/glsl/ir_validate.cpp
> +++ b/src/compiler/glsl/ir_validate.cpp
> @@ -229,20 +229,28 @@ ir_validate::visit_enter(ir_function_signature *ir)
>     }
>
>     this->validate_ir(ir, this->data_enter);
>
>     return visit_continue;
>  }
>
>  ir_visitor_status
>  ir_validate::visit_leave(ir_expression *ir)
>  {
> +   for (int i = ir->num_operands; i < 4; i++) {
> +      assert(ir->operands[i] == NULL);
> +   }
> +
> +   for (unsigned i = 0; i < ir->num_operands; i++) {
> +      assert(ir->operands[i] != NULL);
> +   }
> +
>     switch (ir->operation) {
>     case ir_unop_bit_not:
>        assert(ir->operands[0]->type == ir->type);
>        break;
>     case ir_unop_logic_not:
>        assert(ir->type->is_boolean());
>        assert(ir->operands[0]->type->is_boolean());
>        break;
>
>     case ir_unop_neg:
> diff --git a/src/compiler/glsl/lower_instructions.cpp b/src/compiler/glsl/lower_instructions.cpp
> index 697bb84344..dfce900a16 100644
> --- a/src/compiler/glsl/lower_instructions.cpp
> +++ b/src/compiler/glsl/lower_instructions.cpp
> @@ -186,38 +186,40 @@ lower_instructions(exec_list *instructions, unsigned what_to_lower)
>     lower_instructions_visitor v(what_to_lower);
>
>     visit_list_elements(&v, instructions);
>     return v.progress;
>  }
>
>  void
>  lower_instructions_visitor::sub_to_add_neg(ir_expression *ir)
>  {
>     ir->operation = ir_binop_add;
> +   ir->init_num_operands();
>     ir->operands[1] = new(ir) ir_expression(ir_unop_neg, ir->operands[1]->type,
>                                            ir->operands[1], NULL);
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::div_to_mul_rcp(ir_expression *ir)
>  {
>     assert(ir->operands[1]->type->is_float() || ir->operands[1]->type->is_double());
>
>     /* New expression for the 1.0 / op1 */
>     ir_rvalue *expr;
>     expr = new(ir) ir_expression(ir_unop_rcp,
>                                 ir->operands[1]->type,
>                                 ir->operands[1]);
>
>     /* op0 / op1 -> op0 * (1.0 / op1) */
>     ir->operation = ir_binop_mul;
> +   ir->init_num_operands();
>     ir->operands[1] = expr;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::int_div_to_mul_rcp(ir_expression *ir)
>  {
>     assert(ir->operands[1]->type->is_integer());
>
> @@ -254,54 +256,58 @@ lower_instructions_visitor::int_div_to_mul_rcp(ir_expression *ir)
>
>     op0 = new(ir) ir_expression(ir_binop_mul, vec_type, op0, op1);
>
>     if (ir->operands[1]->type->base_type == GLSL_TYPE_INT) {
>        ir->operation = ir_unop_f2i;
>        ir->operands[0] = op0;
>     } else {
>        ir->operation = ir_unop_i2u;
>        ir->operands[0] = new(ir) ir_expression(ir_unop_f2i, op0);
>     }
> +   ir->init_num_operands();
>     ir->operands[1] = NULL;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::exp_to_exp2(ir_expression *ir)
>  {
>     ir_constant *log2_e = new(ir) ir_constant(float(M_LOG2E));
>
>     ir->operation = ir_unop_exp2;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[0]->type,
>                                            ir->operands[0], log2_e);
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::pow_to_exp2(ir_expression *ir)
>  {
>     ir_expression *const log2_x =
>        new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
>                             ir->operands[0]);
>
>     ir->operation = ir_unop_exp2;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_expression(ir_binop_mul, ir->operands[1]->type,
>                                            ir->operands[1], log2_x);
>     ir->operands[1] = NULL;
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::log_to_log2(ir_expression *ir)
>  {
>     ir->operation = ir_binop_mul;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_expression(ir_unop_log2, ir->operands[0]->type,
>                                            ir->operands[0], NULL);
>     ir->operands[1] = new(ir) ir_constant(float(1.0 / M_LOG2E));
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::mod_to_floor(ir_expression *ir)
>  {
>     ir_variable *x = new(ir) ir_variable(ir->operands[0]->type, "mod_x",
> @@ -338,20 +344,21 @@ lower_instructions_visitor::mod_to_floor(ir_expression *ir)
>
>     if (lowering(DOPS_TO_DFRAC) && ir->type->is_double())
>        dfloor_to_dfrac(floor_expr);
>
>     ir_expression *const mul_expr =
>        new(ir) ir_expression(ir_binop_mul,
>                              new(ir) ir_dereference_variable(y),
>                              floor_expr);
>
>     ir->operation = ir_binop_sub;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_dereference_variable(x);
>     ir->operands[1] = mul_expr;
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
>  {
>     /* Translates
>      *    ir_binop_ldexp x exp
> @@ -458,26 +465,28 @@ lower_instructions_visitor::ldexp_to_arith(ir_expression *ir)
>      */
>
>     ir_constant *exp_shift_clone = exp_shift->clone(ir, NULL);
>
>     /* Don't generate new IR that would need to be lowered in an additional
>      * pass.
>      */
>     if (!lowering(INSERT_TO_SHIFTS)) {
>        ir_constant *exp_width = new(ir) ir_constant(8, vec_elem);
>        ir->operation = ir_unop_bitcast_i2f;
> +      ir->init_num_operands();
>        ir->operands[0] = bitfield_insert(bitcast_f2i(x), resulting_biased_exp,
>                                          exp_shift_clone, exp_width);
>        ir->operands[1] = NULL;
>     } else {
>        ir_constant *sign_mantissa_mask = new(ir) ir_constant(0x807fffffu, vec_elem);
>        ir->operation = ir_unop_bitcast_u2f;
> +      ir->init_num_operands();
>        ir->operands[0] = bit_or(bit_and(bitcast_f2u(x), sign_mantissa_mask),
>                                 lshift(i2u(resulting_biased_exp), exp_shift_clone));
>     }
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::dldexp_to_arith(ir_expression *ir)
>  {
> @@ -588,20 +597,21 @@ lower_instructions_visitor::dldexp_to_arith(ir_expression *ir)
>              i2u(swizzle(resulting_biased_exp, elem, 1)),
>              exp_shift->clone(ir, NULL),
>              exp_width->clone(ir, NULL));
>
>        i.insert_before(assign(unpacked, bfi, WRITEMASK_Y));
>
>        results[elem] = expr(ir_unop_pack_double_2x32, unpacked);
>     }
>
>     ir->operation = ir_quadop_vector;
> +   ir->init_num_operands();
>     ir->operands[0] = results[0];
>     ir->operands[1] = results[1];
>     ir->operands[2] = results[2];
>     ir->operands[3] = results[3];
>
>     /* Don't generate new IR that would need to be lowered in an additional
>      * pass.
>      */
>
>     this->progress = true;
> @@ -664,20 +674,21 @@ lower_instructions_visitor::dfrexp_sig_to_arith(ir_expression *ir)
>        i.insert_before(assign(bits, bit_or(bits,
>                                            csel(swizzle(is_not_zero, elem, 1),
>                                                 exponent_value,
>                                                 zero))));
>        i.insert_before(assign(unpacked, bits, WRITEMASK_Y));
>        results[elem] = expr(ir_unop_pack_double_2x32, unpacked);
>     }
>
>     /* Put the dvec back together */
>     ir->operation = ir_quadop_vector;
> +   ir->init_num_operands();
>     ir->operands[0] = results[0];
>     ir->operands[1] = results[1];
>     ir->operands[2] = results[2];
>     ir->operands[3] = results[3];
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::dfrexp_exp_to_arith(ir_expression *ir)
> @@ -717,73 +728,77 @@ lower_instructions_visitor::dfrexp_exp_to_arith(ir_expression *ir)
>        i.insert_before(assign(high_words,
>                               swizzle_y(expr(ir_unop_unpack_double_2x32, x)),
>                               1 << elem));
>
>     }
>     ir_constant *exponent_shift = new(ir) ir_constant(20, vec_elem);
>     ir_constant *exponent_bias = new(ir) ir_constant(-1022, vec_elem);
>
>     /* For non-zero inputs, shift the exponent down and apply bias. */
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_dereference_variable(is_not_zero);
>     ir->operands[1] = add(exponent_bias, u2i(rshift(high_words, exponent_shift)));
>     ir->operands[2] = izero;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::carry_to_arith(ir_expression *ir)
>  {
>     /* Translates
>      *   ir_binop_carry x y
>      * into
>      *   sum = ir_binop_add x y
>      *   bcarry = ir_binop_less sum x
>      *   carry = ir_unop_b2i bcarry
>      */
>
>     ir_rvalue *x_clone = ir->operands[0]->clone(ir, NULL);
>     ir->operation = ir_unop_i2u;
> +   ir->init_num_operands();
>     ir->operands[0] = b2i(less(add(ir->operands[0], ir->operands[1]), x_clone));
>     ir->operands[1] = NULL;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::borrow_to_arith(ir_expression *ir)
>  {
>     /* Translates
>      *   ir_binop_borrow x y
>      * into
>      *   bcarry = ir_binop_less x y
>      *   carry = ir_unop_b2i bcarry
>      */
>
>     ir->operation = ir_unop_i2u;
> +   ir->init_num_operands();
>     ir->operands[0] = b2i(less(ir->operands[0], ir->operands[1]));
>     ir->operands[1] = NULL;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::sat_to_clamp(ir_expression *ir)
>  {
>     /* Translates
>      *   ir_unop_saturate x
>      * into
>      *   ir_binop_min (ir_binop_max(x, 0.0), 1.0)
>      */
>
>     ir->operation = ir_binop_min;
> +   ir->init_num_operands();
>     ir->operands[0] = new(ir) ir_expression(ir_binop_max, ir->operands[0]->type,
>                                             ir->operands[0],
>                                             new(ir) ir_constant(0.0f));
>     ir->operands[1] = new(ir) ir_constant(1.0f);
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::double_dot_to_fma(ir_expression *ir)
> @@ -800,20 +815,21 @@ lower_instructions_visitor::double_dot_to_fma(ir_expression *ir)
>                                    swizzle(ir->operands[1]->clone(ir, NULL), i, 1)));
>        } else {
>           assig = assign(temp, fma(swizzle(ir->operands[0]->clone(ir, NULL), i, 1),
>                                    swizzle(ir->operands[1]->clone(ir, NULL), i, 1),
>                                    temp));
>        }
>        this->base_ir->insert_before(assig);
>     }
>
>     ir->operation = ir_triop_fma;
> +   ir->init_num_operands();
>     ir->operands[0] = swizzle(ir->operands[0], 0, 1);
>     ir->operands[1] = swizzle(ir->operands[1], 0, 1);
>     ir->operands[2] = new(ir) ir_dereference_variable(temp);
>
>     this->progress = true;
>
>  }
>
>  void
>  lower_instructions_visitor::double_lrp(ir_expression *ir)
> @@ -826,20 +842,21 @@ lower_instructions_visitor::double_lrp(ir_expression *ir)
>     case 1:
>        swizval = SWIZZLE_XXXX;
>        break;
>     default:
>        assert(op0->type->vector_elements == op2->type->vector_elements);
>        swizval = SWIZZLE_XYZW;
>        break;
>     }
>
>     ir->operation = ir_triop_fma;
> +   ir->init_num_operands();
>     ir->operands[0] = swizzle(op2, swizval, op0->type->vector_elements);
>     ir->operands[2] = mul(sub(one, op2->clone(ir, NULL)), op0);
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::dceil_to_dfrac(ir_expression *ir)
>  {
>     /*
> @@ -850,34 +867,36 @@ lower_instructions_visitor::dceil_to_dfrac(ir_expression *ir)
>     ir_instruction &i = *base_ir;
>     ir_constant *zero = new(ir) ir_constant(0.0, ir->operands[0]->type->vector_elements);
>     ir_constant *one = new(ir) ir_constant(1.0, ir->operands[0]->type->vector_elements);
>     ir_variable *frtemp = new(ir) ir_variable(ir->operands[0]->type, "frtemp",
>                                               ir_var_temporary);
>
>     i.insert_before(frtemp);
>     i.insert_before(assign(frtemp, fract(ir->operands[0])));
>
>     ir->operation = ir_binop_add;
> +   ir->init_num_operands();
>     ir->operands[0] = sub(ir->operands[0]->clone(ir, NULL), frtemp);
>     ir->operands[1] = csel(nequal(frtemp, zero), one, zero->clone(ir, NULL));
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::dfloor_to_dfrac(ir_expression *ir)
>  {
>     /*
>      * frtemp = frac(x);
>      * result = sub(x, frtemp);
>      */
>     ir->operation = ir_binop_sub;
> +   ir->init_num_operands();
>     ir->operands[1] = fract(ir->operands[0]->clone(ir, NULL));
>
>     this->progress = true;
>  }
>  void
>  lower_instructions_visitor::dround_even_to_dfrac(ir_expression *ir)
>  {
>     /*
>      * insane but works
>      * temp = x + 0.5;
> @@ -903,20 +922,21 @@ lower_instructions_visitor::dround_even_to_dfrac(ir_expression *ir)
>     i.insert_before(temp);
>     i.insert_before(assign(temp, add(ir->operands[0], p5)));
>
>     i.insert_before(frtemp);
>     i.insert_before(assign(frtemp, fract(temp)));
>
>     i.insert_before(t2);
>     i.insert_before(assign(t2, sub(temp, frtemp)));
>
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = equal(fract(ir->operands[0]->clone(ir, NULL)),
>                             p5->clone(ir, NULL));
>     ir->operands[1] = csel(equal(fract(mul(t2, p5->clone(ir, NULL))),
>                                  zero),
>                            t2,
>                            sub(t2, one));
>     ir->operands[2] = new(ir) ir_dereference_variable(t2);
>
>     this->progress = true;
>  }
> @@ -938,20 +958,21 @@ lower_instructions_visitor::dtrunc_to_dfrac(ir_expression *ir)
>                                               ir_var_temporary);
>     ir_variable *temp = new(ir) ir_variable(ir->operands[0]->type, "temp",
>                                             ir_var_temporary);
>
>     i.insert_before(frtemp);
>     i.insert_before(assign(frtemp, fract(arg)));
>     i.insert_before(temp);
>     i.insert_before(assign(temp, sub(arg->clone(ir, NULL), frtemp)));
>
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = gequal(arg->clone(ir, NULL), zero);
>     ir->operands[1] = new (ir) ir_dereference_variable(temp);
>     ir->operands[2] = add(temp,
>                           csel(equal(frtemp, zero->clone(ir, NULL)),
>                                zero->clone(ir, NULL),
>                                one));
>
>     this->progress = true;
>  }
>
> @@ -961,20 +982,21 @@ lower_instructions_visitor::dsign_to_csel(ir_expression *ir)
>     /*
>      * temp = x > 0.0 ? 1.0 : 0.0;
>      * result = x < 0.0 ? -1.0 : temp;
>      */
>     ir_rvalue *arg = ir->operands[0];
>     ir_constant *zero = new(ir) ir_constant(0.0, arg->type->vector_elements);
>     ir_constant *one = new(ir) ir_constant(1.0, arg->type->vector_elements);
>     ir_constant *neg_one = new(ir) ir_constant(-1.0, arg->type->vector_elements);
>
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = less(arg->clone(ir, NULL),
>                            zero->clone(ir, NULL));
>     ir->operands[1] = neg_one;
>     ir->operands[2] = csel(greater(arg, zero),
>                            one,
>                            zero->clone(ir, NULL));
>
>     this->progress = true;
>  }
>
> @@ -1010,20 +1032,21 @@ lower_instructions_visitor::bit_count_to_math(ir_expression *ir)
>     base_ir->insert_before(assign(temp, sub(temp, bit_and(rshift(temp, c1),
>                                                           c55555555))));
>
>     /* temp = (temp & 0x33333333u) + ((temp >> 2) & 0x33333333u); */
>     base_ir->insert_before(assign(temp, add(bit_and(temp, c33333333),
>                                             bit_and(rshift(temp, c2),
>                                                     c33333333->clone(ir, NULL)))));
>
>     /* int(((temp + (temp >> 4) & 0xF0F0F0Fu) * 0x1010101u) >> 24); */
>     ir->operation = ir_unop_u2i;
> +   ir->init_num_operands();
>     ir->operands[0] = rshift(mul(bit_and(add(temp, rshift(temp, c4)), c0F0F0F0F),
>                                  c01010101),
>                              c24);
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::extract_to_shifts(ir_expression *ir)
>  {
> @@ -1053,20 +1076,21 @@ lower_instructions_visitor::extract_to_shifts(ir_expression *ir)
>        /* Section 8.8 (Integer Functions) of the GLSL 4.50 spec says:
>         *
>         *    If bits is zero, the result will be zero.
>         *
>         * Since (1 << 0) - 1 == 0, we don't need to bother with the conditional
>         * select as in the signed integer case.
>         *
>         * (value >> offset) & mask;
>         */
>        ir->operation = ir_binop_bit_and;
> +      ir->init_num_operands();
>        ir->operands[0] = rshift(ir->operands[0], ir->operands[1]);
>        ir->operands[1] = mask;
>        ir->operands[2] = NULL;
>     } else {
>        ir_constant *c0 =
>           new(ir) ir_constant(int(0), ir->operands[0]->type->vector_elements);
>        ir_constant *c32 =
>           new(ir) ir_constant(int(32), ir->operands[0]->type->vector_elements);
>        ir_variable *temp =
>           new(ir) ir_variable(ir->operands[0]->type, "temp", ir_var_temporary);
> @@ -1083,20 +1107,21 @@ lower_instructions_visitor::extract_to_shifts(ir_expression *ir)
>         *
>         *    If bits is zero, the result will be zero.
>         *
>         * Due to the (x << (y%32)) behavior mentioned before, the (value <<
>         * (32-0)) doesn't "erase" all of the data as we would like, so finish
>         * up with:
>         *
>         * (bits == 0) ? 0 : e;
>         */
>        ir->operation = ir_triop_csel;
> +      ir->init_num_operands();
>        ir->operands[0] = equal(c0, bits);
>        ir->operands[1] = c0->clone(ir, NULL);
>        ir->operands[2] = expr;
>     }
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::insert_to_shifts(ir_expression *ir)
> @@ -1149,20 +1174,21 @@ lower_instructions_visitor::insert_to_shifts(ir_expression *ir)
>     base_ir->insert_before(mask);
>
>     base_ir->insert_before(assign(mask, csel(equal(bits, c32),
>                                              cFFFFFFFF,
>                                              lshift(sub(lshift(c1, bits),
>                                                         c1->clone(ir, NULL)),
>                                                     offset))));
>
>     /* (base & ~mask) | ((insert << offset) & mask) */
>     ir->operation = ir_binop_bit_or;
> +   ir->init_num_operands();
>     ir->operands[0] = bit_and(ir->operands[0], bit_not(mask));
>     ir->operands[1] = bit_and(lshift(ir->operands[1], offset), mask);
>     ir->operands[2] = NULL;
>     ir->operands[3] = NULL;
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::reverse_to_shifts(ir_expression *ir)
> @@ -1232,24 +1258,26 @@ lower_instructions_visitor::reverse_to_shifts(ir_expression *ir)
>      *
>      * temp = ((temp >> 8) & 0x00FF00FFu) | ((temp & 0x00FF00FFu) << 8);
>      * temp = ( temp >> 16              ) | ( temp                << 16);
>      */
>     i.insert_before(assign(temp, bit_or(bit_and(rshift(temp, c8), c00FF00FF),
>                                         lshift(bit_and(temp, c00FF00FF->clone(ir, NULL)),
>                                                c8->clone(ir, NULL)))));
>
>     if (ir->operands[0]->type->base_type == GLSL_TYPE_UINT) {
>        ir->operation = ir_binop_bit_or;
> +      ir->init_num_operands();
>        ir->operands[0] = rshift(temp, c16);
>        ir->operands[1] = lshift(temp, c16->clone(ir, NULL));
>     } else {
>        ir->operation = ir_unop_u2i;
> +      ir->init_num_operands();
>        ir->operands[0] = bit_or(rshift(temp, c16),
>                                 lshift(temp, c16->clone(ir, NULL)));
>     }
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::find_lsb_to_float_cast(ir_expression *ir)
>  {
> @@ -1316,20 +1344,21 @@ lower_instructions_visitor::find_lsb_to_float_cast(ir_expression *ir)
>      *
>      * (lsb_only == 0) ? -1 : lsb;
>      *
>      * Since our input values are all integers, the unbiased exponent must not
>      * be negative.  It will only be negative (-0x7f, in fact) if lsb_only is
>      * 0.  Instead of using (lsb_only == 0), we could use (lsb >= 0).  Which is
>      * better is likely GPU dependent.  Either way, the difference should be
>      * small.
>      */
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = equal(lsb_only, c0);
>     ir->operands[1] = cminus1;
>     ir->operands[2] = new(ir) ir_dereference_variable(lsb);
>
>     this->progress = true;
>  }
>
>  void
>  lower_instructions_visitor::find_msb_to_float_cast(ir_expression *ir)
>  {
> @@ -1416,20 +1445,21 @@ lower_instructions_visitor::find_msb_to_float_cast(ir_expression *ir)
>
>     /* Use msb in the comparison instead of temp so that the subtract can
>      * possibly generate the result without an explicit comparison.
>      *
>      * (msb < 0) ? -1 : msb;
>      *
>      * Since our input values are all integers, the unbiased exponent must not
>      * be negative.  It will only be negative (-0x7f, in fact) if temp is 0.
>      */
>     ir->operation = ir_triop_csel;
> +   ir->init_num_operands();
>     ir->operands[0] = less(msb, c0);
>     ir->operands[1] = cminus1;
>     ir->operands[2] = new(ir) ir_dereference_variable(msb);
>
>     this->progress = true;
>  }
>
>  ir_expression *
>  lower_instructions_visitor::_carry(operand a, operand b)
>  {
> @@ -1548,20 +1578,21 @@ lower_instructions_visitor::imul_high_to_mul(ir_expression *ir)
>     i.insert_before(assign(hi, add(hi, _carry(lo, lshift(t1, c16->clone(ir, NULL))))));
>     i.insert_before(assign(lo,            add(lo, lshift(t1, c16->clone(ir, NULL)))));
>
>     i.insert_before(assign(hi, add(hi, _carry(lo, lshift(t2, c16->clone(ir, NULL))))));
>     i.insert_before(assign(lo,            add(lo, lshift(t2, c16->clone(ir, NULL)))));
>
>     if (different_signs == NULL) {
>        assert(ir->operands[0]->type->base_type == GLSL_TYPE_UINT);
>
>        ir->operation = ir_binop_add;
> +      ir->init_num_operands();
>        ir->operands[0] = add(hi, rshift(t1, c16->clone(ir, NULL)));
>        ir->operands[1] = rshift(t2, c16->clone(ir, NULL));
>     } else {
>        assert(ir->operands[0]->type->base_type == GLSL_TYPE_INT);
>
>        i.insert_before(assign(hi, add(add(hi, rshift(t1, c16->clone(ir, NULL))),
>                                       rshift(t2, c16->clone(ir, NULL)))));
>
>        /* For channels where different_signs is set we have to perform a 64-bit
>         * negation.  This is *not* the same as just negating the high 32-bits.
> @@ -1570,20 +1601,21 @@ lower_instructions_visitor::imul_high_to_mul(ir_expression *ir)
>         */
>        ir_variable *neg_hi =
>           new(ir) ir_variable(glsl_type::ivec(elements), "neg_hi", ir_var_temporary);
>        ir_constant *c1 = new(ir) ir_constant(1u, elements);
>
>        i.insert_before(neg_hi);
>        i.insert_before(assign(neg_hi, add(bit_not(u2i(hi)),
>                                           u2i(_carry(bit_not(lo), c1)))));
>
>        ir->operation = ir_triop_csel;
> +      ir->init_num_operands();
>        ir->operands[0] = new(ir) ir_dereference_variable(different_signs);
>        ir->operands[1] = new(ir) ir_dereference_variable(neg_hi);
>        ir->operands[2] = u2i(hi);
>     }
>  }
>
>  void
>  lower_instructions_visitor::sqrt_to_abs_sqrt(ir_expression *ir)
>  {
>     ir->operands[0] = new(ir) ir_expression(ir_unop_abs, ir->operands[0]);
> diff --git a/src/compiler/glsl/lower_int64.cpp b/src/compiler/glsl/lower_int64.cpp
> index 9770d314af..b6bf9cee7d 100644
> --- a/src/compiler/glsl/lower_int64.cpp
> +++ b/src/compiler/glsl/lower_int64.cpp
> @@ -251,21 +251,21 @@ lower_64bit::compact_destination(ir_factory &body,
>
>     void *const mem_ctx = ralloc_parent(compacted_result);
>     return new(mem_ctx) ir_dereference_variable(compacted_result);
>  }
>
>  ir_rvalue *
>  lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
>                                         ir_expression *ir,
>                                         ir_function_signature *callee)
>  {
> -   const unsigned num_operands = ir->get_num_operands();
> +   const unsigned num_operands = ir->num_operands;
>     ir_variable *src[4][4];
>     ir_variable *dst[4];
>     void *const mem_ctx = ralloc_parent(ir);
>     exec_list instructions;
>     unsigned source_components = 0;
>     const glsl_type *const result_type =
>        ir->type->base_type == GLSL_TYPE_UINT64
>        ? glsl_type::uvec2_type : glsl_type::ivec2_type;
>
>     ir_factory body(&instructions, mem_ctx);
> @@ -312,21 +312,21 @@ lower_64bit::lower_op_to_function_call(ir_instruction *base_ir,
>     tail->next = after;
>
>     return rv;
>  }
>
>  ir_rvalue *
>  lower_64bit_visitor::handle_op(ir_expression *ir,
>                                 const char *function_name,
>                                 function_generator generator)
>  {
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++)
> +   for (unsigned i = 0; i < ir->num_operands; i++)
>        if (!ir->operands[i]->type->is_integer_64())
>           return ir;
>
>     /* Get a handle to the correct ir_function_signature for the core
>      * operation.
>      */
>     ir_function_signature *callee = NULL;
>     ir_function *f = find_function(function_name);
>
>     if (f != NULL) {
> diff --git a/src/compiler/glsl/lower_mat_op_to_vec.cpp b/src/compiler/glsl/lower_mat_op_to_vec.cpp
> index 9a27029de3..88c5d6679d 100644
> --- a/src/compiler/glsl/lower_mat_op_to_vec.cpp
> +++ b/src/compiler/glsl/lower_mat_op_to_vec.cpp
> @@ -69,21 +69,21 @@ public:
>
>  static bool
>  mat_op_to_vec_predicate(ir_instruction *ir)
>  {
>     ir_expression *expr = ir->as_expression();
>     unsigned int i;
>
>     if (!expr)
>        return false;
>
> -   for (i = 0; i < expr->get_num_operands(); i++) {
> +   for (i = 0; i < expr->num_operands; i++) {
>        if (expr->operands[i]->type->is_matrix())
>          return true;
>     }
>
>     return false;
>  }
>
>  bool
>  do_mat_op_to_vec(exec_list *instructions)
>  {
> @@ -287,21 +287,21 @@ ir_mat_op_to_vec_visitor::do_equal_mat_mat(ir_dereference *result,
>        any = new(this->mem_ctx) ir_expression(ir_unop_logic_not, any);
>
>     ir_assignment *const assign =
>        new(mem_ctx) ir_assignment(result->clone(mem_ctx, NULL), any);
>     base_ir->insert_before(assign);
>  }
>
>  static bool
>  has_matrix_operand(const ir_expression *expr, unsigned &columns)
>  {
> -   for (unsigned i = 0; i < expr->get_num_operands(); i++) {
> +   for (unsigned i = 0; i < expr->num_operands; i++) {
>        if (expr->operands[i]->type->is_matrix()) {
>          columns = expr->operands[i]->type->matrix_columns;
>          return true;
>        }
>     }
>
>     return false;
>  }
>
>
> @@ -311,32 +311,32 @@ ir_mat_op_to_vec_visitor::visit_leave(ir_assignment *orig_assign)
>     ir_expression *orig_expr = orig_assign->rhs->as_expression();
>     unsigned int i, matrix_columns = 1;
>     ir_dereference *op[2];
>
>     if (!orig_expr)
>        return visit_continue;
>
>     if (!has_matrix_operand(orig_expr, matrix_columns))
>        return visit_continue;
>
> -   assert(orig_expr->get_num_operands() <= 2);
> +   assert(orig_expr->num_operands <= 2);
>
>     mem_ctx = ralloc_parent(orig_assign);
>
>     ir_dereference_variable *result =
>        orig_assign->lhs->as_dereference_variable();
>     assert(result);
>
>     /* Store the expression operands in temps so we can use them
>      * multiple times.
>      */
> -   for (i = 0; i < orig_expr->get_num_operands(); i++) {
> +   for (i = 0; i < orig_expr->num_operands; i++) {
>        ir_assignment *assign;
>        ir_dereference *deref = orig_expr->operands[i]->as_dereference();
>
>        /* Avoid making a temporary if we don't need to to avoid aliasing. */
>        if (deref &&
>           deref->variable_referenced() != result->variable_referenced()) {
>          op[i] = deref;
>          continue;
>        }
>
> diff --git a/src/compiler/glsl/lower_ubo_reference.cpp b/src/compiler/glsl/lower_ubo_reference.cpp
> index 163c25e706..a63d80c139 100644
> --- a/src/compiler/glsl/lower_ubo_reference.cpp
> +++ b/src/compiler/glsl/lower_ubo_reference.cpp
> @@ -620,21 +620,21 @@ lower_ubo_reference_visitor::check_ssbo_unsized_array_length_expression(ir_expre
>  {
>     if (ir->operation ==
>         ir_expression_operation(ir_unop_ssbo_unsized_array_length)) {
>           /* Don't replace this unop if it is found alone. It is going to be
>            * removed by the optimization passes or replaced if it is part of
>            * an ir_assignment or another ir_expression.
>            */
>           return;
>     }
>
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++) {
> +   for (unsigned i = 0; i < ir->num_operands; i++) {
>        if (ir->operands[i]->ir_type != ir_type_expression)
>           continue;
>        ir_expression *expr = (ir_expression *) ir->operands[i];
>        ir_expression *temp = calculate_ssbo_unsized_array_length(expr);
>        if (!temp)
>           continue;
>
>        delete expr;
>        ir->operands[i] = temp;
>     }
> diff --git a/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp b/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> index 784db08592..ea8b5922ce 100644
> --- a/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> +++ b/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> @@ -158,21 +158,21 @@ ir_vec_index_to_cond_assign_visitor::convert_vector_extract_to_cond_assign(ir_rv
>                                             expr->operands[0],
>                                             expr->operands[1],
>                                             ir->type);
>  }
>
>  ir_visitor_status
>  ir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir)
>  {
>     unsigned int i;
>
> -   for (i = 0; i < ir->get_num_operands(); i++) {
> +   for (i = 0; i < ir->num_operands; i++) {
>        ir->operands[i] = convert_vector_extract_to_cond_assign(ir->operands[i]);
>     }
>
>     return visit_continue;
>  }
>
>  ir_visitor_status
>  ir_vec_index_to_cond_assign_visitor::visit_enter(ir_swizzle *ir)
>  {
>     /* Can't be hit from normal GLSL, since you can't swizzle a scalar (which
> diff --git a/src/compiler/glsl/lower_vector.cpp b/src/compiler/glsl/lower_vector.cpp
> index a658410ae6..72192b1b25 100644
> --- a/src/compiler/glsl/lower_vector.cpp
> +++ b/src/compiler/glsl/lower_vector.cpp
> @@ -126,21 +126,21 @@ lower_vector_visitor::handle_rvalue(ir_rvalue **rvalue)
>     if ((expr == NULL) || (expr->operation != ir_quadop_vector))
>        return;
>
>     if (this->dont_lower_swz && is_extended_swizzle(expr))
>        return;
>
>     /* FINISHME: Is this the right thing to use for the ralloc context?
>      */
>     void *const mem_ctx = expr;
>
> -   assert(expr->type->vector_elements == expr->get_num_operands());
> +   assert(expr->type->vector_elements == expr->num_operands);
>
>     /* Generate a temporary with the same type as the ir_quadop_operation.
>      */
>     ir_variable *const temp =
>        new(mem_ctx) ir_variable(expr->type, "vecop_tmp", ir_var_temporary);
>
>     this->base_ir->insert_before(temp);
>
>     /* Counter of the number of components collected so far.
>      */
> diff --git a/src/compiler/glsl/opt_algebraic.cpp b/src/compiler/glsl/opt_algebraic.cpp
> index b44ab595ec..382b4617d1 100644
> --- a/src/compiler/glsl/opt_algebraic.cpp
> +++ b/src/compiler/glsl/opt_algebraic.cpp
> @@ -321,22 +321,22 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
>
>        if (matrix_mul && matrix_mul->operation == ir_binop_mul &&
>           matrix_mul->operands[0]->type->is_matrix() &&
>           matrix_mul->operands[1]->type->is_matrix()) {
>
>           return mul(matrix_mul->operands[0],
>                      mul(matrix_mul->operands[1], ir->operands[1]));
>        }
>     }
>
> -   assert(ir->get_num_operands() <= 4);
> -   for (unsigned i = 0; i < ir->get_num_operands(); i++) {
> +   assert(ir->num_operands <= 4);
> +   for (unsigned i = 0; i < ir->num_operands; i++) {
>        if (ir->operands[i]->type->is_matrix())
>          return ir;
>
>        op_const[i] = ir->operands[i]->constant_expression_value();
>        op_expr[i] = ir->operands[i]->as_expression();
>     }
>
>     if (this->mem_ctx == NULL)
>        this->mem_ctx = ralloc_parent(ir);
>
> diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp
> index 97dcc7e1ac..e72aec78f6 100644
> --- a/src/compiler/glsl/opt_constant_folding.cpp
> +++ b/src/compiler/glsl/opt_constant_folding.cpp
> @@ -67,21 +67,21 @@ ir_constant_fold(ir_rvalue **rvalue)
>     if (*rvalue == NULL || (*rvalue)->ir_type == ir_type_constant)
>        return false;
>
>     /* Note that we do rvalue visitoring on leaving.  So if an
>      * expression has a non-constant operand, no need to go looking
>      * down it to find if it's constant.  This cuts the time of this
>      * pass down drastically.
>      */
>     ir_expression *expr = (*rvalue)->as_expression();
>     if (expr) {
> -      for (unsigned int i = 0; i < expr->get_num_operands(); i++) {
> +      for (unsigned int i = 0; i < expr->num_operands; i++) {
>          if (!expr->operands[i]->as_constant())
>             return false;
>        }
>     }
>
>     /* Ditto for swizzles. */
>     ir_swizzle *swiz = (*rvalue)->as_swizzle();
>     if (swiz && !swiz->val->as_constant())
>        return false;
>
> diff --git a/src/compiler/glsl/opt_tree_grafting.cpp b/src/compiler/glsl/opt_tree_grafting.cpp
> index b0a1604191..6b5d93af66 100644
> --- a/src/compiler/glsl/opt_tree_grafting.cpp
> +++ b/src/compiler/glsl/opt_tree_grafting.cpp
> @@ -225,21 +225,21 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir)
>
>     if (ir->return_deref && check_graft(ir, ir->return_deref->var) == visit_stop)
>        return visit_stop;
>
>     return visit_continue;
>  }
>
>  ir_visitor_status
>  ir_tree_grafting_visitor::visit_enter(ir_expression *ir)
>  {
> -   for (unsigned int i = 0; i < ir->get_num_operands(); i++) {
> +   for (unsigned int i = 0; i < ir->num_operands; i++) {
>        if (do_graft(&ir->operands[i]))
>          return visit_stop;
>     }
>
>     return visit_continue;
>  }
>
>  ir_visitor_status
>  ir_tree_grafting_visitor::visit_enter(ir_if *ir)
>  {
> diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
> index ac12b59d07..db7f11c6bf 100644
> --- a/src/mesa/program/ir_to_mesa.cpp
> +++ b/src/mesa/program/ir_to_mesa.cpp
> @@ -997,21 +997,21 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
>          return;
>        if (try_emit_mad_for_and_not(ir, 0))
>          return;
>     }
>
>     if (ir->operation == ir_quadop_vector) {
>        this->emit_swz(ir);
>        return;
>     }
>
> -   for (operand = 0; operand < ir->get_num_operands(); operand++) {
> +   for (operand = 0; operand < ir->num_operands; operand++) {
>        this->result.file = PROGRAM_UNDEFINED;
>        ir->operands[operand]->accept(this);
>        if (this->result.file == PROGRAM_UNDEFINED) {
>          printf("Failed to get tree for expression operand:\n");
>           ir->operands[operand]->print();
>           printf("\n");
>          exit(1);
>        }
>        op[operand] = this->result;
>
> @@ -1729,21 +1729,21 @@ get_sampler_uniform_value(class ir_dereference *sampler,
>   * operand to the CMP instruction.
>   */
>  bool
>  ir_to_mesa_visitor::process_move_condition(ir_rvalue *ir)
>  {
>     ir_rvalue *src_ir = ir;
>     bool negate = true;
>     bool switch_order = false;
>
>     ir_expression *const expr = ir->as_expression();
> -   if ((expr != NULL) && (expr->get_num_operands() == 2)) {
> +   if ((expr != NULL) && (expr->num_operands == 2)) {
>        bool zero_on_left = false;
>
>        if (expr->operands[0]->is_zero()) {
>          src_ir = expr->operands[1];
>          zero_on_left = true;
>        } else if (expr->operands[1]->is_zero()) {
>          src_ir = expr->operands[0];
>          zero_on_left = false;
>        }
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 9bc745c791..aaa5cddcf3 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -1568,21 +1568,21 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir)
>     if (!native_integers && ir->operation == ir_binop_logic_and) {
>        if (try_emit_mad_for_and_not(ir, 1))
>           return;
>        if (try_emit_mad_for_and_not(ir, 0))
>           return;
>     }
>
>     if (ir->operation == ir_quadop_vector)
>        assert(!"ir_quadop_vector should have been lowered");
>
> -   for (unsigned int operand = 0; operand < ir->get_num_operands(); operand++) {
> +   for (unsigned int operand = 0; operand < ir->num_operands; operand++) {
>        this->result.file = PROGRAM_UNDEFINED;
>        ir->operands[operand]->accept(this);
>        if (this->result.file == PROGRAM_UNDEFINED) {
>           printf("Failed to get tree for expression operand:\n");
>           ir->operands[operand]->print();
>           printf("\n");
>           exit(1);
>        }
>        op[operand] = this->result;
>
> @@ -2983,21 +2983,21 @@ get_assignment_lhs(ir_dereference *ir, glsl_to_tgsi_visitor *v, int *component)
>  bool
>  glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
>  {
>     ir_rvalue *src_ir = ir;
>     bool negate = true;
>     bool switch_order = false;
>
>     ir_expression *const expr = ir->as_expression();
>
>     if (native_integers) {
> -      if ((expr != NULL) && (expr->get_num_operands() == 2)) {
> +      if ((expr != NULL) && (expr->num_operands == 2)) {
>           enum glsl_base_type type = expr->operands[0]->type->base_type;
>           if (type == GLSL_TYPE_INT || type == GLSL_TYPE_UINT ||
>               type == GLSL_TYPE_BOOL) {
>              if (expr->operation == ir_binop_equal) {
>                 if (expr->operands[0]->is_zero()) {
>                    src_ir = expr->operands[1];
>                    switch_order = true;
>                 }
>                 else if (expr->operands[1]->is_zero()) {
>                    src_ir = expr->operands[0];
> @@ -3012,21 +3012,21 @@ glsl_to_tgsi_visitor::process_move_condition(ir_rvalue *ir)
>                    src_ir = expr->operands[0];
>                 }
>              }
>           }
>        }
>
>        src_ir->accept(this);
>        return switch_order;
>     }
>
> -   if ((expr != NULL) && (expr->get_num_operands() == 2)) {
> +   if ((expr != NULL) && (expr->num_operands == 2)) {
>        bool zero_on_left = false;
>
>        if (expr->operands[0]->is_zero()) {
>           src_ir = expr->operands[1];
>           zero_on_left = true;
>        } else if (expr->operands[1]->is_zero()) {
>           src_ir = expr->operands[0];
>           zero_on_left = false;
>        }
>
> --
> 2.13.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list