From 77f5221233ea427b622af46831feed438e0dd59e Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Thu, 10 Aug 2017 20:42:29 +1000 Subject: [PATCH] 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 --- 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 +- .../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 +- .../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 efddbed6ea3..3b30f6858e0 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 f7e90fba5b6..b121ab92107 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 ee806052326..a07c0ecf953 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 63c026ad06d..ee8697ba218 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 170759abebd..e2b72772a26 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 a493657d35c..25b00a749f2 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 5f22eb36ae6..9af7d8033aa 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 fa739afa24e..895954fc2d1 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 bc377dff3b9..dbb3fa2fa5c 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 76d366c4b96..caffaf9bfb2 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 ff04e9a26d8..4d8d66b7cc6 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 0a244f14398..b0965eb562d 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 b49255e05d1..fdbad16a34f 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 f7bf68db364..a83658d20f7 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 26d31b03c12..ceaa5887c8a 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 382b4617d1b..31d1f744625 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 e72aec78f68..3b9394d1358 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 40395120974..52e3937bb11 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 1c06ffe6750..914b46004c1 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 e05f03190aa..136ef877294 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 96b06621b58..e141ac4b715 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 bada7f4ea80..e8f7ecac929 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; -- 2.30.2