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

Timothy Arceri tarceri at itsqueeze.com
Sun Jul 30 22:37:42 UTC 2017


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 4b3dbcff17..0bf82d126f 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -1480,25 +1480,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
 }
 
 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 baa835924b..a170b2d7b2 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1569,21 +1569,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;
 
@@ -2984,21 +2984,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];
@@ -3013,21 +3013,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



More information about the mesa-dev mailing list