glsl: Unify ir_constant::const_elements and ::components

There was no reason to treat array types and record types differently.
Unifying them saves a bunch of code and saves a few bytes in every
ir_constant.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Reviewed-by: Elie Tournier <elie.tournier@collabora.com>
This commit is contained in:
Ian Romanick
2017-09-07 19:23:51 -07:00
parent 0e88153e99
commit 9ac8fece63
8 changed files with 28 additions and 115 deletions

View File

@@ -285,17 +285,6 @@ constant_copy(ir_constant *ir, void *mem_ctx)
break; break;
case GLSL_TYPE_STRUCT: case GLSL_TYPE_STRUCT:
ret->elements = ralloc_array(mem_ctx, nir_constant *,
ir->type->length);
ret->num_elements = ir->type->length;
i = 0;
foreach_in_list(ir_constant, field, &ir->components) {
ret->elements[i] = constant_copy(field, mem_ctx);
i++;
}
break;
case GLSL_TYPE_ARRAY: case GLSL_TYPE_ARRAY:
ret->elements = ralloc_array(mem_ctx, nir_constant *, ret->elements = ralloc_array(mem_ctx, nir_constant *,
ir->type->length); ir->type->length);

View File

@@ -759,7 +759,12 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
assert(type->is_scalar() || type->is_vector() || type->is_matrix() assert(type->is_scalar() || type->is_vector() || type->is_matrix()
|| type->is_record() || type->is_array()); || type->is_record() || type->is_array());
if (type->is_array()) { /* If the constant is a record, the types of each of the entries in
* value_list must be a 1-for-1 match with the structure components. Each
* entry must also be a constant. Just move the nodes from the value_list
* to the list in the ir_constant.
*/
if (type->is_array() || type->is_record()) {
this->const_elements = ralloc_array(this, ir_constant *, type->length); this->const_elements = ralloc_array(this, ir_constant *, type->length);
unsigned i = 0; unsigned i = 0;
foreach_in_list(ir_constant, value, value_list) { foreach_in_list(ir_constant, value, value_list) {
@@ -770,20 +775,6 @@ ir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
return; return;
} }
/* If the constant is a record, the types of each of the entries in
* value_list must be a 1-for-1 match with the structure components. Each
* entry must also be a constant. Just move the nodes from the value_list
* to the list in the ir_constant.
*/
/* FINISHME: Should there be some type checking and / or assertions here? */
/* FINISHME: Should the new constant take ownership of the nodes from
* FINISHME: value_list, or should it make copies?
*/
if (type->is_record()) {
value_list->move_nodes_to(& this->components);
return;
}
for (unsigned i = 0; i < 16; i++) { for (unsigned i = 0; i < 16; i++) {
this->value.u[i] = 0; this->value.u[i] = 0;
} }
@@ -931,9 +922,11 @@ ir_constant::zero(void *mem_ctx, const glsl_type *type)
} }
if (type->is_record()) { if (type->is_record()) {
c->const_elements = ralloc_array(c, ir_constant *, type->length);
for (unsigned i = 0; i < type->length; i++) { for (unsigned i = 0; i < type->length; i++) {
ir_constant *comp = ir_constant::zero(mem_ctx, type->fields.structure[i].type); c->const_elements[i] =
c->components.push_tail(comp); ir_constant::zero(mem_ctx, type->fields.structure[i].type);
} }
} }
@@ -1106,24 +1099,10 @@ ir_constant::get_array_element(unsigned i) const
ir_constant * ir_constant *
ir_constant::get_record_field(int idx) ir_constant::get_record_field(int idx)
{ {
if (idx < 0) assert(this->type->is_record());
return NULL; assert(idx >= 0 && idx < this->type->length);
if (this->components.is_empty()) return const_elements[idx];
return NULL;
exec_node *node = this->components.get_head_raw();
for (int i = 0; i < idx; i++) {
node = node->next;
/* If the end of the list is encountered before the element matching the
* requested field is found, return NULL.
*/
if (node->is_tail_sentinel())
return NULL;
}
return (ir_constant *) node;
} }
void void
@@ -1169,15 +1148,7 @@ ir_constant::copy_offset(ir_constant *src, int offset)
break; break;
} }
case GLSL_TYPE_STRUCT: { case GLSL_TYPE_STRUCT:
assert (src->type == this->type);
this->components.make_empty();
foreach_in_list(ir_constant, orig, &src->components) {
this->components.push_tail(orig->clone(this, NULL));
}
break;
}
case GLSL_TYPE_ARRAY: { case GLSL_TYPE_ARRAY: {
assert (src->type == this->type); assert (src->type == this->type);
for (unsigned i = 0; i < this->type->length; i++) { for (unsigned i = 0; i < this->type->length; i++) {
@@ -1241,7 +1212,7 @@ ir_constant::has_value(const ir_constant *c) const
if (this->type != c->type) if (this->type != c->type)
return false; return false;
if (this->type->is_array()) { if (this->type->is_array() || this->type->is_record()) {
for (unsigned i = 0; i < this->type->length; i++) { for (unsigned i = 0; i < this->type->length; i++) {
if (!this->const_elements[i]->has_value(c->const_elements[i])) if (!this->const_elements[i]->has_value(c->const_elements[i]))
return false; return false;
@@ -1249,26 +1220,6 @@ ir_constant::has_value(const ir_constant *c) const
return true; return true;
} }
if (this->type->is_record()) {
const exec_node *a_node = this->components.get_head_raw();
const exec_node *b_node = c->components.get_head_raw();
while (!a_node->is_tail_sentinel()) {
assert(!b_node->is_tail_sentinel());
const ir_constant *const a_field = (ir_constant *) a_node;
const ir_constant *const b_field = (ir_constant *) b_node;
if (!a_field->has_value(b_field))
return false;
a_node = a_node->next;
b_node = b_node->next;
}
return true;
}
for (unsigned i = 0; i < this->type->components(); i++) { for (unsigned i = 0; i < this->type->components(); i++) {
switch (this->type->base_type) { switch (this->type->base_type) {
case GLSL_TYPE_UINT: case GLSL_TYPE_UINT:
@@ -1969,15 +1920,10 @@ steal_memory(ir_instruction *ir, void *new_ctx)
/* The components of aggregate constants are not visited by the normal /* The components of aggregate constants are not visited by the normal
* visitor, so steal their values by hand. * visitor, so steal their values by hand.
*/ */
if (constant != NULL) { if (constant != NULL &&
if (constant->type->is_record()) { (constant->type->is_array() || constant->type->is_record())) {
foreach_in_list(ir_constant, field, &constant->components) { for (unsigned int i = 0; i < constant->type->length; i++) {
steal_memory(field, ir); steal_memory(constant->const_elements[i], ir);
}
} else if (constant->type->is_array()) {
for (unsigned int i = 0; i < constant->type->length; i++) {
steal_memory(constant->const_elements[i], ir);
}
} }
} }

View File

@@ -2262,12 +2262,9 @@ public:
*/ */
union ir_constant_data value; union ir_constant_data value;
/* Array elements */ /* Array elements and structure fields */
ir_constant **const_elements; ir_constant **const_elements;
/* Structure fields */
exec_list components;
private: private:
/** /**
* Parameterless constructor only used by the clone method * Parameterless constructor only used by the clone method

View File

@@ -345,21 +345,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
case GLSL_TYPE_IMAGE: case GLSL_TYPE_IMAGE:
return new(mem_ctx) ir_constant(this->type, &this->value); return new(mem_ctx) ir_constant(this->type, &this->value);
case GLSL_TYPE_STRUCT: { case GLSL_TYPE_STRUCT:
ir_constant *c = new(mem_ctx) ir_constant;
c->type = this->type;
for (const exec_node *node = this->components.get_head_raw()
; !node->is_tail_sentinel()
; node = node->next) {
ir_constant *const orig = (ir_constant *) node;
c->components.push_tail(orig->clone(mem_ctx, NULL));
}
return c;
}
case GLSL_TYPE_ARRAY: { case GLSL_TYPE_ARRAY: {
ir_constant *c = new(mem_ctx) ir_constant; ir_constant *c = new(mem_ctx) ir_constant;

View File

@@ -469,13 +469,10 @@ void ir_print_visitor::visit(ir_constant *ir)
for (unsigned i = 0; i < ir->type->length; i++) for (unsigned i = 0; i < ir->type->length; i++)
ir->get_array_element(i)->accept(this); ir->get_array_element(i)->accept(this);
} else if (ir->type->is_record()) { } else if (ir->type->is_record()) {
ir_constant *value = (ir_constant *) ir->components.get_head();
for (unsigned i = 0; i < ir->type->length; i++) { for (unsigned i = 0; i < ir->type->length; i++) {
fprintf(f, "(%s ", ir->type->fields.structure[i].name); fprintf(f, "(%s ", ir->type->fields.structure[i].name);
value->accept(this); ir->get_record_field(i)->accept(this);
fprintf(f, ")"); fprintf(f, ")");
value = (ir_constant *) value->next;
} }
} else { } else {
for (unsigned i = 0; i < ir->type->components(); i++) { for (unsigned i = 0; i < ir->type->components(); i++) {

View File

@@ -206,17 +206,13 @@ set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
{ {
const glsl_type *t_without_array = type->without_array(); const glsl_type *t_without_array = type->without_array();
if (type->is_record()) { if (type->is_record()) {
ir_constant *field_constant;
field_constant = (ir_constant *)val->components.get_head();
for (unsigned int i = 0; i < type->length; i++) { for (unsigned int i = 0; i < type->length; i++) {
const glsl_type *field_type = type->fields.structure[i].type; const glsl_type *field_type = type->fields.structure[i].type;
const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name, const char *field_name = ralloc_asprintf(mem_ctx, "%s.%s", name,
type->fields.structure[i].name); type->fields.structure[i].name);
set_uniform_initializer(mem_ctx, prog, field_name, set_uniform_initializer(mem_ctx, prog, field_name,
field_type, field_constant, boolean_true); field_type, val->get_record_field(i),
field_constant = (ir_constant *)field_constant->next; boolean_true);
} }
return; return;
} else if (t_without_array->is_record() || } else if (t_without_array->is_record() ||

View File

@@ -1913,7 +1913,8 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
src_reg temp_base = get_temp(ir->type); src_reg temp_base = get_temp(ir->type);
dst_reg temp = dst_reg(temp_base); dst_reg temp = dst_reg(temp_base);
foreach_in_list(ir_constant, field_value, &ir->components) { for (i = 0; i < ir->type->length; i++) {
ir_constant *const field_value = ir->get_record_field(i);
int size = type_size(field_value->type); int size = type_size(field_value->type);
assert(size > 0); assert(size > 0);

View File

@@ -3045,7 +3045,8 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
st_src_reg temp_base = get_temp(ir->type); st_src_reg temp_base = get_temp(ir->type);
st_dst_reg temp = st_dst_reg(temp_base); st_dst_reg temp = st_dst_reg(temp_base);
foreach_in_list(ir_constant, field_value, &ir->components) { for (i = 0; i < ir->type->length; i++) {
ir_constant *const field_value = ir->get_record_field(i);
int size = type_size(field_value->type); int size = type_size(field_value->type);
assert(size > 0); assert(size > 0);