[Mesa-dev] [RFC v1 14/38] glsl/nir: Use deref instructions instead of dref chains
Jason Ekstrand
jason at jlekstrand.net
Wed Mar 21 05:54:48 UTC 2018
---
src/compiler/glsl/glsl_to_nir.cpp | 239 +++++++++++++++-----------------------
1 file changed, 94 insertions(+), 145 deletions(-)
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 9da4526..be7a510 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -90,12 +90,10 @@ private:
nir_builder b;
nir_ssa_def *result; /* result of the expression tree last visited */
- nir_deref_var *evaluate_deref(nir_instr *mem_ctx, ir_instruction *ir);
+ nir_deref_instr *evaluate_deref(ir_instruction *ir);
- /* the head of the dereference chain we're creating */
- nir_deref_var *deref_head;
- /* the tail of the dereference chain we're creating */
- nir_deref *deref_tail;
+ /* most recent deref instruction created */
+ nir_deref_instr *deref;
nir_variable *var; /* variable created by ir_variable visitor */
@@ -198,8 +196,6 @@ nir_visitor::nir_visitor(nir_shader *shader)
this->result = NULL;
this->impl = NULL;
this->var = NULL;
- this->deref_head = NULL;
- this->deref_tail = NULL;
memset(&this->b, 0, sizeof(this->b));
}
@@ -209,12 +205,11 @@ nir_visitor::~nir_visitor()
_mesa_hash_table_destroy(this->overload_table, NULL);
}
-nir_deref_var *
-nir_visitor::evaluate_deref(nir_instr *mem_ctx, ir_instruction *ir)
+nir_deref_instr *
+nir_visitor::evaluate_deref(ir_instruction *ir)
{
ir->accept(this);
- ralloc_steal(mem_ctx, this->deref_head);
- return this->deref_head;
+ return this->deref;
}
static nir_constant *
@@ -627,76 +622,76 @@ nir_visitor::visit(ir_call *ir)
switch (ir->callee->intrinsic_id) {
case ir_intrinsic_atomic_counter_read:
- op = nir_intrinsic_atomic_counter_read_var;
+ op = nir_intrinsic_atomic_counter_read_deref;
break;
case ir_intrinsic_atomic_counter_increment:
- op = nir_intrinsic_atomic_counter_inc_var;
+ op = nir_intrinsic_atomic_counter_inc_deref;
break;
case ir_intrinsic_atomic_counter_predecrement:
- op = nir_intrinsic_atomic_counter_dec_var;
+ op = nir_intrinsic_atomic_counter_dec_deref;
break;
case ir_intrinsic_atomic_counter_add:
- op = nir_intrinsic_atomic_counter_add_var;
+ op = nir_intrinsic_atomic_counter_add_deref;
break;
case ir_intrinsic_atomic_counter_and:
- op = nir_intrinsic_atomic_counter_and_var;
+ op = nir_intrinsic_atomic_counter_and_deref;
break;
case ir_intrinsic_atomic_counter_or:
- op = nir_intrinsic_atomic_counter_or_var;
+ op = nir_intrinsic_atomic_counter_or_deref;
break;
case ir_intrinsic_atomic_counter_xor:
- op = nir_intrinsic_atomic_counter_xor_var;
+ op = nir_intrinsic_atomic_counter_xor_deref;
break;
case ir_intrinsic_atomic_counter_min:
- op = nir_intrinsic_atomic_counter_min_var;
+ op = nir_intrinsic_atomic_counter_min_deref;
break;
case ir_intrinsic_atomic_counter_max:
- op = nir_intrinsic_atomic_counter_max_var;
+ op = nir_intrinsic_atomic_counter_max_deref;
break;
case ir_intrinsic_atomic_counter_exchange:
- op = nir_intrinsic_atomic_counter_exchange_var;
+ op = nir_intrinsic_atomic_counter_exchange_deref;
break;
case ir_intrinsic_atomic_counter_comp_swap:
- op = nir_intrinsic_atomic_counter_comp_swap_var;
+ op = nir_intrinsic_atomic_counter_comp_swap_deref;
break;
case ir_intrinsic_image_load:
- op = nir_intrinsic_image_var_load;
+ op = nir_intrinsic_image_deref_load;
break;
case ir_intrinsic_image_store:
- op = nir_intrinsic_image_var_store;
+ op = nir_intrinsic_image_deref_store;
break;
case ir_intrinsic_image_atomic_add:
- op = nir_intrinsic_image_var_atomic_add;
+ op = nir_intrinsic_image_deref_atomic_add;
break;
case ir_intrinsic_image_atomic_min:
- op = nir_intrinsic_image_var_atomic_min;
+ op = nir_intrinsic_image_deref_atomic_min;
break;
case ir_intrinsic_image_atomic_max:
- op = nir_intrinsic_image_var_atomic_max;
+ op = nir_intrinsic_image_deref_atomic_max;
break;
case ir_intrinsic_image_atomic_and:
- op = nir_intrinsic_image_var_atomic_and;
+ op = nir_intrinsic_image_deref_atomic_and;
break;
case ir_intrinsic_image_atomic_or:
- op = nir_intrinsic_image_var_atomic_or;
+ op = nir_intrinsic_image_deref_atomic_or;
break;
case ir_intrinsic_image_atomic_xor:
- op = nir_intrinsic_image_var_atomic_xor;
+ op = nir_intrinsic_image_deref_atomic_xor;
break;
case ir_intrinsic_image_atomic_exchange:
- op = nir_intrinsic_image_var_atomic_exchange;
+ op = nir_intrinsic_image_deref_atomic_exchange;
break;
case ir_intrinsic_image_atomic_comp_swap:
- op = nir_intrinsic_image_var_atomic_comp_swap;
+ op = nir_intrinsic_image_deref_atomic_comp_swap;
break;
case ir_intrinsic_memory_barrier:
op = nir_intrinsic_memory_barrier;
break;
case ir_intrinsic_image_size:
- op = nir_intrinsic_image_var_size;
+ op = nir_intrinsic_image_deref_size;
break;
case ir_intrinsic_image_samples:
- op = nir_intrinsic_image_var_samples;
+ op = nir_intrinsic_image_deref_samples;
break;
case ir_intrinsic_ssbo_store:
op = nir_intrinsic_store_ssbo;
@@ -826,22 +821,22 @@ nir_visitor::visit(ir_call *ir)
nir_dest *dest = &instr->dest;
switch (op) {
- case nir_intrinsic_atomic_counter_read_var:
- case nir_intrinsic_atomic_counter_inc_var:
- case nir_intrinsic_atomic_counter_dec_var:
- case nir_intrinsic_atomic_counter_add_var:
- case nir_intrinsic_atomic_counter_min_var:
- case nir_intrinsic_atomic_counter_max_var:
- case nir_intrinsic_atomic_counter_and_var:
- case nir_intrinsic_atomic_counter_or_var:
- case nir_intrinsic_atomic_counter_xor_var:
- case nir_intrinsic_atomic_counter_exchange_var:
- case nir_intrinsic_atomic_counter_comp_swap_var: {
+ case nir_intrinsic_atomic_counter_read_deref:
+ case nir_intrinsic_atomic_counter_inc_deref:
+ case nir_intrinsic_atomic_counter_dec_deref:
+ case nir_intrinsic_atomic_counter_add_deref:
+ case nir_intrinsic_atomic_counter_min_deref:
+ case nir_intrinsic_atomic_counter_max_deref:
+ case nir_intrinsic_atomic_counter_and_deref:
+ case nir_intrinsic_atomic_counter_or_deref:
+ case nir_intrinsic_atomic_counter_xor_deref:
+ case nir_intrinsic_atomic_counter_exchange_deref:
+ case nir_intrinsic_atomic_counter_comp_swap_deref: {
/* Set the counter variable dereference. */
exec_node *param = ir->actual_parameters.get_head();
ir_dereference *counter = (ir_dereference *)param;
- instr->variables[0] = evaluate_deref(&instr->instr, counter);
+ instr->src[0] = nir_src_for_ssa(&evaluate_deref(counter)->dest.ssa);
param = param->get_next();
/* Set the intrinsic destination. */
@@ -851,13 +846,13 @@ nir_visitor::visit(ir_call *ir)
/* Set the intrinsic parameters. */
if (!param->is_tail_sentinel()) {
- instr->src[0] =
+ instr->src[1] =
nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
param = param->get_next();
}
if (!param->is_tail_sentinel()) {
- instr->src[1] =
+ instr->src[2] =
nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
param = param->get_next();
}
@@ -865,18 +860,18 @@ nir_visitor::visit(ir_call *ir)
nir_builder_instr_insert(&b, &instr->instr);
break;
}
- case nir_intrinsic_image_var_load:
- case nir_intrinsic_image_var_store:
- case nir_intrinsic_image_var_atomic_add:
- case nir_intrinsic_image_var_atomic_min:
- case nir_intrinsic_image_var_atomic_max:
- case nir_intrinsic_image_var_atomic_and:
- case nir_intrinsic_image_var_atomic_or:
- case nir_intrinsic_image_var_atomic_xor:
- case nir_intrinsic_image_var_atomic_exchange:
- case nir_intrinsic_image_var_atomic_comp_swap:
- case nir_intrinsic_image_var_samples:
- case nir_intrinsic_image_var_size: {
+ case nir_intrinsic_image_deref_load:
+ case nir_intrinsic_image_deref_store:
+ case nir_intrinsic_image_deref_atomic_add:
+ case nir_intrinsic_image_deref_atomic_min:
+ case nir_intrinsic_image_deref_atomic_max:
+ case nir_intrinsic_image_deref_atomic_and:
+ case nir_intrinsic_image_deref_atomic_or:
+ case nir_intrinsic_image_deref_atomic_xor:
+ case nir_intrinsic_image_deref_atomic_exchange:
+ case nir_intrinsic_image_deref_atomic_comp_swap:
+ case nir_intrinsic_image_deref_samples:
+ case nir_intrinsic_image_deref_size: {
nir_ssa_undef_instr *instr_undef =
nir_ssa_undef_instr_create(shader, 1, 32);
nir_builder_instr_insert(&b, &instr_undef->instr);
@@ -887,20 +882,20 @@ nir_visitor::visit(ir_call *ir)
const glsl_type *type =
image->variable_referenced()->type->without_array();
- instr->variables[0] = evaluate_deref(&instr->instr, image);
+ instr->src[0] = nir_src_for_ssa(&evaluate_deref(image)->dest.ssa);
param = param->get_next();
/* Set the intrinsic destination. */
if (ir->return_deref) {
unsigned num_components = ir->return_deref->type->vector_elements;
- if (instr->intrinsic == nir_intrinsic_image_var_size)
+ if (instr->intrinsic == nir_intrinsic_image_deref_size)
instr->num_components = num_components;
nir_ssa_dest_init(&instr->instr, &instr->dest,
num_components, 32, NULL);
}
- if (op == nir_intrinsic_image_var_size ||
- op == nir_intrinsic_image_var_samples) {
+ if (op == nir_intrinsic_image_deref_size ||
+ op == nir_intrinsic_image_deref_samples) {
nir_builder_instr_insert(&b, &instr->instr);
break;
}
@@ -919,29 +914,29 @@ nir_visitor::visit(ir_call *ir)
srcs[i] = &instr_undef->def;
}
- instr->src[0] = nir_src_for_ssa(nir_vec(&b, srcs, 4));
+ instr->src[1] = nir_src_for_ssa(nir_vec(&b, srcs, 4));
param = param->get_next();
/* Set the sample argument, which is undefined for single-sample
* images.
*/
if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS) {
- instr->src[1] =
+ instr->src[2] =
nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
param = param->get_next();
} else {
- instr->src[1] = nir_src_for_ssa(&instr_undef->def);
+ instr->src[2] = nir_src_for_ssa(&instr_undef->def);
}
/* Set the intrinsic parameters. */
if (!param->is_tail_sentinel()) {
- instr->src[2] =
+ instr->src[3] =
nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
param = param->get_next();
}
if (!param->is_tail_sentinel()) {
- instr->src[3] =
+ instr->src[4] =
nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
param = param->get_next();
}
@@ -1207,19 +1202,8 @@ nir_visitor::visit(ir_call *ir)
unreachable("not reached");
}
- if (ir->return_deref) {
- nir_intrinsic_instr *store_instr =
- nir_intrinsic_instr_create(shader, nir_intrinsic_store_var);
- store_instr->num_components = ir->return_deref->type->vector_elements;
- nir_intrinsic_set_write_mask(store_instr,
- (1 << store_instr->num_components) - 1);
-
- store_instr->variables[0] =
- evaluate_deref(&store_instr->instr, ir->return_deref);
- store_instr->src[0] = nir_src_for_ssa(&dest->ssa);
-
- nir_builder_instr_insert(&b, &store_instr->instr);
- }
+ if (ir->return_deref)
+ nir_store_deref(&b, evaluate_deref(ir->return_deref), &dest->ssa, ~0);
return;
}
@@ -1237,19 +1221,12 @@ nir_visitor::visit(ir_assignment *ir)
if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) &&
(ir->write_mask == (1 << num_components) - 1 || ir->write_mask == 0)) {
- /* We're doing a plain-as-can-be copy, so emit a copy_var */
- nir_intrinsic_instr *copy =
- nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var);
-
- copy->variables[0] = evaluate_deref(©->instr, ir->lhs);
- copy->variables[1] = evaluate_deref(©->instr, ir->rhs);
-
if (ir->condition) {
nir_push_if(&b, evaluate_rvalue(ir->condition));
- nir_builder_instr_insert(&b, ©->instr);
+ nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs));
nir_pop_if(&b, NULL);
} else {
- nir_builder_instr_insert(&b, ©->instr);
+ nir_copy_deref(&b, evaluate_deref(ir->lhs), evaluate_deref(ir->rhs));
}
return;
}
@@ -1257,7 +1234,7 @@ nir_visitor::visit(ir_assignment *ir)
assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector());
ir->lhs->accept(this);
- nir_deref_var *lhs_deref = this->deref_head;
+ nir_deref_instr *lhs_deref = this->deref;
nir_ssa_def *src = evaluate_rvalue(ir->rhs);
if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != 0) {
@@ -1274,19 +1251,12 @@ nir_visitor::visit(ir_assignment *ir)
src = nir_swizzle(&b, src, swiz, num_components, !supports_ints);
}
- nir_intrinsic_instr *store =
- nir_intrinsic_instr_create(this->shader, nir_intrinsic_store_var);
- store->num_components = ir->lhs->type->vector_elements;
- nir_intrinsic_set_write_mask(store, ir->write_mask);
- store->variables[0] = nir_deref_var_clone(lhs_deref, store);
- store->src[0] = nir_src_for_ssa(src);
-
if (ir->condition) {
nir_push_if(&b, evaluate_rvalue(ir->condition));
- nir_builder_instr_insert(&b, &store->instr);
+ nir_store_deref(&b, lhs_deref, src, ir->write_mask);
nir_pop_if(&b, NULL);
} else {
- nir_builder_instr_insert(&b, &store->instr);
+ nir_store_deref(&b, lhs_deref, src, ir->write_mask);
}
}
@@ -1353,13 +1323,7 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir)
* must emit a variable load.
*/
- nir_intrinsic_instr *load_instr =
- nir_intrinsic_instr_create(this->shader, nir_intrinsic_load_var);
- load_instr->num_components = ir->type->vector_elements;
- load_instr->variables[0] = this->deref_head;
- ralloc_steal(load_instr, load_instr->variables[0]);
- unsigned bit_size = glsl_get_bit_size(ir->type);
- add_instr(&load_instr->instr, ir->type->vector_elements, bit_size);
+ this->result = nir_load_deref(&b, this->deref);
}
return this->result;
@@ -1422,16 +1386,16 @@ nir_visitor::visit(ir_expression *ir)
deref->accept(this);
nir_intrinsic_op op;
- if (this->deref_head->var->data.mode == nir_var_shader_in) {
+ if (this->deref->mode == nir_var_shader_in) {
switch (ir->operation) {
case ir_unop_interpolate_at_centroid:
- op = nir_intrinsic_interp_var_at_centroid;
+ op = nir_intrinsic_interp_deref_at_centroid;
break;
case ir_binop_interpolate_at_offset:
- op = nir_intrinsic_interp_var_at_offset;
+ op = nir_intrinsic_interp_deref_at_offset;
break;
case ir_binop_interpolate_at_sample:
- op = nir_intrinsic_interp_var_at_sample;
+ op = nir_intrinsic_interp_deref_at_sample;
break;
default:
unreachable("Invalid interpolation intrinsic");
@@ -1443,18 +1407,17 @@ nir_visitor::visit(ir_expression *ir)
* sense, we'll just turn it into a load which will probably
* eventually end up as an SSA definition.
*/
- assert(this->deref_head->var->data.mode == nir_var_global);
- op = nir_intrinsic_load_var;
+ assert(this->deref->mode == nir_var_global);
+ op = nir_intrinsic_load_deref;
}
nir_intrinsic_instr *intrin = nir_intrinsic_instr_create(shader, op);
intrin->num_components = deref->type->vector_elements;
- intrin->variables[0] = this->deref_head;
- ralloc_steal(intrin, intrin->variables[0]);
+ intrin->src[0] = nir_src_for_ssa(&this->deref->dest.ssa);
- if (intrin->intrinsic == nir_intrinsic_interp_var_at_offset ||
- intrin->intrinsic == nir_intrinsic_interp_var_at_sample)
- intrin->src[0] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1]));
+ if (intrin->intrinsic == nir_intrinsic_interp_deref_at_offset ||
+ intrin->intrinsic == nir_intrinsic_interp_deref_at_sample)
+ intrin->src[1] = nir_src_for_ssa(evaluate_rvalue(ir->operands[1]));
unsigned bit_size = glsl_get_bit_size(deref->type);
add_instr(&intrin->instr, deref->type->vector_elements, bit_size);
@@ -2021,6 +1984,9 @@ nir_visitor::visit(ir_texture *ir)
if (ir->offset != NULL)
num_srcs++;
+ /* Add one for the texture deref */
+ num_srcs += 1;
+
nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs);
instr->op = op;
@@ -2045,9 +2011,11 @@ nir_visitor::visit(ir_texture *ir)
unreachable("not reached");
}
- instr->texture = evaluate_deref(&instr->instr, ir->sampler);
+ nir_deref_instr *sampler_deref = evaluate_deref(ir->sampler);
+ instr->src[0].src = nir_src_for_ssa(&sampler_deref->dest.ssa);
+ instr->src[0].src_type = nir_tex_src_texture_deref;
- unsigned src_number = 0;
+ unsigned src_number = 1;
if (ir->coordinate != NULL) {
instr->coord_components = ir->coordinate->type->vector_elements;
@@ -2146,8 +2114,7 @@ nir_visitor::visit(ir_constant *ir)
var->data.read_only = true;
var->constant_initializer = constant_copy(ir, var);
- this->deref_head = nir_deref_var_create(this->shader, var);
- this->deref_tail = &this->deref_head->deref;
+ this->deref = nir_build_deref_var(&b, var);
}
void
@@ -2158,9 +2125,7 @@ nir_visitor::visit(ir_dereference_variable *ir)
assert(entry);
nir_variable *var = (nir_variable *) entry->data;
- nir_deref_var *deref = nir_deref_var_create(this->shader, var);
- this->deref_head = deref;
- this->deref_tail = &deref->deref;
+ this->deref = nir_build_deref_var(&b, var);
}
void
@@ -2171,33 +2136,17 @@ nir_visitor::visit(ir_dereference_record *ir)
int field_index = ir->field_idx;
assert(field_index >= 0);
- nir_deref_struct *deref = nir_deref_struct_create(this->deref_tail, field_index);
- deref->deref.type = ir->type;
- this->deref_tail->child = &deref->deref;
- this->deref_tail = &deref->deref;
+ this->deref = nir_build_deref_struct(&b, this->deref, field_index);
}
void
nir_visitor::visit(ir_dereference_array *ir)
{
- nir_deref_array *deref = nir_deref_array_create(this->shader);
- deref->deref.type = ir->type;
-
- ir_constant *const_index = ir->array_index->as_constant();
- if (const_index != NULL) {
- deref->deref_array_type = nir_deref_array_type_direct;
- deref->base_offset = const_index->value.u[0];
- } else {
- deref->deref_array_type = nir_deref_array_type_indirect;
- deref->indirect =
- nir_src_for_ssa(evaluate_rvalue(ir->array_index));
- }
+ nir_ssa_def *index = evaluate_rvalue(ir->array_index);
ir->array->accept(this);
- this->deref_tail->child = &deref->deref;
- ralloc_steal(this->deref_tail, deref);
- this->deref_tail = &deref->deref;
+ this->deref = nir_build_deref_array(&b, this->deref, index);
}
void
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list