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

Timothy Arceri tarceri at itsqueeze.com
Wed Aug 9 03:34:02 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.

The reduction in time is so small that it is not really
measurable. However callgrind was reporting this function as
being called just under 34 million times while compiling the
Deus Ex shaders (just pre-linking was profiled) with 0.20%
spent in this function.

v2:
 - make num_operands a unit8_t
 - fix unsigned/signed mismatches

Reviewed-by: Thomas Helland<thomashelland90 at gmail.com>
---
 src/compiler/glsl/glsl_to_nir.cpp                  |  4 +--
 src/compiler/glsl/ir.cpp                           | 22 +++++++++++++--
 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, 103 insertions(+), 32 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..51b875058b 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++) {
+   for (unsigned 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..58e6356566 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];
+   uint8_t 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..397cd080b1 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 (unsigned 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.4



More information about the mesa-dev mailing list