Mesa (master): glsl: pass mem_ctx to constant_expression_value(...) and friends

Timothy Arceri tarceri at kemper.freedesktop.org
Fri Aug 11 05:47:15 UTC 2017


Module: Mesa
Branch: master
Commit: 77f5221233ea427b622af46831feed438e0dd59e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=77f5221233ea427b622af46831feed438e0dd59e

Author: Timothy Arceri <tarceri at itsqueeze.com>
Date:   Thu Aug 10 20:42:29 2017 +1000

glsl: pass mem_ctx to constant_expression_value(...) and friends

The main motivation for this is that threaded compilation can fall
over if we were to allocate IR inside constant_expression_value()
when calling it on a builtin. This is because builtins are shared
across the whole OpenGL context.

f81ede469910d worked around the problem by cloning the entire
builtin before constant_expression_value() could be called on
it. However cloning the whole function each time we referenced
it lead to a significant reduction in the GLSL IR compiler
performance. This change along with the following patch
helps fix that performance regression.

Other advantages are that we reduce the number of calls to
ralloc_parent(), and for loop unrolling we free constants after
they are used rather than leaving them hanging around.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/compiler/glsl/ast_array_index.cpp            |   2 +-
 src/compiler/glsl/ast_function.cpp               |  17 ++--
 src/compiler/glsl/ast_to_hir.cpp                 |  15 ++-
 src/compiler/glsl/ast_type.cpp                   |   7 +-
 src/compiler/glsl/ir.h                           |  37 +++++---
 src/compiler/glsl/ir_constant_expression.cpp     | 114 +++++++++++++++--------
 src/compiler/glsl/linker.cpp                     |   2 +-
 src/compiler/glsl/loop_controls.cpp              |   6 +-
 src/compiler/glsl/loop_unroll.cpp                |   2 +-
 src/compiler/glsl/lower_buffer_access.cpp        |   2 +-
 src/compiler/glsl/lower_distance.cpp             |   3 +-
 src/compiler/glsl/lower_tess_level.cpp           |   3 +-
 src/compiler/glsl/lower_vec_index_to_swizzle.cpp |   7 +-
 src/compiler/glsl/lower_vector_derefs.cpp        |   3 +-
 src/compiler/glsl/lower_vector_insert.cpp        |   3 +-
 src/compiler/glsl/opt_algebraic.cpp              |   9 +-
 src/compiler/glsl/opt_constant_folding.cpp       |   5 +-
 src/compiler/glsl/opt_constant_propagation.cpp   |   3 +-
 src/compiler/glsl/opt_constant_variable.cpp      |   2 +-
 src/compiler/glsl/opt_if_simplification.cpp      |   3 +-
 src/mesa/program/ir_to_mesa.cpp                  |   6 +-
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp       |   7 +-
 22 files changed, 168 insertions(+), 90 deletions(-)

