Commit 9d78d6c9 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

tr: Simplify array types.

The length is now set on creation.
Neither length nor element type can be changed later on.
parent 8572a6c5
......@@ -1370,24 +1370,15 @@ FIRM_API int is_Method_type(const ir_type *method);
* @{
*/
/** Create a new type array. */
FIRM_API ir_type *new_type_array(ir_type *element_type);
/** Sets the size (number of elements) of the array, i.e. [0,size[ */
FIRM_API void set_array_size(ir_type *array, ir_node *size);
/** Sets array size of @p array to @p size elements. */
FIRM_API void set_array_size_int(ir_type *array, unsigned size);
/**
* Create a new type array with the given number of elements.
*
* 0 elements designates an array of unknown length.
*/
FIRM_API ir_type *new_type_array(ir_type *element_type, unsigned n_elements);
/** returns true if lower size != Unknown */
FIRM_API int has_array_size(const ir_type *array);
/** Returns the size (number of elements) of an array. */
FIRM_API ir_node *get_array_size(const ir_type *array);
/** Works only if bound is Const node with tarval that can be converted to long. */
FIRM_API unsigned get_array_size_int(const ir_type *array);
/** Sets the array element type. */
FIRM_API void set_array_element_type(ir_type *array, ir_type *tp);
FIRM_API unsigned get_array_size(const ir_type *array);
/** Returns the array element type. */
FIRM_API ir_type *get_array_element_type(const ir_type *array);
......
......@@ -613,8 +613,8 @@ static void emit_array_type(const ir_type *type)
emit_uleb128(abbrev_array_type);
emit_type_address(element_type);
if (has_array_size(type)) {
unsigned bound = get_array_size_int(type);
unsigned const bound = get_array_size(type);
if (bound != 0) {
emit_uleb128(abbrev_subrange_type);
emit_uleb128(bound);
}
......
......@@ -1561,7 +1561,7 @@ static aggregate_spec_t const *decide_compound_ret(ir_type const *type)
unsigned size = get_type_size(type);
if (is_Array_type(type)) {
/* This is used for returning complex float numbers */
if (size == 8 && has_array_size(type) && get_array_size_int(type) == 2
if (size == 8 && get_array_size(type) == 2
&& is_float(get_array_element_type(type))) {
return &iu4_iu4_spec;
}
......
......@@ -496,16 +496,7 @@ static ir_node *gen_be_Relocation(ir_node *node)
static ir_type *make_array_type(ir_type *tp)
{
unsigned alignment = get_type_alignment(tp);
unsigned size = get_type_size(tp);
ir_type *res = new_type_array(tp);
set_type_alignment(res, alignment);
set_array_size_int(res, 2);
if (alignment > size)
size = alignment;
set_type_size(res, 2 * size);
set_type_state(res, layout_fixed);
return res;
return new_type_array(tp, 2);
}
/**
......
......@@ -1192,35 +1192,10 @@ static void dump_node_with_edges(ir_node *n, void *env)
dump_ir_block_edge(F, n);
}
/** Dumps a const-like node. */
static void dump_const_node(ir_node *n, void *env)
{
FILE *F = (FILE*)env;
if (is_Block(n))
return;
dump_node_wo_blockedge(F, n);
}
/***********************************************************************/
/* the following routines dump the nodes/irgs bracketed to graphs. */
/***********************************************************************/
/** Dumps a constant expression as entity initializer, array bound ... */
static void dump_const_expression(FILE *F, ir_node *value)
{
ir_graph *irg = get_const_code_irg();
ir_dump_flags_t old_flags = ir_get_dump_flags();
ir_remove_dump_flags(ir_dump_flag_consts_local);
irg_walk(value, dump_const_node, NULL, F);
/* Decrease visited flag so that we walk with the same flag for the next
expression. This guarantees that we don't dump the same node twice,
as for const expressions cse is performed to save memory. */
set_irg_visited(irg, get_irg_visited(irg) -1);
ir_set_dump_flags(old_flags);
}
void dump_begin_block_subgraph(FILE *F, const ir_node *block)
{
assert(is_Block(block));
......@@ -1478,9 +1453,6 @@ static void dump_type_info(ir_type *const tp, ir_entity *const ent, void *const
return;
case tpo_array:
print_type_type_edge(F, tp, get_array_element_type(tp), ARR_ELT_TYPE_EDGE_ATTR);
ir_node *size = get_array_size(tp);
print_node_type_edge(F, size, tp, "label: \"size\"");
dump_const_expression(F, size);
return;
case tpo_pointer:
print_type_type_edge(F, tp, get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
......
......@@ -704,19 +704,8 @@ static void dump_type_details(FILE *const F, ir_type const *const tp)
case tpo_array:
if (verbosity & dump_verbosity_typeattrs) {
fprintf(F, "\n array ");
const ir_type *elem_tp = get_array_element_type(tp);
fprintf(F, "[");
const ir_node *size = get_array_size(tp);
if (is_Const(size)) {
fprintf(F, "%ld", get_Const_long(size));
} else {
dump_node_opcode(F, size);
fprintf(F, " %ld", get_irn_node_nr(size));
}
ir_fprintf(F, "] of <%+F>", elem_tp);
fprintf(F, "\n");
ir_fprintf(F, "\n array [%.u] of <%+F>\n", get_array_size(tp), elem_tp);
}
return;
......
......@@ -373,14 +373,4 @@ void walk_const_code(irg_walk_func *pre, irg_walk_func *post, void *env)
foreach_irp_irg(i, irg) {
walk_types_entities(get_irg_frame_type(irg), &walk_entity, &my_env);
}
/* Walk constant array bounds. */
for (size_t i = 0; i < n_types; i++) {
ir_type *tp = get_irp_type(i);
if (is_Array_type(tp)) {
ir_node *size = get_array_size(tp);
if (size != NULL)
irg_walk(size, pre, post, env);
}
}
}
......@@ -577,13 +577,7 @@ static void write_type_array(write_env_t *env, ir_type *tp)
write_type_common(env, tp);
write_type_ref(env, element_type);
ir_node *size = get_array_size(tp);
if (is_Const(size))
write_long(env, get_Const_long(size));
else if (is_Unknown(size))
write_symbol(env, "unknown");
else
panic("upper array bound is not constant");
write_unsigned(env, get_array_size(tp));
fputc('\n', env->file);
}
......@@ -1610,14 +1604,9 @@ static void read_type(read_env_t *env)
switch (opcode) {
case tpo_array: {
ir_type *elemtype = read_type_ref(env);
type = new_type_array(elemtype);
char *str = read_word(env);
if (!streq(str, "unknown")) {
long size = atol(str);
set_array_size_int(type, size);
}
obstack_free(&env->obst, str);
ir_type *const elemtype = read_type_ref(env);
unsigned const length = read_unsigned(env);
type = new_type_array(elemtype, length);
set_type_size(type, size);
goto finish_type;
}
......
......@@ -352,12 +352,8 @@ static void instrument_irg(ir_graph *irg, ir_entity *counters, block_id_walker_d
*/
static ir_entity *new_array_entity(ident *name, int size)
{
ir_type *const uint_type = new_type_primitive(mode_Iu);
ir_type *const array_type = new_type_array(uint_type);
set_array_size_int(array_type, size);
set_type_size(array_type, size * get_mode_size_bytes(mode_Iu));
set_type_state(array_type, layout_fixed);
ir_type *const uint_type = new_type_primitive(mode_Iu);
ir_type *const array_type = new_type_array(uint_type, size);
ir_type *const owner = get_glob_type();
return new_global_entity(owner, name, array_type, ir_visibility_private, IR_LINKAGE_DEFAULT);
......@@ -369,14 +365,10 @@ static ir_entity *new_array_entity(ident *name, int size)
*/
static ir_entity *new_static_string_entity(ident *name, const char *string)
{
/* Create the type for a fixed-length string */
ir_type *const char_type = new_type_primitive(mode_Bs);
ir_type *const string_type = new_type_array(char_type);
size_t const length = strlen(string) + 1;
/* Create the type for a fixed-length string */
set_array_size_int(string_type, length);
set_type_size(string_type, length);
set_type_state(string_type, layout_fixed);
ir_type *const string_type = new_type_array(char_type, length);
ir_type *const owner = get_glob_type();
ir_entity *const result = new_global_entity(owner, name, string_type, ir_visibility_private, IR_LINKAGE_CONSTANT);
......
......@@ -772,58 +772,29 @@ ident *get_segment_ident(ir_type const *type)
return type->name;
}
ir_type *new_type_array(ir_type *element_type)
ir_type *new_type_array(ir_type *const element_type, unsigned const n_elements)
{
assert(!is_Method_type(element_type));
ir_type *res = new_type(tpo_array, sizeof(array_attr), NULL);
ir_type *const res = new_type(tpo_array, sizeof(array_attr), NULL);
res->attr.array.element_type = element_type;
res->attr.array.size = new_r_Unknown(get_const_code_irg(), mode_Iu);
res->attr.array.size = n_elements;
set_type_alignment(res, get_type_alignment(element_type));
if (n_elements != 0) {
set_type_size(res, n_elements * get_type_size(element_type));
set_type_state(res, layout_fixed);
}
hook_new_type(res);
return res;
}
void set_array_size(ir_type *array, ir_node *size)
{
assert(is_Array_type(array));
assert(size != NULL);
array->attr.array.size = size;
}
void set_array_size_int(ir_type *array, unsigned size)
{
ir_graph *irg = get_const_code_irg();
set_array_size(array, new_r_Const_long(irg, mode_Iu, size));
}
int has_array_size(const ir_type *array)
{
assert(is_Array_type(array));
return !is_Unknown(array->attr.array.size);
}
ir_node *get_array_size(const ir_type *array)
unsigned get_array_size(const ir_type *array)
{
assert(is_Array_type(array));
return array->attr.array.size;
}
unsigned get_array_size_int(const ir_type *array)
{
ir_node *const node = get_array_size(array);
return get_Const_long(node);
}
void set_array_element_type(ir_type *array, ir_type *tp)
{
assert(is_Array_type(array));
assert(!is_Method_type(tp));
array->attr.array.element_type = tp;
set_type_alignment(array, get_type_alignment(tp));
}
ir_type *get_array_element_type(const ir_type *array)
{
assert(is_Array_type(array));
......
......@@ -76,7 +76,7 @@ typedef struct {
/** Array type attributes. */
typedef struct {
ir_node *size; /**< number of elements in the array. */
unsigned size; /**< number of elements in the array. */
ir_type *element_type; /**< The type of the array elements. */
} array_attr;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment