Commit 1c3acfb9 authored by Matthias Braun's avatar Matthias Braun
Browse files

set type alignment at type construction time

parent 5d84b5a8
...@@ -1015,18 +1015,9 @@ FIRM_API unsigned get_type_size_bytes(const ir_type *tp); ...@@ -1015,18 +1015,9 @@ FIRM_API unsigned get_type_size_bytes(const ir_type *tp);
FIRM_API void set_type_size_bytes(ir_type *tp, unsigned size); FIRM_API void set_type_size_bytes(ir_type *tp, unsigned size);
/** Returns the alignment of a type in bytes. */ /** Returns the alignment of a type in bytes. */
FIRM_API unsigned get_type_alignment_bytes(ir_type *tp); FIRM_API unsigned get_type_alignment_bytes(const ir_type *tp);
/** Sets the alignment of a type in bytes. /** Sets the alignment of a type in bytes. */
*
* If the alignment of a type is
* not set, it is calculated here according to the following rules:
* -#.) if a type has a mode, the alignment is the mode size.
* -#.) compound types have the alignment of their biggest member.
* -#.) array types have the alignment of their element type.
* -#.) method types return 0 here.
* -#.) all other types return 1 here (i.e. aligned at byte).
*/
FIRM_API void set_type_alignment_bytes(ir_type *tp, unsigned align); FIRM_API void set_type_alignment_bytes(ir_type *tp, unsigned align);
/** Returns the visited counter of a type. /** Returns the visited counter of a type.
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "error.h" #include "error.h"
#include "dbginfo.h" #include "dbginfo.h"
#include "irprog_t.h" #include "irprog_t.h"
#include "bitfiddle.h"
#include "array.h" #include "array.h"
...@@ -238,44 +239,16 @@ void set_type_size_bytes(ir_type *tp, unsigned size) ...@@ -238,44 +239,16 @@ void set_type_size_bytes(ir_type *tp, unsigned size)
tpop->ops.set_type_size(tp, size); tpop->ops.set_type_size(tp, size);
} }
unsigned get_type_alignment_bytes(ir_type *tp) unsigned (get_type_alignment_bytes)(const ir_type *type)
{ {
if (tp->align > 0) return get_type_alignment_bytes_(type);
return tp->align;
/* alignment NOT set calculate it "on demand" */
unsigned align;
if (tp->mode)
align = (get_mode_size_bits(tp->mode) + 7) >> 3;
else if (is_Array_type(tp))
align = get_type_alignment_bytes(get_array_element_type(tp));
else if (is_compound_type(tp)) {
align = 0;
for (size_t i = 0, n = get_compound_n_members(tp); i < n; ++i) {
ir_type *t = get_entity_type(get_compound_member(tp, i));
unsigned a = get_type_alignment_bytes(t);
if (a > align)
align = a;
}
} else if (is_Method_type(tp)) {
align = 0;
} else {
align = 1;
}
/* write back */
tp->align = align;
return align;
} }
void set_type_alignment_bytes(ir_type *tp, unsigned align) void set_type_alignment_bytes(ir_type *type, unsigned align)
{ {
assert(is_type(tp)); assert(is_type(type));
/* Methods don't have an alignment. */ assert(align > 0);
if (tp->type_op != type_method) { type->align = align;
tp->align = align;
}
} }
const char *get_type_state_name(ir_type_state s) const char *get_type_state_name(ir_type_state s)
...@@ -713,6 +686,7 @@ ir_type *new_type_method(size_t n_param, size_t n_res) ...@@ -713,6 +686,7 @@ ir_type *new_type_method(size_t n_param, size_t n_res)
res->attr.ma.res_type = XMALLOCNZ(ir_type*, n_res); res->attr.ma.res_type = XMALLOCNZ(ir_type*, n_res);
res->attr.ma.variadicity = variadicity_non_variadic; res->attr.ma.variadicity = variadicity_non_variadic;
res->attr.ma.properties = mtp_no_property; res->attr.ma.properties = mtp_no_property;
set_type_alignment_bytes(res, 1);
hook_new_type(res); hook_new_type(res);
return res; return res;
} }
...@@ -739,6 +713,7 @@ ir_type *clone_type_method(ir_type *tp) ...@@ -739,6 +713,7 @@ ir_type *clone_type_method(ir_type *tp)
res->attr.ma.variadicity = tp->attr.ma.variadicity; res->attr.ma.variadicity = tp->attr.ma.variadicity;
res->attr.ma.properties = tp->attr.ma.properties; res->attr.ma.properties = tp->attr.ma.properties;
res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv; res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
set_type_alignment_bytes(res, get_type_alignment_bytes(tp));
hook_new_type(res); hook_new_type(res);
return res; return res;
} }
...@@ -950,6 +925,7 @@ ir_type *new_type_array(ir_type *element_type) ...@@ -950,6 +925,7 @@ ir_type *new_type_array(ir_type *element_type)
ir_type *res = new_type(type_array, NULL); ir_type *res = new_type(type_array, NULL);
res->attr.aa.element_type = element_type; res->attr.aa.element_type = element_type;
res->attr.aa.size = new_r_Unknown(get_const_code_irg(), mode_Iu); res->attr.aa.size = new_r_Unknown(get_const_code_irg(), mode_Iu);
set_type_alignment_bytes(res, get_type_alignment_bytes(element_type));
ident *const id = new_id_from_chars("elem_ent", 8); ident *const id = new_id_from_chars("elem_ent", 8);
res->attr.aa.element_ent = new_entity(res, id, element_type); res->attr.aa.element_ent = new_entity(res, id, element_type);
...@@ -1001,6 +977,7 @@ void set_array_element_type(ir_type *array, ir_type *tp) ...@@ -1001,6 +977,7 @@ void set_array_element_type(ir_type *array, ir_type *tp)
assert(is_Array_type(array)); assert(is_Array_type(array));
assert(!is_Method_type(tp)); assert(!is_Method_type(tp));
array->attr.aa.element_type = tp; array->attr.aa.element_type = tp;
set_type_alignment_bytes(array, get_type_alignment_bytes(tp));
} }
ir_type *get_array_element_type(const ir_type *array) ir_type *get_array_element_type(const ir_type *array)
...@@ -1047,8 +1024,10 @@ ir_type *new_type_pointer(ir_type *points_to) ...@@ -1047,8 +1024,10 @@ ir_type *new_type_pointer(ir_type *points_to)
ir_mode *const mode = get_type_pointer_mode(points_to); ir_mode *const mode = get_type_pointer_mode(points_to);
ir_type *const res = new_type(type_pointer, mode); ir_type *const res = new_type(type_pointer, mode);
res->attr.pa.points_to = points_to; res->attr.pa.points_to = points_to;
res->size = get_mode_size_bytes(res->mode); unsigned size = get_mode_size_bytes(mode);
res->size = size;
res->flags |= tf_layout_fixed; res->flags |= tf_layout_fixed;
set_type_alignment_bytes(res, size);
hook_new_type(res); hook_new_type(res);
return res; return res;
} }
...@@ -1094,6 +1073,11 @@ ir_type *new_type_primitive(ir_mode *mode) ...@@ -1094,6 +1073,11 @@ ir_type *new_type_primitive(ir_mode *mode)
ir_type *res = new_type(type_primitive, mode); ir_type *res = new_type(type_primitive, mode);
res->size = get_mode_size_bytes(mode); res->size = get_mode_size_bytes(mode);
res->flags |= tf_layout_fixed; res->flags |= tf_layout_fixed;
unsigned mode_size = get_mode_size_bits(mode);
unsigned align = mode_size > 0
? ceil_po2((get_mode_size_bits(mode) + 7) >> 3)
: 1;
set_type_alignment_bytes(res, align);
hook_new_type(res); hook_new_type(res);
return res; return res;
} }
...@@ -1282,9 +1266,7 @@ void default_layout_compound_type(ir_type *type) ...@@ -1282,9 +1266,7 @@ void default_layout_compound_type(ir_type *type)
if (align_all > 0 && size % align_all) { if (align_all > 0 && size % align_all) {
size += align_all - (size % align_all); size += align_all - (size % align_all);
} }
if (align_all > get_type_alignment_bytes(type)) { set_type_alignment_bytes(type, align_all);
set_type_alignment_bytes(type, align_all);
}
set_type_size_bytes(type, size); set_type_size_bytes(type, size);
set_type_state(type, layout_fixed); set_type_state(type, layout_fixed);
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define get_type_tpop_nameid(tp) get_type_tpop_nameid_(tp) #define get_type_tpop_nameid(tp) get_type_tpop_nameid_(tp)
#define get_type_tpop_code(tp) get_type_tpop_code_(tp) #define get_type_tpop_code(tp) get_type_tpop_code_(tp)
#define get_type_mode(tp) get_type_mode_(tp) #define get_type_mode(tp) get_type_mode_(tp)
#define get_type_alignment_bytes(tp) get_type_alignment_bytes_(tp)
#define get_type_size_bytes(tp) get_type_size_bytes_(tp) #define get_type_size_bytes(tp) get_type_size_bytes_(tp)
#define get_type_state(tp) get_type_state_(tp) #define get_type_state(tp) get_type_state_(tp)
#define get_type_visited(tp) get_type_visited_(tp) #define get_type_visited(tp) get_type_visited_(tp)
...@@ -201,6 +202,11 @@ static inline ir_visited_t get_master_type_visited_(void) ...@@ -201,6 +202,11 @@ static inline ir_visited_t get_master_type_visited_(void)
return firm_type_visited; return firm_type_visited;
} }
static inline int is_type_(const void *thing)
{
return get_kind(thing) == k_type;
}
static inline int is_lowered_type(const ir_type *tp) static inline int is_lowered_type(const ir_type *tp)
{ {
return tp->flags & tf_lowered_type; return tp->flags & tf_lowered_type;
...@@ -253,6 +259,12 @@ static inline ir_mode *get_type_mode_(const ir_type *tp) ...@@ -253,6 +259,12 @@ static inline ir_mode *get_type_mode_(const ir_type *tp)
return tp->mode; return tp->mode;
} }
static inline unsigned get_type_alignment_bytes_(const ir_type *type)
{
assert(is_type(type));
return type->align;
}
static inline unsigned get_type_size_bytes_(const ir_type *tp) static inline unsigned get_type_size_bytes_(const ir_type *tp)
{ {
assert(tp->kind == k_type); assert(tp->kind == k_type);
...@@ -300,11 +312,6 @@ static inline void set_type_dbg_info_(ir_type *tp, type_dbg_info *db) ...@@ -300,11 +312,6 @@ static inline void set_type_dbg_info_(ir_type *tp, type_dbg_info *db)
tp->dbi = db; tp->dbi = db;
} }
static inline int is_type_(const void *thing)
{
return get_kind(thing) == k_type;
}
static inline int is_class_type_(const ir_type *clss) static inline int is_class_type_(const ir_type *clss)
{ {
return clss->type_op == type_class; return clss->type_op == type_class;
......
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