diff --git a/src/compiler/glsl/ast_array_index.cpp b/src/compiler/glsl/ast_array_index.cpp
index efddbed6ea..3b30f6858e 100644
--- a/src/compiler/glsl/ast_array_index.cpp
+++ b/src/compiler/glsl/ast_array_index.cpp
@@ -167,7 +167,7 @@ _mesa_ast_array_index_to_hir(void *mem_ctx,
     * index is not a constant expression, ensure that the array has a
     * declared size.
     */
-   ir_constant *const const_index = idx->constant_expression_value();
+   ir_constant *const const_index = idx->constant_expression_value(mem_ctx);
    if (const_index != NULL && idx->type->is_integer()) {
       const int idx = const_index->value.i[0];
       const char *type_name = "error";
diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp
index f7e90fba5b..b121ab9210 100644
--- a/src/compiler/glsl/ast_function.cpp
+++ b/src/compiler/glsl/ast_function.cpp
@@ -37,6 +37,7 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters,
                    exec_list *parameters,
                    struct _mesa_glsl_parse_state *state)
 {
+   void *mem_ctx = state;
    unsigned count = 0;
 
    foreach_list_typed(ast_node, ast, link, parameters) {
@@ -48,7 +49,9 @@ process_parameters(exec_list *instructions, exec_list *actual_parameters,
       ast->set_is_lhs(true);
       ir_rvalue *result = ast->hir(instructions, state);
 
-      ir_constant *const constant = result->constant_expression_value();
+      ir_constant *const constant =
+         result->constant_expression_value(mem_ctx);
+
       if (constant != NULL)
          result = constant;
 
@@ -518,7 +521,8 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
     * instructions; just generate an ir_constant.
     */
    if (state->is_version(120, 100)) {
-      ir_constant *value = sig->constant_expression_value(actual_parameters,
+      ir_constant *value = sig->constant_expression_value(ctx,
+                                                          actual_parameters,
                                                           NULL);
       if (value != NULL) {
          return value;
@@ -939,7 +943,7 @@ convert_component(ir_rvalue *src, const glsl_type *desired_type)
    assert(result->type == desired_type);
 
    /* Try constant folding; it may fold in the conversion we just added. */
-   ir_constant *const constant = result->constant_expression_value();
+   ir_constant *const constant = result->constant_expression_value(ctx);
    return (constant != NULL) ? (ir_rvalue *) constant : (ir_rvalue *) result;
 }
 
@@ -967,6 +971,7 @@ static bool
 implicitly_convert_component(ir_rvalue * &from, const glsl_base_type to,
                              struct _mesa_glsl_parse_state *state)
 {
+   void *mem_ctx = state;
    ir_rvalue *result = from;
 
    if (to != from->type->base_type) {
@@ -985,7 +990,7 @@ implicitly_convert_component(ir_rvalue * &from, const glsl_base_type to,
       }
    }
 
-   ir_rvalue *const constant = result->constant_expression_value();
+   ir_rvalue *const constant = result->constant_expression_value(mem_ctx);
 
    if (constant != NULL)
       result = constant;
@@ -2154,7 +2159,7 @@ ast_function_expression::hir(exec_list *instructions,
             instructions->push_tail(
                new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
                                       matrix, NULL));
-            var->constant_value = matrix->constant_expression_value();
+            var->constant_value = matrix->constant_expression_value(ctx);
 
             /* Replace the matrix with dereferences of its columns. */
             for (int i = 0; i < matrix->type->matrix_columns; i++) {
@@ -2221,7 +2226,7 @@ ast_function_expression::hir(exec_list *instructions,
           * After doing so, track whether or not all the parameters to the
           * constructor are trivially constant valued expressions.
           */
-         ir_rvalue *const constant = result->constant_expression_value();
+         ir_rvalue *const constant = result->constant_expression_value(ctx);
 
          if (constant != NULL)
             result = constant;
diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp
index ee80605232..a07c0ecf95 100644
--- a/src/compiler/glsl/ast_to_hir.cpp
+++ b/src/compiler/glsl/ast_to_hir.cpp
@@ -1845,7 +1845,7 @@ ast_expression::do_hir(exec_list *instructions,
          error_emitted = true;
       }
 
-      ir_constant *cond_val = op[0]->constant_expression_value();
+      ir_constant *cond_val = op[0]->constant_expression_value(ctx);
 
       if (then_instructions.is_empty()
           && else_instructions.is_empty()
@@ -2229,6 +2229,8 @@ static unsigned
 process_array_size(exec_node *node,
                    struct _mesa_glsl_parse_state *state)
 {
+   void *mem_ctx = state;
+
    exec_list dummy_instructions;
 
    ast_node *array_size = exec_node_data(ast_node, node, link);
@@ -2261,7 +2263,7 @@ process_array_size(exec_node *node,
       return 0;
    }
 
-   ir_constant *const size = ir->constant_expression_value();
+   ir_constant *const size = ir->constant_expression_value(mem_ctx);
    if (size == NULL ||
        (state->is_version(120, 300) &&
         array_size->has_sequence_subexpression())) {
@@ -4326,6 +4328,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
                     exec_list *initializer_instructions,
                     struct _mesa_glsl_parse_state *state)
 {
+   void *mem_ctx = state;
    ir_rvalue *result = NULL;
 
    YYLTYPE initializer_loc = decl->initializer->get_location();
@@ -4460,7 +4463,9 @@ process_initializer(ir_variable *var, ast_declaration *decl,
           * GLSL ES 3.00.4 spec.  This is a new limitation for these GLSL
           * versions.
           */
-         ir_constant *constant_value = rhs->constant_expression_value();
+         ir_constant *constant_value =
+            rhs->constant_expression_value(mem_ctx);
+
          if (!constant_value ||
              (state->is_version(430, 300) &&
               decl->initializer->has_sequence_subexpression())) {
@@ -4520,7 +4525,7 @@ process_initializer(ir_variable *var, ast_declaration *decl,
       } else
          initializer_type = rhs->type;
 
-      var->constant_initializer = rhs->constant_expression_value();
+      var->constant_initializer = rhs->constant_expression_value(mem_ctx);
       var->data.has_initializer = true;
 
       /* If the declared variable is an unsized array, it must inherrit
@@ -6652,7 +6657,7 @@ ast_case_label::hir(exec_list *instructions,
        * comparison of cached test expression value to case label.
        */
       ir_rvalue *const label_rval = this->test_value->hir(instructions, state);
-      ir_constant *label_const = label_rval->constant_expression_value();
+      ir_constant *label_const = label_rval->constant_expression_value(ctx);
 
       if (!label_const) {
          YYLTYPE loc = this->test_value->get_location();
diff --git a/src/compiler/glsl/ast_type.cpp b/src/compiler/glsl/ast_type.cpp
index 63c026ad06..ee8697ba21 100644
--- a/src/compiler/glsl/ast_type.cpp
+++ b/src/compiler/glsl/ast_type.cpp
@@ -866,7 +866,9 @@ ast_layout_expression::process_qualifier_constant(struct _mesa_glsl_parse_state
 
       ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
 
-      ir_constant *const const_int = ir->constant_expression_value();
+      ir_constant *const const_int =
+         ir->constant_expression_value(ralloc_parent(ir));
+
       if (const_int == NULL || !const_int->type->is_integer()) {
          YYLTYPE loc = const_expression->get_location();
          _mesa_glsl_error(&loc, state, "%s must be an integral constant "
@@ -921,7 +923,8 @@ process_qualifier_constant(struct _mesa_glsl_parse_state *state,
 
    ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
 
-   ir_constant *const const_int = ir->constant_expression_value();
+   ir_constant *const const_int =
+      ir->constant_expression_value(ralloc_parent(ir));
    if (const_int == NULL || !const_int->type->is_integer()) {
       _mesa_glsl_error(loc, state, "%s must be an integral constant "
                        "expression", qual_indentifier);
diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h
index 170759abeb..e2b72772a2 100644
--- a/src/compiler/glsl/ir.h
+++ b/src/compiler/glsl/ir.h
@@ -229,7 +229,8 @@ public:
 
    virtual ir_visitor_status accept(ir_hierarchical_visitor *);
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    ir_rvalue *as_rvalue_to_saturate();
 
@@ -1170,7 +1171,9 @@ public:
     * given a list of the actual parameters and the variable context.
     * Returns NULL for non-built-ins.
     */
-   ir_constant *constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context);
+   ir_constant *constant_expression_value(void *mem_ctx,
+                                          exec_list *actual_parameters,
+                                          struct hash_table *variable_context);
 
    /**
     * Get the name of the function for which this is a signature
@@ -1273,7 +1276,8 @@ private:
     * Returns false if the expression is not constant, true otherwise,
     * and the value in *result if result is non-NULL.
     */
-   bool constant_expression_evaluate_expression_list(const struct exec_list &body,
+   bool constant_expression_evaluate_expression_list(void *mem_ctx,
+                                                     const struct exec_list &body,
 						     struct hash_table *variable_context,
 						     ir_constant **result);
 };
@@ -1429,7 +1433,8 @@ public:
 
    virtual ir_assignment *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -1535,7 +1540,8 @@ public:
     * If the expression cannot be constant folded, this method will return
     * \c NULL.
     */
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
     * This is only here for ir_reader to used for testing purposes please use
@@ -1616,7 +1622,8 @@ public:
 
    virtual ir_call *clone(void *mem_ctx, struct hash_table *ht) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -1838,7 +1845,8 @@ public:
 
    virtual ir_texture *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
@@ -1935,7 +1943,8 @@ public:
 
    virtual ir_swizzle *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
     * Construct an ir_swizzle from the textual representation.  Can fail.
@@ -2001,7 +2010,8 @@ public:
    virtual ir_dereference_variable *clone(void *mem_ctx,
 					  struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual bool equals(const ir_instruction *ir,
                        enum ir_node_type ignore = ir_type_unset) const;
@@ -2048,7 +2058,8 @@ public:
    virtual ir_dereference_array *clone(void *mem_ctx,
 				       struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual bool equals(const ir_instruction *ir,
                        enum ir_node_type ignore = ir_type_unset) const;
@@ -2085,7 +2096,8 @@ public:
    virtual ir_dereference_record *clone(void *mem_ctx,
 					struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    /**
     * Get the variable that is ultimately referenced by an r-value
@@ -2156,7 +2168,8 @@ public:
 
    virtual ir_constant *clone(void *mem_ctx, struct hash_table *) const;
 
-   virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL);
+   virtual ir_constant *constant_expression_value(void *mem_ctx,
+                                                  struct hash_table *variable_context = NULL);
 
    virtual void accept(ir_visitor *v)
    {
diff --git a/src/compiler/glsl/ir_constant_expression.cpp b/src/compiler/glsl/ir_constant_expression.cpp
index a493657d35..25b00a749f 100644
--- a/src/compiler/glsl/ir_constant_expression.cpp
+++ b/src/compiler/glsl/ir_constant_expression.cpp
@@ -509,7 +509,7 @@ constant_referenced(const ir_dereference *deref,
 
 
 ir_constant *
-ir_rvalue::constant_expression_value(struct hash_table *)
+ir_rvalue::constant_expression_value(void *mem_ctx, struct hash_table *)
 {
    assert(this->type->is_error());
    return NULL;
@@ -628,8 +628,11 @@ bitfield_insert(uint32_t base, uint32_t insert, int offset, int bits)
 }
 
 ir_constant *
-ir_expression::constant_expression_value(struct hash_table *variable_context)
+ir_expression::constant_expression_value(void *mem_ctx,
+                                         struct hash_table *variable_context)
 {
+   assert(mem_ctx);
+
    if (this->type->is_error())
       return NULL;
 
@@ -639,7 +642,9 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
    memset(&data, 0, sizeof(data));
 
    for (unsigned operand = 0; operand < this->num_operands; operand++) {
-      op[operand] = this->operands[operand]->constant_expression_value(variable_context);
+      op[operand] =
+         this->operands[operand]->constant_expression_value(mem_ctx,
+                                                            variable_context);
       if (!op[operand])
          return NULL;
    }
@@ -676,16 +681,14 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
       components = op[1]->type->components();
    }
 
-   void *ctx = ralloc_parent(this);
-
    /* Handle array operations here, rather than below. */
    if (op[0]->type->is_array()) {
       assert(op[1] != NULL && op[1]->type->is_array());
       switch (this->operation) {
       case ir_binop_all_equal:
-         return new(ctx) ir_constant(op[0]->has_value(op[1]));
+         return new(mem_ctx) ir_constant(op[0]->has_value(op[1]));
       case ir_binop_any_nequal:
-         return new(ctx) ir_constant(!op[0]->has_value(op[1]));
+         return new(mem_ctx) ir_constant(!op[0]->has_value(op[1]));
       default:
          break;
       }
@@ -694,12 +697,12 @@ ir_expression::constant_expression_value(struct hash_table *variable_context)
 
 #include "ir_expression_operation_constant.h"
 
-   return new(ctx) ir_constant(this->type, &data);
+   return new(mem_ctx) ir_constant(this->type, &data);
 }
 
 
 ir_constant *
-ir_texture::constant_expression_value(struct hash_table *)
+ir_texture::constant_expression_value(void *mem_ctx, struct hash_table *)
 {
    /* texture lookups aren't constant expressions */
    return NULL;
@@ -707,9 +710,13 @@ ir_texture::constant_expression_value(struct hash_table *)
 
 
 ir_constant *
-ir_swizzle::constant_expression_value(struct hash_table *variable_context)
+ir_swizzle::constant_expression_value(void *mem_ctx,
+                                      struct hash_table *variable_context)
 {
-   ir_constant *v = this->val->constant_expression_value(variable_context);
+   assert(mem_ctx);
+
+   ir_constant *v = this->val->constant_expression_value(mem_ctx,
+                                                         variable_context);
 
    if (v != NULL) {
       ir_constant_data data = { { 0 } };
@@ -729,17 +736,18 @@ ir_swizzle::constant_expression_value(struct hash_table *variable_context)
          }
       }
 
-      void *ctx = ralloc_parent(this);
-      return new(ctx) ir_constant(this->type, &data);
+      return new(mem_ctx) ir_constant(this->type, &data);
    }
    return NULL;
 }
 
 
 ir_constant *
-ir_dereference_variable::constant_expression_value(struct hash_table *variable_context)
+ir_dereference_variable::constant_expression_value(void *mem_ctx,
+                                                   struct hash_table *variable_context)
 {
    assert(var);
+   assert(mem_ctx);
 
    /* Give priority to the context hashtable, if it exists */
    if (variable_context) {
@@ -758,18 +766,20 @@ ir_dereference_variable::constant_expression_value(struct hash_table *variable_c
    if (!var->constant_value)
       return NULL;
 
-   return var->constant_value->clone(ralloc_parent(var), NULL);
+   return var->constant_value->clone(mem_ctx, NULL);
 }
 
 
 ir_constant *
-ir_dereference_array::constant_expression_value(struct hash_table *variable_context)
+ir_dereference_array::constant_expression_value(void *mem_ctx,
+                                                struct hash_table *variable_context)
 {
-   ir_constant *array = this->array->constant_expression_value(variable_context);
-   ir_constant *idx = this->array_index->constant_expression_value(variable_context);
+   assert(mem_ctx);
+
+   ir_constant *array = this->array->constant_expression_value(mem_ctx, variable_context);
+   ir_constant *idx = this->array_index->constant_expression_value(mem_ctx, variable_context);
 
    if ((array != NULL) && (idx != NULL)) {
-      void *ctx = ralloc_parent(this);
       if (array->type->is_matrix()) {
          /* Array access of a matrix results in a vector.
           */
@@ -809,14 +819,14 @@ ir_dereference_array::constant_expression_value(struct hash_table *variable_cont
             break;
          }
 
-         return new(ctx) ir_constant(column_type, &data);
+         return new(mem_ctx) ir_constant(column_type, &data);
       } else if (array->type->is_vector()) {
          const unsigned component = idx->value.u[0];
 
-         return new(ctx) ir_constant(array, component);
+         return new(mem_ctx) ir_constant(array, component);
       } else {
          const unsigned index = idx->value.u[0];
-         return array->get_array_element(index)->clone(ctx, NULL);
+         return array->get_array_element(index)->clone(mem_ctx, NULL);
       }
    }
    return NULL;
@@ -824,16 +834,19 @@ ir_dereference_array::constant_expression_value(struct hash_table *variable_cont
 
 
 ir_constant *
-ir_dereference_record::constant_expression_value(struct hash_table *)
+ir_dereference_record::constant_expression_value(void *mem_ctx,
+                                                 struct hash_table *)
 {
-   ir_constant *v = this->record->constant_expression_value();
+   assert(mem_ctx);
+
+   ir_constant *v = this->record->constant_expression_value(mem_ctx);
 
    return (v != NULL) ? v->get_record_field(this->field_idx) : NULL;
 }
 
 
 ir_constant *
-ir_assignment::constant_expression_value(struct hash_table *)
+ir_assignment::constant_expression_value(void *mem_ctx, struct hash_table *)
 {
    /* FINISHME: Handle CEs involving assignment (return RHS) */
    return NULL;
@@ -841,23 +854,30 @@ ir_assignment::constant_expression_value(struct hash_table *)
 
 
 ir_constant *
-ir_constant::constant_expression_value(struct hash_table *)
+ir_constant::constant_expression_value(void *mem_ctx, struct hash_table *)
 {
    return this;
 }
 
 
 ir_constant *
-ir_call::constant_expression_value(struct hash_table *variable_context)
+ir_call::constant_expression_value(void *mem_ctx, struct hash_table *variable_context)
 {
-   return this->callee->constant_expression_value(&this->actual_parameters, variable_context);
+   assert(mem_ctx);
+
+   return this->callee->constant_expression_value(mem_ctx,
+                                                  &this->actual_parameters,
+                                                  variable_context);
 }
 
 
-bool ir_function_signature::constant_expression_evaluate_expression_list(const struct exec_list &body,
+bool ir_function_signature::constant_expression_evaluate_expression_list(void *mem_ctx,
+                                                                        const struct exec_list &body,
                                                                          struct hash_table *variable_context,
                                                                          ir_constant **result)
 {
+   assert(mem_ctx);
+
    foreach_in_list(ir_instruction, inst, &body) {
       switch(inst->ir_type) {
 
@@ -872,7 +892,9 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
       case ir_type_assignment: {
          ir_assignment *asg = inst->as_assignment();
          if (asg->condition) {
-            ir_constant *cond = asg->condition->constant_expression_value(variable_context);
+            ir_constant *cond =
+               asg->condition->constant_expression_value(mem_ctx,
+                                                         variable_context);
             if (!cond)
                return false;
             if (!cond->get_bool_component(0))
@@ -885,7 +907,8 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
          if (!constant_referenced(asg->lhs, variable_context, store, offset))
             return false;
 
-         ir_constant *value = asg->rhs->constant_expression_value(variable_context);
+         ir_constant *value =
+            asg->rhs->constant_expression_value(mem_ctx, variable_context);
 
          if (!value)
             return false;
@@ -897,7 +920,9 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
          /* (return (expression)) */
       case ir_type_return:
          assert (result);
-         *result = inst->as_return()->value->constant_expression_value(variable_context);
+         *result =
+            inst->as_return()->value->constant_expression_value(mem_ctx,
+                                                                variable_context);
          return *result != NULL;
 
          /* (call name (ref) (params))*/
@@ -918,7 +943,8 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
                                   store, offset))
             return false;
 
-         ir_constant *value = call->constant_expression_value(variable_context);
+         ir_constant *value =
+            call->constant_expression_value(mem_ctx, variable_context);
 
          if(!value)
             return false;
@@ -931,14 +957,18 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
       case ir_type_if: {
          ir_if *iif = inst->as_if();
 
-         ir_constant *cond = iif->condition->constant_expression_value(variable_context);
+         ir_constant *cond =
+            iif->condition->constant_expression_value(mem_ctx,
+                                                      variable_context);
          if (!cond || !cond->type->is_boolean())
             return false;
 
          exec_list &branch = cond->get_bool_component(0) ? iif->then_instructions : iif->else_instructions;
 
          *result = NULL;
-         if (!constant_expression_evaluate_expression_list(branch, variable_context, result))
+         if (!constant_expression_evaluate_expression_list(mem_ctx, branch,
+                                                           variable_context,
+                                                           result))
             return false;
 
          /* If there was a return in the branch chosen, drop out now. */
@@ -962,8 +992,12 @@ bool ir_function_signature::constant_expression_evaluate_expression_list(const s
 }
 
 ir_constant *
-ir_function_signature::constant_expression_value(exec_list *actual_parameters, struct hash_table *variable_context)
+ir_function_signature::constant_expression_value(void *mem_ctx,
+                                                 exec_list *actual_parameters,
+                                                 struct hash_table *variable_context)
 {
+   assert(mem_ctx);
+
    const glsl_type *type = this->return_type;
    if (type == glsl_type::void_type)
       return NULL;
@@ -998,7 +1032,8 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters, s
    const exec_node *parameter_info = origin ? origin->parameters.get_head_raw() : parameters.get_head_raw();
 
    foreach_in_list(ir_rvalue, n, actual_parameters) {
-      ir_constant *constant = n->constant_expression_value(variable_context);
+      ir_constant *constant =
+         n->constant_expression_value(mem_ctx, variable_context);
       if (constant == NULL) {
          _mesa_hash_table_destroy(deref_hash, NULL);
          return NULL;
@@ -1016,8 +1051,9 @@ ir_function_signature::constant_expression_value(exec_list *actual_parameters, s
    /* Now run the builtin function until something non-constant
     * happens or we get the result.
     */
-   if (constant_expression_evaluate_expression_list(origin ? origin->body : body, deref_hash, &result) && result)
-      result = result->clone(ralloc_parent(this), NULL);
+   if (constant_expression_evaluate_expression_list(mem_ctx, origin ? origin->body : body, deref_hash, &result) &&
+       result)
+      result = result->clone(mem_ctx, NULL);
 
    _mesa_hash_table_destroy(deref_hash, NULL);
 
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 5f22eb36ae..9af7d8033a 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -428,7 +428,7 @@ public:
       if (!ir->variable_referenced()->type->contains_sampler())
          return visit_continue;
 
-      if (!ir->array_index->constant_expression_value()) {
+      if (!ir->array_index->constant_expression_value(ralloc_parent(ir))) {
          dynamic_sampler_array_indexing = true;
          return visit_stop;
       }
diff --git a/src/compiler/glsl/loop_controls.cpp b/src/compiler/glsl/loop_controls.cpp
index fa739afa24..895954fc2d 100644
--- a/src/compiler/glsl/loop_controls.cpp
+++ b/src/compiler/glsl/loop_controls.cpp
@@ -96,7 +96,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
    ir_expression *const div =
       new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment);
 
-   ir_constant *iter = div->constant_expression_value();
+   ir_constant *iter = div->constant_expression_value(mem_ctx);
    if (iter == NULL) {
       ralloc_free(mem_ctx);
       return -1;
@@ -108,7 +108,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
       ir_rvalue *cast =
          new(mem_ctx) ir_expression(op, glsl_type::int_type, iter, NULL);
 
-      iter = cast->constant_expression_value();
+      iter = cast->constant_expression_value(mem_ctx);
    }
 
    int iter_value = iter->get_int_component(0);
@@ -153,7 +153,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
       ir_expression *const cmp =
 	 new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
 
-      ir_constant *const cmp_result = cmp->constant_expression_value();
+      ir_constant *const cmp_result = cmp->constant_expression_value(mem_ctx);
 
       assert(cmp_result != NULL);
       if (cmp_result->get_bool_component(0)) {
diff --git a/src/compiler/glsl/loop_unroll.cpp b/src/compiler/glsl/loop_unroll.cpp
index bc377dff3b..dbb3fa2fa5 100644
--- a/src/compiler/glsl/loop_unroll.cpp
+++ b/src/compiler/glsl/loop_unroll.cpp
@@ -106,7 +106,7 @@ public:
       if (options->EmitNoIndirectSampler) {
          if ((ir->array->type->is_array() &&
               ir->array->type->contains_sampler()) &&
-             !ir->array_index->constant_expression_value()) {
+             !ir->array_index->constant_expression_value(ralloc_parent(ir))) {
             unsupported_variable_indexing = true;
             return visit_continue;
          }
diff --git a/src/compiler/glsl/lower_buffer_access.cpp b/src/compiler/glsl/lower_buffer_access.cpp
index 76d366c4b9..caffaf9bfb 100644
--- a/src/compiler/glsl/lower_buffer_access.cpp
+++ b/src/compiler/glsl/lower_buffer_access.cpp
@@ -404,7 +404,7 @@ lower_buffer_access::setup_buffer_access(void *mem_ctx,
             array_index = i2u(array_index);
 
          ir_constant *const_index =
-            array_index->constant_expression_value(NULL);
+            array_index->constant_expression_value(mem_ctx, NULL);
          if (const_index) {
             *const_offset += array_stride * const_index->value.u[0];
          } else {
diff --git a/src/compiler/glsl/lower_distance.cpp b/src/compiler/glsl/lower_distance.cpp
index ff04e9a26d..4d8d66b7cc 100644
--- a/src/compiler/glsl/lower_distance.cpp
+++ b/src/compiler/glsl/lower_distance.cpp
@@ -235,7 +235,8 @@ lower_distance_visitor::create_indices(ir_rvalue *old_index,
       old_index = new(ctx) ir_expression(ir_unop_u2i, old_index);
    }
 
-   ir_constant *old_index_constant = old_index->constant_expression_value();
+   ir_constant *old_index_constant =
+      old_index->constant_expression_value(ctx);
    if (old_index_constant) {
       /* gl_ClipDistance is being accessed via a constant index.  Don't bother
        * creating expressions to calculate the lowered indices.  Just create
diff --git a/src/compiler/glsl/lower_tess_level.cpp b/src/compiler/glsl/lower_tess_level.cpp
index 0a244f1439..b0965eb562 100644
--- a/src/compiler/glsl/lower_tess_level.cpp
+++ b/src/compiler/glsl/lower_tess_level.cpp
@@ -264,7 +264,8 @@ lower_tess_level_visitor::fix_lhs(ir_assignment *ir)
 
    ir_dereference *const new_lhs = (ir_dereference *) expr->operands[0];
 
-   ir_constant *old_index_constant = expr->operands[1]->constant_expression_value();
+   ir_constant *old_index_constant =
+      expr->operands[1]->constant_expression_value(mem_ctx);
    if (!old_index_constant) {
       ir->rhs = new(mem_ctx) ir_expression(ir_triop_vector_insert,
                                            expr->operands[0]->type,
diff --git a/src/compiler/glsl/lower_vec_index_to_swizzle.cpp b/src/compiler/glsl/lower_vec_index_to_swizzle.cpp
index b49255e05d..fdbad16a34 100644
--- a/src/compiler/glsl/lower_vec_index_to_swizzle.cpp
+++ b/src/compiler/glsl/lower_vec_index_to_swizzle.cpp
@@ -63,11 +63,12 @@ ir_vec_index_to_swizzle_visitor::handle_rvalue(ir_rvalue **rv)
    if (expr == NULL || expr->operation != ir_binop_vector_extract)
       return;
 
-   ir_constant *const idx = expr->operands[1]->constant_expression_value();
+   void *mem_ctx = ralloc_parent(expr);
+   ir_constant *const idx =
+      expr->operands[1]->constant_expression_value(mem_ctx);
    if (idx == NULL)
       return;
 
-   void *ctx = ralloc_parent(expr);
    this->progress = true;
 
    /* Page 40 of the GLSL 1.20 spec says:
@@ -87,7 +88,7 @@ ir_vec_index_to_swizzle_visitor::handle_rvalue(ir_rvalue **rv)
    const int i = CLAMP(idx->value.i[0], 0,
                        (int) expr->operands[0]->type->vector_elements - 1);
 
-   *rv = new(ctx) ir_swizzle(expr->operands[0], i, 0, 0, 0, 1);
+   *rv = new(mem_ctx) ir_swizzle(expr->operands[0], i, 0, 0, 0, 1);
 }
 
 bool
diff --git a/src/compiler/glsl/lower_vector_derefs.cpp b/src/compiler/glsl/lower_vector_derefs.cpp
index f7bf68db36..a83658d20f 100644
--- a/src/compiler/glsl/lower_vector_derefs.cpp
+++ b/src/compiler/glsl/lower_vector_derefs.cpp
@@ -61,8 +61,9 @@ vector_deref_visitor::visit_enter(ir_assignment *ir)
    ir_dereference *const new_lhs = (ir_dereference *) deref->array;
    ir->set_lhs(new_lhs);
 
-   ir_constant *old_index_constant = deref->array_index->constant_expression_value();
    void *mem_ctx = ralloc_parent(ir);
+   ir_constant *old_index_constant =
+      deref->array_index->constant_expression_value(mem_ctx);
    if (!old_index_constant) {
       ir->rhs = new(mem_ctx) ir_expression(ir_triop_vector_insert,
                                            new_lhs->type,
diff --git a/src/compiler/glsl/lower_vector_insert.cpp b/src/compiler/glsl/lower_vector_insert.cpp
index 26d31b03c1..ceaa5887c8 100644
--- a/src/compiler/glsl/lower_vector_insert.cpp
+++ b/src/compiler/glsl/lower_vector_insert.cpp
@@ -65,7 +65,8 @@ vector_insert_visitor::handle_rvalue(ir_rvalue **rv)
 
    factory.mem_ctx = ralloc_parent(expr);
 
-   ir_constant *const idx = expr->operands[2]->constant_expression_value();
+   ir_constant *const idx =
+      expr->operands[2]->constant_expression_value(factory.mem_ctx);
    if (idx != NULL) {
       /* Replace (vector_insert (vec) (scalar) (index)) with a dereference of
        * a new temporary.  The new temporary gets assigned as
diff --git a/src/compiler/glsl/opt_algebraic.cpp b/src/compiler/glsl/opt_algebraic.cpp
index 382b4617d1..31d1f74462 100644
--- a/src/compiler/glsl/opt_algebraic.cpp
+++ b/src/compiler/glsl/opt_algebraic.cpp
@@ -263,9 +263,11 @@ ir_algebraic_visitor::reassociate_constant(ir_expression *ir1, int const_index,
        ir2->operands[1]->type->is_matrix())
       return false;
 
+   void *mem_ctx = ralloc_parent(ir2);
+
    ir_constant *ir2_const[2];
-   ir2_const[0] = ir2->operands[0]->constant_expression_value();
-   ir2_const[1] = ir2->operands[1]->constant_expression_value();
+   ir2_const[0] = ir2->operands[0]->constant_expression_value(mem_ctx);
+   ir2_const[1] = ir2->operands[1]->constant_expression_value(mem_ctx);
 
    if (ir2_const[0] && ir2_const[1])
       return false;
@@ -333,7 +335,8 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
       if (ir->operands[i]->type->is_matrix())
 	 return ir;
 
-      op_const[i] = ir->operands[i]->constant_expression_value();
+      op_const[i] =
+         ir->operands[i]->constant_expression_value(ralloc_parent(ir));
       op_expr[i] = ir->operands[i]->as_expression();
    }
 
diff --git a/src/compiler/glsl/opt_constant_folding.cpp b/src/compiler/glsl/opt_constant_folding.cpp
index e72aec78f6..3b9394d135 100644
--- a/src/compiler/glsl/opt_constant_folding.cpp
+++ b/src/compiler/glsl/opt_constant_folding.cpp
@@ -100,7 +100,8 @@ ir_constant_fold(ir_rvalue **rvalue)
    if (var_ref)
       return false;
 
-   ir_constant *constant = (*rvalue)->constant_expression_value();
+   ir_constant *constant =
+      (*rvalue)->constant_expression_value(ralloc_parent(*rvalue));
    if (constant) {
       *rvalue = constant;
       return true;
@@ -189,7 +190,7 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir)
    }
 
    /* Next, see if the call can be replaced with an assignment of a constant */
-   ir_constant *const_val = ir->constant_expression_value();
+   ir_constant *const_val = ir->constant_expression_value(ralloc_parent(ir));
 
    if (const_val != NULL) {
       ir_assignment *assignment =
diff --git a/src/compiler/glsl/opt_constant_propagation.cpp b/src/compiler/glsl/opt_constant_propagation.cpp
index 4039512097..52e3937bb1 100644
--- a/src/compiler/glsl/opt_constant_propagation.cpp
+++ b/src/compiler/glsl/opt_constant_propagation.cpp
@@ -154,7 +154,8 @@ ir_constant_propagation_visitor::constant_folding(ir_rvalue **rvalue)
 
    ir_dereference_variable *var_ref = (*rvalue)->as_dereference_variable();
    if (var_ref && !var_ref->type->is_array()) {
-      ir_constant *constant = var_ref->constant_expression_value();
+      ir_constant *constant =
+         var_ref->constant_expression_value(ralloc_parent(var_ref));
       if (constant) {
          *rvalue = constant;
          this->progress = true;
diff --git a/src/compiler/glsl/opt_constant_variable.cpp b/src/compiler/glsl/opt_constant_variable.cpp
index 1c06ffe675..914b46004c 100644
--- a/src/compiler/glsl/opt_constant_variable.cpp
+++ b/src/compiler/glsl/opt_constant_variable.cpp
@@ -131,7 +131,7 @@ ir_constant_variable_visitor::visit_enter(ir_assignment *ir)
        var->data.mode == ir_var_shader_shared)
       return visit_continue;
 
-   constval = ir->rhs->constant_expression_value();
+   constval = ir->rhs->constant_expression_value(ralloc_parent(ir));
    if (!constval)
       return visit_continue;
 
diff --git a/src/compiler/glsl/opt_if_simplification.cpp b/src/compiler/glsl/opt_if_simplification.cpp
index e05f03190a..136ef87729 100644
--- a/src/compiler/glsl/opt_if_simplification.cpp
+++ b/src/compiler/glsl/opt_if_simplification.cpp
@@ -84,7 +84,8 @@ ir_if_simplification_visitor::visit_leave(ir_if *ir)
     * FINISHME: This can probably be done with some flags, but it would take
     * FINISHME: some work to get right.
     */
-   ir_constant *condition_constant = ir->condition->constant_expression_value();
+   ir_constant *condition_constant =
+      ir->condition->constant_expression_value(ralloc_parent(ir));
    if (condition_constant) {
       /* Move the contents of the one branch of the conditional
        * that matters out.
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 96b06621b5..e141ac4b71 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1543,7 +1543,7 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
    src_reg src;
    int element_size = type_size(ir->type);
 
-   index = ir->array_index->constant_expression_value();
+   index = ir->array_index->constant_expression_value(ralloc_parent(ir));
 
    ir->array->accept(this);
    src = this->result;
@@ -1657,8 +1657,10 @@ calc_sampler_offsets(struct gl_shader_program *prog, ir_dereference *deref,
    switch (deref->ir_type) {
    case ir_type_dereference_array: {
       ir_dereference_array *deref_arr = deref->as_dereference_array();
+
+      void *mem_ctx = ralloc_parent(deref_arr);
       ir_constant *array_index =
-         deref_arr->array_index->constant_expression_value();
+         deref_arr->array_index->constant_expression_value(mem_ctx);
 
       if (!array_index) {
 	 /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index bada7f4ea8..e8f7ecac92 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2835,7 +2835,7 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
    int element_size = type_size(ir->type);
    bool is_2D = false;
 
-   index = ir->array_index->constant_expression_value();
+   index = ir->array_index->constant_expression_value(ralloc_parent(ir));
 
    ir->array->accept(this);
    src = this->result;
@@ -4137,7 +4137,10 @@ glsl_to_tgsi_visitor::calc_deref_offsets(ir_dereference *tail,
 
    case ir_type_dereference_array: {
       ir_dereference_array *deref_arr = tail->as_dereference_array();
-      ir_constant *array_index = deref_arr->array_index->constant_expression_value();
+
+      void *mem_ctx = ralloc_parent(deref_arr);
+      ir_constant *array_index =
+         deref_arr->array_index->constant_expression_value(mem_ctx);
 
       if (!array_index) {
          st_src_reg temp_reg;




More information about the mesa-commit mailing list