From: Götz Lindenmaier Date: Fri, 16 Jul 2004 19:19:07 +0000 (+0000) Subject: added a routine to compute array indicees. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=f6b661eaae85376166a897e8e7b3bf3a177f8524;p=libfirm added a routine to compute array indicees. [r3501] --- diff --git a/ir/tr/entity.c b/ir/tr/entity.c index 451eb5106..2f73c5c6b 100644 --- a/ir/tr/entity.c +++ b/ir/tr/entity.c @@ -767,6 +767,117 @@ int get_compound_ent_value_offset_bytes(entity *ent, int pos) { return offset >> 3; } + +static void init_index(type *arr) { + int init; + int dim = 0; + + assert(get_array_n_dimensions(arr) == 1); + + if (has_array_lower_bound(arr, dim)) + init = get_array_lower_bound_int(arr, 0) -1; + else + init = get_array_upper_bound_int(arr, 0) +1; + + set_entity_link(get_array_element_entity(arr), (void *)init); +} + + +static int get_next_index(entity *elem_ent) { + type *arr = get_entity_owner(elem_ent); + int next; + int dim = 0; + + assert(get_array_n_dimensions(arr) == 1); + + if (has_array_lower_bound(arr, dim)) { + next = (int)get_entity_link(elem_ent) +1; + if (has_array_upper_bound(arr, dim)) { + int upper = get_array_upper_bound_int(arr, dim); + if (next == upper) next = get_array_lower_bound_int(arr, dim); + } + } else { + next = (int)get_entity_link(elem_ent) -1; + if (has_array_lower_bound(arr, dim)) { + int upper = get_array_upper_bound_int(arr, dim); + if (next == upper) next = get_array_upper_bound_int(arr, dim); + } + } + + set_entity_link(elem_ent, (void *)next); + return next; +} + +/* Compute the array indicees in compound graph paths of initialized entities. + * + * All arrays must have fixed lower and upper bounds. One array can + * have an open bound. If there are several open bounds, we do + * nothing. There must be initializer elements for all array + * elements. Uses the link field in the array element entities. The + * array bounds must be representable as ints. + * + * (If the bounds are not representable as ints we have to represent + * the indicees as firm nodes. But the still we must be able to + * evaluate the index against the upper bound.) + */ +void compute_compound_ent_array_indicees(entity *ent) { + type *tp = get_entity_type(ent); + int i, n_vals; + entity *unknown_bound_entity = NULL; + + if (!is_compound_type(tp) || + (ent->variability == variability_uninitialized)) return ; + + n_vals = get_compound_ent_n_values(ent); + if (n_vals == 0) return; + + /* We can not compute the indicees if there is more than one array + with an unknown bound. For this remember the first entity that + represents such an array. It could be ent. */ + if (is_array_type(tp)) { + assert(get_array_n_dimensions(tp) == 1 && "other not implemented"); + int dim = 0; + if (!has_array_lower_bound(tp, dim) || !has_array_upper_bound(tp, dim)) + unknown_bound_entity = ent; + } + + /* Initialize the entity links to lower bound -1 and test all path elements + for known bounds. */ + for (i = 0; i < n_vals; ++i) { + compound_graph_path *path = get_compound_ent_value_path(ent, i); + int j, path_len = get_compound_graph_path_length(path); + for (j = 0; j < path_len; ++j) { + entity *node = get_compound_graph_path_node(path, j); + type *elem_tp = get_entity_type(node); + + if (is_array_type(elem_tp)) { + assert(get_array_n_dimensions(elem_tp) == 1 && "other not implemented"); + int dim = 0; + if (!has_array_lower_bound(elem_tp, dim) || !has_array_upper_bound(elem_tp, dim)) { + if (!unknown_bound_entity) unknown_bound_entity = node; + if (node != unknown_bound_entity) return; + } + + init_index(elem_tp); + } + } + } + + /* Finally compute the indicees ... */ + for (i = 0; i < n_vals; ++i) { + compound_graph_path *path = get_compound_ent_value_path(ent, i); + int j, path_len = get_compound_graph_path_length(path); + for (j = 0; j < path_len; ++j) { + entity *node = get_compound_graph_path_node(path, j); + type *owner_tp = get_entity_owner(node); + if (is_array_type(owner_tp)) + set_compound_graph_path_array_index (path, j, get_next_index(node)); + } + } + +} + + static int *resize (int *buf, int new_size) { int *new_buf = (int *)calloc(new_size, 4); memcpy(new_buf, buf, new_size>1); @@ -1061,9 +1172,9 @@ entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) { res = resolve_ent_polymorphy2(dynamic_class, static_ent); if (!res) { - fprintf(stderr, " Could not find entity "); DDME(static_ent); - fprintf(stderr, " in "); DDMT(dynamic_class); - fprintf(stderr, "\n"); + printf(" Could not find entity "); DDME(static_ent); + printf(" in "); DDMT(dynamic_class); + printf("\n"); dump_entity(static_ent); dump_type(get_entity_owner(static_ent)); dump_type(dynamic_class); @@ -1082,36 +1193,36 @@ entity *resolve_ent_polymorphy(type *dynamic_class, entity* static_ent) { #if 1 || DEBUG_libfirm int dump_node_opcode(FILE *F, ir_node *n); /* from irdump.c */ -#define X(a) case a: fprintf(stderr, #a); break +#define X(a) case a: printf(#a); break void dump_entity (entity *ent) { int i, j; type *owner = get_entity_owner(ent); type *type = get_entity_type(ent); assert(ent && ent->kind == k_entity); - fprintf(stderr, "entity %s (%ld)\n", get_entity_name(ent), get_entity_nr(ent)); - fprintf(stderr, " type: %s (%ld)\n", get_type_name(type), get_type_nr(type)); - fprintf(stderr, " owner: %s (%ld)\n", get_type_name(owner), get_type_nr(owner)); + printf("entity %s (%ld)\n", get_entity_name(ent), get_entity_nr(ent)); + printf(" type: %s (%ld)\n", get_type_name(type), get_type_nr(type)); + printf(" owner: %s (%ld)\n", get_type_name(owner), get_type_nr(owner)); if (get_entity_n_overwrites(ent) > 0) { - fprintf(stderr, " overwrites:\n"); + printf(" overwrites:\n"); for (i = 0; i < get_entity_n_overwrites(ent); ++i) { entity *ov = get_entity_overwrites(ent, i); - fprintf(stderr, " %d: %s of class %s\n", i, get_entity_name(ov), get_type_name(get_entity_owner(ov))); + printf(" %d: %s of class %s\n", i, get_entity_name(ov), get_type_name(get_entity_owner(ov))); } } else { - fprintf(stderr, " Does not overwrite other entities. \n"); + printf(" Does not overwrite other entities. \n"); } if (get_entity_n_overwrittenby(ent) > 0) { - fprintf(stderr, " overwritten by:\n"); + printf(" overwritten by:\n"); for (i = 0; i < get_entity_n_overwrittenby(ent); ++i) { entity *ov = get_entity_overwrittenby(ent, i); - fprintf(stderr, " %d: %s of class %s\n", i, get_entity_name(ov), get_type_name(get_entity_owner(ov))); + printf(" %d: %s of class %s\n", i, get_entity_name(ov), get_type_name(get_entity_owner(ov))); } } else { - fprintf(stderr, " Is not overwriten by other entities. \n"); + printf(" Is not overwriten by other entities. \n"); } - fprintf(stderr, " allocation: "); + printf(" allocation: "); switch (get_entity_allocation(ent)) { X(allocation_dynamic); X(allocation_automatic); @@ -1119,14 +1230,14 @@ void dump_entity (entity *ent) { X(allocation_parameter); } - fprintf(stderr, "\n visibility: "); + printf("\n visibility: "); switch (get_entity_visibility(ent)) { X(visibility_local); X(visibility_external_visible); X(visibility_external_allocated); } - fprintf(stderr, "\n variability: "); + printf("\n variability: "); switch (get_entity_variability(ent)) { X(variability_uninitialized); X(variability_initialized); @@ -1136,45 +1247,45 @@ void dump_entity (entity *ent) { if (get_entity_variability(ent) != variability_uninitialized) { if (is_atomic_entity(ent)) { - fprintf(stderr, "\n atomic value: "); + printf("\n atomic value: "); dump_node_opcode(stdout, get_atomic_ent_value(ent)); } else { - fprintf(stderr, "\n compound values:"); + printf("\n compound values:"); for (i = 0; i < get_compound_ent_n_values(ent); ++i) { compound_graph_path *path = get_compound_ent_value_path(ent, i); entity *ent0 = get_compound_graph_path_node(path, 0); - fprintf(stderr, "\n %3d ", get_entity_offset_bits(ent0)); + printf("\n %3d ", get_entity_offset_bits(ent0)); if (get_type_state(type) == layout_fixed) - fprintf(stderr, "(%3d) ", get_compound_ent_value_offset_bits(ent, i)); - fprintf(stderr, "%s", get_entity_name(ent0)); + printf("(%3d) ", get_compound_ent_value_offset_bits(ent, i)); + printf("%s", get_entity_name(ent0)); for (j = 0; j < get_compound_graph_path_length(path); ++j) { entity *node = get_compound_graph_path_node(path, j); - fprintf(stderr, ".%s", get_entity_name(node)); + printf(".%s", get_entity_name(node)); if (is_array_type(get_entity_owner(node))) - fprintf(stderr, "[%d]", get_compound_graph_path_array_index(path, j)); + printf("[%d]", get_compound_graph_path_array_index(path, j)); } - fprintf(stderr, "\t = "); + printf("\t = "); dump_node_opcode(stdout, get_compound_ent_value(ent, i)); } } } - fprintf(stderr, "\n volatility: "); + printf("\n volatility: "); switch (get_entity_volatility(ent)) { X(volatility_non_volatile); X(volatility_is_volatile); } - fprintf(stderr, "\n peculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent))); - fprintf(stderr, "\n ld_name: %s", ent->ld_name ? get_entity_ld_name(ent) : "no yet set"); - fprintf(stderr, "\n offset: %d", get_entity_offset_bits(ent)); + printf("\n peculiarity: %s", get_peculiarity_string(get_entity_peculiarity(ent))); + printf("\n ld_name: %s", ent->ld_name ? get_entity_ld_name(ent) : "no yet set"); + printf("\n offset: %d", get_entity_offset_bits(ent)); if (is_method_type(get_entity_type(ent))) { if (get_entity_irg(ent)) /* can be null */ { printf("\n irg = %ld", get_irg_graph_nr(get_entity_irg(ent))); } else { printf("\n irg = NULL"); } } - fprintf(stderr, "\n\n"); + printf("\n\n"); } #undef X #else /* DEBUG_libfirm */ diff --git a/ir/tr/entity.h b/ir/tr/entity.h index 57ad9a604..344efea19 100644 --- a/ir/tr/entity.h +++ b/ir/tr/entity.h @@ -427,6 +427,18 @@ int get_compound_ent_value_offset_bits(entity *ent, int pos); */ int get_compound_ent_value_offset_bytes(entity *ent, int pos); +/** Compute the array indicees in compound graph paths of initialized entities. + * + * All arrays must have fixed lower and upper bounds. One array can + * have an open upper bound. If there are several open bounds, we do + * nothing. There must be initializer elements for all array + * elements. Uses the link field in the array element entities. The + * array bounds must be representable as ints. + * + * @param ent Any entity. + */ +void compute_compound_ent_array_indicees(entity *ent); + /** Sort the values of the compound entity by their overall offset. * * This requires that the layout of all concerned types is fixed. diff --git a/ir/tr/trvrfy.c b/ir/tr/trvrfy.c index 30d3ceafe..b84fc04ee 100644 --- a/ir/tr/trvrfy.c +++ b/ir/tr/trvrfy.c @@ -60,6 +60,17 @@ static int check_class(type *tp) { return 0; } +/** + * Check an array. + */ +static int check_array(type *tp) { + int i, n_dim = get_array_n_dimensions(tp); + for (i = 0; i < n_dim; ++i) + assert(has_array_lower_bound(tp, i) || has_array_upper_bound(tp, i)); + + return 0; +} + /** * Checks a type. * @@ -69,6 +80,8 @@ static int check_type(type *tp) { switch (get_type_tpop_code(tp)) { case tpo_class: return check_class(tp); + case tpo_array: + return check_array(tp); default: break; } return 0; diff --git a/ir/tr/type.c b/ir/tr/type.c index dd517314d..3e7c3bce9 100644 --- a/ir/tr/type.c +++ b/ir/tr/type.c @@ -1384,7 +1384,7 @@ ir_node * get_array_upper_bound (type *array, int dimension) { assert(array && (array->type_op == type_array)); return array->attr.aa.upper_bound[dimension]; } -long get_array_lower_upper_int (type *array, int dimension) { +long get_array_upper_bound_int (type *array, int dimension) { ir_node *node; assert(array && (array->type_op == type_array)); node = array->attr.aa.upper_bound[dimension]; diff --git a/ir/tr/type.h b/ir/tr/type.h index bbea8073e..1bd30ca0e 100644 --- a/ir/tr/type.h +++ b/ir/tr/type.h @@ -705,6 +705,7 @@ type *new_type_array (ident *name, int n_dimensions, * Initializes order to the order of the dimensions. * The entity for array elements is built automatically. * Set dimension sizes after call to constructor with set_* routines. + * A legal array type must have at least one dimension set. */ type *new_d_type_array (ident *name, int n_dimensions, type *element_type, dbg_info* db);