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 efddbed6ea32c26836d51395475fe6419b00d3cb..3b30f6858e000dbe07adc6fc1e3cdf3794809aca 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 f7e90fba5b68bc7f9ba3216669766d71a0297b62..b121ab92107e418bb10304d4bb4ccb14c4ee64f5 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 ee8060523263b9dfb111e6cdebc93b7076dc5b8f..a07c0ecf953477720f0ac6317a91e83e04efb698 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 63c026ad06d3b94e87d5bf994040b572d7983d2d..ee8697ba21809c02b53968c29a5d8dfd38132ec3 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 170759abebd632660deed823f3e90cb709b5c2cb..e2b72772a26b8dc876f3270fee0e36b2ee564c4c 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 a493657d35c03829ea72a8e88816eb2ce81b6111..25b00a749f2d23537537749532d99c48bebece3c 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 5f22eb36ae6c5475f7095521bd3852368111c38e..9af7d8033aab505819dae39ec26e2b29fb2f37ad 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 fa739afa24ef9aa9387acd0c1242f8567c1c7537..895954fc2d141c78908a3122f4d89ed7681b75c6 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 bc377dff3b9b0ef1860ede39a1d7bb3866dc1e82..dbb3fa2fa5cfb3f478f062e16376b59624d493d2 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 76d366c4b967de7fed36fe0c95e293cf8516e0f5..caffaf9bfb229621e1b12f778c740bdc77590a66 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 ff04e9a26d8417a48198e5acf54c063ee08daf68..4d8d66b7cc62969feb4c52668539a8e4fe64785a 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 0a244f14398d62b70803399d68ac0386bb22b46b..b0965eb562dd8e6e176dae3a48f58623c20b3020 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 b49255e05d116e2ef8c37d05011d9c0cda1d0946..fdbad16a34f1d73a6b2bffdc5310a05365f458f1 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 f7bf68db3646be163d0ffd853c3b807f15576788..a83658d20f7113feee5e63d22b71f7ce73fb77d0 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 26d31b03c128991f6a336b1321e7019743d68502..ceaa5887c8a7c08c4954166c8b0c282c4b19df6b 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 382b4617d1b3b62f4a90df2cfa99a076af0a617c..31d1f744625410a9e5eb5401e619d4c73b242515 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 e72aec78f68618f3c32fba036490435d299de0e8..3b9394d1358ad7c6712e8e6e6863f1f0e2d84e1d 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 403951209740972ba0173bc54d8e9e00647c98e3..52e3937bb11ecfe685dcae6828dfae2f83dd767a 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 1c06ffe6750aa5460de5fb7b1ec8077a71108573..914b46004c15c354c49b552e312a2076fceee71c 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 e05f03190aa10e8d7035e4787b0e4e231b18be8b..136ef8772942025acf9a0efe600c84179382a444 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 96b06621b58c80d287e8205390ef2b63dc0594af..e141ac4b71521d0140f28dceacdb65a67cee16c2 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 bada7f4ea800466addad820aac5ecb419c86721e..e8f7ecac929db9033a952908d1bc19ab14c3aeb6 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;