summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/ir_constant_expression.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2017-08-10 20:42:29 +1000
committerTimothy Arceri <[email protected]>2017-08-11 15:44:08 +1000
commit77f5221233ea427b622af46831feed438e0dd59e (patch)
tree01b42678b12c9fb954a4fb79f176d7f594498d46 /src/compiler/glsl/ir_constant_expression.cpp
parentd4f79e995f180239c5d14e8493de9aac5a9e6833 (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.cpp114
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);