diff options
author | Timothy Arceri <[email protected]> | 2017-08-10 20:42:29 +1000 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2017-08-11 15:44:08 +1000 |
commit | 77f5221233ea427b622af46831feed438e0dd59e (patch) | |
tree | 01b42678b12c9fb954a4fb79f176d7f594498d46 /src/compiler/glsl/ir_constant_expression.cpp | |
parent | d4f79e995f180239c5d14e8493de9aac5a9e6833 (diff) |
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 <[email protected]>
Diffstat (limited to 'src/compiler/glsl/ir_constant_expression.cpp')
-rw-r--r-- | src/compiler/glsl/ir_constant_expression.cpp | 114 |
1 files changed, 75 insertions, 39 deletions
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); |