glsl: pass mem_ctx to constant_expression_value(...) and friends
authorTimothy Arceri <tarceri@itsqueeze.com>
Thu, 10 Aug 2017 10:42:29 +0000 (20:42 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Fri, 11 Aug 2017 05:44:08 +0000 (15:44 +1000)
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@whitecape.org>
22 files changed:
src/compiler/glsl/ast_array_index.cpp
src/compiler/glsl/ast_function.cpp
src/compiler/glsl/ast_to_hir.cpp
src/compiler/glsl/ast_type.cpp
src/compiler/glsl/ir.h
src/compiler/glsl/ir_constant_expression.cpp
src/compiler/glsl/linker.cpp
src/compiler/glsl/loop_controls.cpp
src/compiler/glsl/loop_unroll.cpp
src/compiler/glsl/lower_buffer_access.cpp
src/compiler/glsl/lower_distance.cpp
src/compiler/glsl/lower_tess_level.cpp
src/compiler/glsl/lower_vec_index_to_swizzle.cpp
src/compiler/glsl/lower_vector_derefs.cpp
src/compiler/glsl/lower_vector_insert.cpp
src/compiler/glsl/opt_algebraic.cpp
src/compiler/glsl/opt_constant_folding.cpp
src/compiler/glsl/opt_constant_propagation.cpp
src/compiler/glsl/opt_constant_variable.cpp
src/compiler/glsl/opt_if_simplification.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index efddbed..3b30f68 100644 (file)
@@ -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";
index f7e90fb..b121ab9 100644 (file)
@@ -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;
index ee80605..a07c0ec 100644 (file)
@@ -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();
index 63c026a..ee8697b 100644 (file)
@@ -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);
index 170759a..e2b7277 100644 (file)
@@ -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)
    {
index a493657..25b00a7 100644 (file)
@@ -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);
 
index 5f22eb3..9af7d80 100644 (file)
@@ -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;
       }
index fa739af..895954f 100644 (file)
@@ -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)) {
index bc377df..dbb3fa2 100644 (file)
@@ -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;
          }
index 76d366c..caffaf9 100644 (file)
@@ -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 {
index ff04e9a..4d8d66b 100644 (file)
@@ -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
index 0a244f1..b0965eb 100644 (file)
@@ -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,
index b49255e..fdbad16 100644 (file)
@@ -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
index f7bf68d..a83658d 100644 (file)
@@ -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,
index 26d31b0..ceaa588 100644 (file)
@@ -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
index 382b461..31d1f74 100644 (file)
@@ -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();
    }
 
index e72aec7..3b9394d 100644 (file)
@@ -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 =
index 4039512..52e3937 100644 (file)
@@ -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;
index 1c06ffe..914b460 100644 (file)
@@ -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;
 
index e05f031..136ef87 100644 (file)
@@ -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.
index 96b0662..e141ac4 100644 (file)
@@ -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,
index bada7f4..e8f7eca 100644 (file)
@@ -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;