Commit e1773a0d authored by Matthias Braun's avatar Matthias Braun
Browse files

simplify handling of bitfield members

We do not model them as a type anymore, but simply annotate
compound_member entities with a bit offset and bit size.
parent 13febceb
...@@ -345,18 +345,22 @@ FIRM_API const char *get_align_name(ir_align a); ...@@ -345,18 +345,22 @@ FIRM_API const char *get_align_name(ir_align a);
/** Returns the offset of an entity (in a compound) in bytes. Only set if /** Returns the offset of an entity (in a compound) in bytes. Only set if
* layout = fixed. */ * layout = fixed. */
FIRM_API int get_entity_offset(const ir_entity *ent); FIRM_API int get_entity_offset(const ir_entity *entity);
/** Sets the offset of an entity (in a compound) in bytes. */ /** Sets the offset of an entity (in a compound) in bytes. */
FIRM_API void set_entity_offset(ir_entity *ent, int offset); FIRM_API void set_entity_offset(ir_entity *entity, int offset);
/** Returns the offset bit remainder of a bitfield entity (in a compound) in /** For bitfields, returns the offset in bits to the bitfield base. */
* bits. Only set if layout = fixed. */ FIRM_API unsigned get_entity_bitfield_offset(const ir_entity *entity);
FIRM_API unsigned char get_entity_offset_bits_remainder(const ir_entity *ent);
/** Sets the offset bit remainder of a bitfield entity (in a compound) in bits. */ /** Sets the offset in bits to the base for a bitfield. */
FIRM_API void set_entity_offset_bits_remainder(ir_entity *ent, FIRM_API void set_entity_bitfield_offset(ir_entity *entity, unsigned offset);
unsigned char offset);
/** Sets the size in bits for a bitfield. 0 means not a bitfield. */
FIRM_API void set_entity_bitfield_size(ir_entity *entity, unsigned size);
/** Returns the size in bits for a bitfield, 0 if entity is not a bitfield. */
FIRM_API unsigned get_entity_bitfield_size(const ir_entity *entity);
/** Returns the stored intermediate information. */ /** Returns the stored intermediate information. */
FIRM_API void *get_entity_link(const ir_entity *ent); FIRM_API void *get_entity_link(const ir_entity *ent);
...@@ -1886,12 +1890,6 @@ FIRM_API ir_type *new_d_type_primitive(ir_mode *mode, type_dbg_info* db); ...@@ -1886,12 +1890,6 @@ FIRM_API ir_type *new_d_type_primitive(ir_mode *mode, type_dbg_info* db);
/** Returns true if a type is a primitive type. */ /** Returns true if a type is a primitive type. */
FIRM_API int is_Primitive_type(const ir_type *primitive); FIRM_API int is_Primitive_type(const ir_type *primitive);
/** Returns the base type of a primitive (bitfield) type or NULL if none. */
FIRM_API ir_type *get_primitive_base_type(const ir_type *tp);
/** Sets the base type of a primitive (bitfield) type. */
FIRM_API void set_primitive_base_type(ir_type *tp, ir_type *base_tp);
/** /**
* This type opcode marks that the corresponding type is a primitive type. * This type opcode marks that the corresponding type is a primitive type.
* *
......
...@@ -432,22 +432,6 @@ ir_storage_class_class_t classify_pointer(const ir_node *irn, ...@@ -432,22 +432,6 @@ ir_storage_class_class_t classify_pointer(const ir_node *irn,
return res; return res;
} }
/**
* If adr represents a Bitfield Sel, skip it
*/
static const ir_node *skip_Bitfield_Sels(const ir_node *adr)
{
if (is_Sel(adr)) {
ir_entity *ent = get_Sel_entity(adr);
ir_type *bf_type = get_entity_type(ent);
/* is it a bitfield type? */
if (is_Primitive_type(bf_type) && get_primitive_base_type(bf_type) != NULL)
adr = get_Sel_ptr(adr);
}
return adr;
}
/** /**
* Determine the alias relation between two addresses. * Determine the alias relation between two addresses.
* *
...@@ -564,16 +548,6 @@ static ir_alias_relation _get_alias_relation( ...@@ -564,16 +548,6 @@ static ir_alias_relation _get_alias_relation(
return ir_sure_alias; return ir_sure_alias;
} }
/*
* Bitfields can be constructed as Sels from its base address.
* As they have different entities, the disambiguator would find that they are
* alias free. While this is true for its values, it is false for the addresses
* (strictly speaking, the Sel's are NOT the addresses of the bitfields).
* So, skip those bitfield selecting Sel's.
*/
adr1 = skip_Bitfield_Sels(adr1);
adr2 = skip_Bitfield_Sels(adr2);
/* skip Sels */ /* skip Sels */
const ir_node *base1 = adr1; const ir_node *base1 = adr1;
const ir_node *base2 = adr2; const ir_node *base2 = adr2;
......
...@@ -673,11 +673,6 @@ static void emit_compound_type(const ir_type *type) ...@@ -673,11 +673,6 @@ static void emit_compound_type(const ir_type *type)
for (size_t i = 0; i < n_members; ++i) { for (size_t i = 0; i < n_members; ++i) {
ir_entity *member = get_compound_member(type, i); ir_entity *member = get_compound_member(type, i);
ir_type *member_type = get_entity_type(member); ir_type *member_type = get_entity_type(member);
if (is_Primitive_type(member_type)) {
ir_type *base = get_primitive_base_type(member_type);
if (base != NULL)
member_type = base;
}
emit_type(member_type); emit_type(member_type);
} }
...@@ -695,14 +690,11 @@ static void emit_compound_type(const ir_type *type) ...@@ -695,14 +690,11 @@ static void emit_compound_type(const ir_type *type)
ir_entity *member = get_compound_member(type, i); ir_entity *member = get_compound_member(type, i);
ir_type *member_type = get_entity_type(member); ir_type *member_type = get_entity_type(member);
int offset = get_entity_offset(member); int offset = get_entity_offset(member);
ir_type *base;
if (is_Primitive_type(member_type) && if (get_entity_bitfield_size(member) > 0) {
(base = get_primitive_base_type(member_type))) { unsigned bit_offset = get_entity_bitfield_offset(member);
unsigned bit_offset = get_entity_offset_bits_remainder(member); unsigned bit_size = get_entity_bitfield_size(member);
unsigned base_size = get_type_size_bytes(base); unsigned base_size = get_type_size_bytes(member_type);
ir_mode *mode = get_type_mode(member_type);
unsigned bit_size = get_mode_size_bits(mode);
bit_offset = base_size*8 - bit_offset - bit_size; bit_offset = base_size*8 - bit_offset - bit_size;
...@@ -710,7 +702,6 @@ static void emit_compound_type(const ir_type *type) ...@@ -710,7 +702,6 @@ static void emit_compound_type(const ir_type *type)
emit_uleb128(base_size); emit_uleb128(base_size);
emit_uleb128(bit_size); emit_uleb128(bit_size);
emit_uleb128(bit_offset); emit_uleb128(bit_offset);
member_type = base;
} else { } else {
emit_uleb128(abbrev_member); emit_uleb128(abbrev_member);
} }
......
...@@ -852,13 +852,13 @@ static normal_or_bitfield *glob_vals; ...@@ -852,13 +852,13 @@ static normal_or_bitfield *glob_vals;
static size_t max_vals; static size_t max_vals;
#endif #endif
static void emit_bitfield(normal_or_bitfield *vals, size_t offset_bits, static void emit_bitfield(normal_or_bitfield *vals, unsigned offset_bits,
unsigned bitfield_size,
const ir_initializer_t *initializer, ir_type *type) const ir_initializer_t *initializer, ir_type *type)
{ {
static const size_t BITS_PER_BYTE = 8; static const size_t BITS_PER_BYTE = 8;
ir_mode *mode = get_type_mode(type);
ir_tarval *tv = NULL;
ir_tarval *tv = NULL;
switch (get_initializer_kind(initializer)) { switch (get_initializer_kind(initializer)) {
case IR_INITIALIZER_NULL: case IR_INITIALIZER_NULL:
return; return;
...@@ -876,14 +876,13 @@ static void emit_bitfield(normal_or_bitfield *vals, size_t offset_bits, ...@@ -876,14 +876,13 @@ static void emit_bitfield(normal_or_bitfield *vals, size_t offset_bits,
case IR_INITIALIZER_COMPOUND: case IR_INITIALIZER_COMPOUND:
panic("bitfield initializer is compound"); panic("bitfield initializer is compound");
} }
if (tv == NULL) { if (tv == NULL || tv == tarval_bad) {
panic("Couldn't get numeric value for bitfield initializer"); panic("Couldn't get numeric value for bitfield initializer");
} }
tv = tarval_convert_to(tv, get_type_mode(type));
int value_len = get_type_size_bytes(get_primitive_base_type(type)); int value_len = get_type_size_bytes(type);
size_t bit_offset = 0; size_t bit_offset = 0;
size_t end = get_mode_size_bits(mode); size_t end = bitfield_size;
bool big_endian = be_get_backend_param()->byte_order_big_endian; bool big_endian = be_get_backend_param()->byte_order_big_endian;
while (bit_offset < end) { while (bit_offset < end) {
size_t src_offset = bit_offset / BITS_PER_BYTE; size_t src_offset = bit_offset / BITS_PER_BYTE;
...@@ -991,20 +990,13 @@ static void emit_ir_initializer(normal_or_bitfield *vals, ...@@ -991,20 +990,13 @@ static void emit_ir_initializer(normal_or_bitfield *vals,
ir_initializer_t *sub_initializer ir_initializer_t *sub_initializer
= get_initializer_compound_value(initializer, i); = get_initializer_compound_value(initializer, i);
ir_type *subtype = get_entity_type(member); ir_type *subtype = get_entity_type(member);
ir_mode *mode = get_type_mode(subtype); unsigned bitfield_size = get_entity_bitfield_size(member);
if (mode != NULL) { if (bitfield_size > 0) {
size_t offset_bits unsigned offset_bits = get_entity_bitfield_offset(member);
= get_entity_offset_bits_remainder(member); emit_bitfield(&vals[offset], offset_bits, bitfield_size,
sub_initializer, subtype);
if (is_Primitive_type(subtype) continue;
&& get_primitive_base_type(subtype) != NULL) {
emit_bitfield(&vals[offset], offset_bits,
sub_initializer, subtype);
continue;
} else {
assert(offset_bits == 0);
}
} }
emit_ir_initializer(&vals[offset], sub_initializer, subtype); emit_ir_initializer(&vals[offset], sub_initializer, subtype);
......
...@@ -564,12 +564,18 @@ static void dump_entity_to_file_prefix(FILE *const F, ...@@ -564,12 +564,18 @@ static void dump_entity_to_file_prefix(FILE *const F,
get_entity_vtable_number(ent)); get_entity_vtable_number(ent));
} }
} else { /* no entattrs */ } else { /* no entattrs */
ir_fprintf(F, "%s(%3d:%d) %+F: %s", prefix, ir_fprintf(F, "%s %+F: %s", prefix, type, get_entity_name(ent));
get_entity_offset(ent),
get_entity_offset_bits_remainder(ent), type,
get_entity_name(ent));
if (is_Method_type(type)) if (is_Method_type(type))
fputs("(...)", F); fputs("(...)", F);
if (ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER) {
ir_fprintf(F, " offset: %d", get_entity_offset(ent));
unsigned bitfield_size = get_entity_bitfield_size(ent);
if (bitfield_size > 0) {
unsigned bitfield_offset = get_entity_bitfield_offset(ent);
ir_fprintf(F, " bitfield offs %u size %u", bitfield_offset,
bitfield_size);
}
}
if (verbosity & dump_verbosity_accessStats) { if (verbosity & dump_verbosity_accessStats) {
dump_entity_linkage(F, ent); dump_entity_linkage(F, ent);
...@@ -594,7 +600,7 @@ static void dump_entity_to_file_prefix(FILE *const F, ...@@ -594,7 +600,7 @@ static void dump_entity_to_file_prefix(FILE *const F,
fprintf(F, "\n%s aligned: %s", prefix, get_align_name(get_entity_aligned(ent))); fprintf(F, "\n%s aligned: %s", prefix, get_align_name(get_entity_aligned(ent)));
fprintf(F, "\n%s alignment: %u", prefix, get_entity_alignment(ent)); fprintf(F, "\n%s alignment: %u", prefix, get_entity_alignment(ent));
fprintf(F, "\n%s ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set"); fprintf(F, "\n%s ld_name: %s", prefix, ent->ld_name ? get_entity_ld_name(ent) : "no yet set");
fprintf(F, "\n%s offset: %d bytes, %d rem bits", prefix, get_entity_offset(ent), get_entity_offset_bits_remainder(ent)); fprintf(F, "\n%s offset: %d bytes", prefix, get_entity_offset(ent));
if (is_Method_type(type)) { if (is_Method_type(type)) {
const ir_graph *irg = get_entity_irg(ent); const ir_graph *irg = get_entity_irg(ent);
if (irg != NULL) { if (irg != NULL) {
...@@ -758,14 +764,6 @@ void dump_type_to_file(FILE *const F, const ir_type *const tp) ...@@ -758,14 +764,6 @@ void dump_type_to_file(FILE *const F, const ir_type *const tp)
break; break;
case tpo_primitive: case tpo_primitive:
if (verbosity & dump_verbosity_typeattrs) {
const ir_type *base_tp = get_primitive_base_type(tp);
if (base_tp != NULL)
ir_fprintf(F, "\n base type: %+F", tp);
fprintf(F, "\n");
}
break;
case tpo_none: case tpo_none:
case tpo_unknown: case tpo_unknown:
fprintf(F, "\n"); fprintf(F, "\n");
......
...@@ -559,16 +559,8 @@ static void write_type(write_env_t *env, ir_type *tp); ...@@ -559,16 +559,8 @@ static void write_type(write_env_t *env, ir_type *tp);
static void write_type_primitive(write_env_t *env, ir_type *tp) static void write_type_primitive(write_env_t *env, ir_type *tp)
{ {
ir_type *base_type = get_primitive_base_type(tp);
if (base_type != NULL)
write_type(env, base_type);
write_type_common(env, tp); write_type_common(env, tp);
write_mode_ref(env, get_type_mode(tp)); write_mode_ref(env, get_type_mode(tp));
if (base_type == NULL)
base_type = get_none_type();
write_type_ref(env, base_type);
fputc('\n', env->file); fputc('\n', env->file);
} }
...@@ -769,7 +761,8 @@ static void write_entity(write_env_t *env, ir_entity *ent) ...@@ -769,7 +761,8 @@ static void write_entity(write_env_t *env, ir_entity *ent)
break; break;
case IR_ENTITY_COMPOUND_MEMBER: case IR_ENTITY_COMPOUND_MEMBER:
write_long(env, get_entity_offset(ent)); write_long(env, get_entity_offset(ent));
write_unsigned(env, get_entity_offset_bits_remainder(ent)); write_unsigned(env, get_entity_bitfield_offset(ent));
write_unsigned(env, get_entity_bitfield_size(ent));
break; break;
case IR_ENTITY_PARAMETER: { case IR_ENTITY_PARAMETER: {
size_t num = get_entity_parameter_number(ent); size_t num = get_entity_parameter_number(ent);
...@@ -1776,11 +1769,7 @@ static void read_type(read_env_t *env) ...@@ -1776,11 +1769,7 @@ static void read_type(read_env_t *env)
case tpo_primitive: { case tpo_primitive: {
ir_mode *mode = read_mode_ref(env); ir_mode *mode = read_mode_ref(env);
ir_type *base_type = read_type_ref(env);
type = new_type_primitive(mode); type = new_type_primitive(mode);
if (base_type != get_none_type()) {
set_primitive_base_type(type, base_type);
}
goto finish_type; goto finish_type;
} }
...@@ -1880,8 +1869,9 @@ static void read_entity(read_env_t *env, ir_entity_kind kind) ...@@ -1880,8 +1869,9 @@ static void read_entity(read_env_t *env, ir_entity_kind kind)
entity = new_entity(owner, name, type); entity = new_entity(owner, name, type);
if (ld_name != NULL) if (ld_name != NULL)
set_entity_ld_ident(entity, ld_name); set_entity_ld_ident(entity, ld_name);
set_entity_offset(entity, (int) read_long(env)); set_entity_offset(entity, read_int(env));
set_entity_offset_bits_remainder(entity, (unsigned char) read_long(env)); set_entity_bitfield_offset(entity, read_unsigned(env));
set_entity_bitfield_size(entity, read_unsigned(env));
break; break;
case IR_ENTITY_METHOD: case IR_ENTITY_METHOD:
entity = new_entity(owner, name, type); entity = new_entity(owner, name, type);
......
...@@ -996,23 +996,7 @@ static unsigned optimize_load(ir_node *load) ...@@ -996,23 +996,7 @@ static unsigned optimize_load(ir_node *load)
value = find_compound_ent_value(ptr); value = find_compound_ent_value(ptr);
} }
if (value != NULL) { if (value != NULL) {
ir_graph *irg = get_irn_irg(load);
value = can_replace_load_by_const(load, value); value = can_replace_load_by_const(load, value);
if (value != NULL && is_Sel(ptr)) {
/* frontend has inserted masking operations after bitfield accesses,
* so we might have to shift the const. */
unsigned char bit_offset = get_entity_offset_bits_remainder(get_Sel_entity(ptr));
if (bit_offset != 0) {
if (is_Const(value)) {
ir_tarval *tv_old = get_Const_tarval(value);
ir_tarval *tv_offset = new_tarval_from_long(bit_offset, mode_Bu);
ir_tarval *tv_new = tarval_shl(tv_old, tv_offset);
value = new_r_Const(irg, tv_new);
} else {
value = NULL;
}
}
}
} }
} }
} }
......
...@@ -44,7 +44,6 @@ static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind, ...@@ -44,7 +44,6 @@ static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind,
ir_entity *res = XMALLOCZ(ir_entity); ir_entity *res = XMALLOCZ(ir_entity);
res->kind = k_entity; res->kind = k_entity;
res->name = name; res->name = name;
res->ld_name = NULL;
res->type = type; res->type = type;
res->owner = owner; res->owner = owner;
...@@ -52,12 +51,7 @@ static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind, ...@@ -52,12 +51,7 @@ static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind,
res->volatility = volatility_non_volatile; res->volatility = volatility_non_volatile;
res->aligned = align_is_aligned; res->aligned = align_is_aligned;
res->usage = ir_usage_unknown; res->usage = ir_usage_unknown;
res->compiler_gen = 0;
res->visibility = ir_visibility_external; res->visibility = ir_visibility_external;
res->offset = -1;
res->offset_bit_remainder = 0;
res->alignment = 0;
res->link = NULL;
#ifdef DEBUG_libfirm #ifdef DEBUG_libfirm
res->nr = get_irp_new_node_nr(); res->nr = get_irp_new_node_nr();
#endif #endif
...@@ -90,6 +84,7 @@ ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type, ...@@ -90,6 +84,7 @@ ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
res->attr.mtd_attr.irg = NULL; res->attr.mtd_attr.irg = NULL;
} else if (is_compound_type(owner) && !(owner->flags & tf_segment)) { } else if (is_compound_type(owner) && !(owner->flags & tf_segment)) {
res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db); res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db);
res->attr.compound_member.offset = -1;
} else { } else {
res = intern_new_entity(owner, IR_ENTITY_NORMAL, name, type, db); res = intern_new_entity(owner, IR_ENTITY_NORMAL, name, type, db);
} }
...@@ -116,6 +111,7 @@ ir_entity *new_d_parameter_entity(ir_type *owner, size_t pos, ir_type *type, ...@@ -116,6 +111,7 @@ ir_entity *new_d_parameter_entity(ir_type *owner, size_t pos, ir_type *type,
ident *name = make_parameter_entity_name(pos); ident *name = make_parameter_entity_name(pos);
ir_entity *res ir_entity *res
= intern_new_entity(owner, IR_ENTITY_PARAMETER, name, type, dbgi); = intern_new_entity(owner, IR_ENTITY_PARAMETER, name, type, dbgi);
res->attr.compound_member.offset = -1;
res->attr.parameter.number = pos; res->attr.parameter.number = pos;
hook_new_entity(res); hook_new_entity(res);
return res; return res;
...@@ -717,14 +713,24 @@ void (set_entity_offset)(ir_entity *ent, int offset) ...@@ -717,14 +713,24 @@ void (set_entity_offset)(ir_entity *ent, int offset)
_set_entity_offset(ent, offset); _set_entity_offset(ent, offset);
} }
unsigned char (get_entity_offset_bits_remainder)(const ir_entity *ent) unsigned (get_entity_bitfield_offset)(const ir_entity *ent)
{ {
return _get_entity_offset_bits_remainder(ent); return _get_entity_bitfield_offset(ent);
} }
void (set_entity_offset_bits_remainder)(ir_entity *ent, unsigned char offset) void (set_entity_bitfield_offset)(ir_entity *ent, unsigned offset)
{ {
_set_entity_offset_bits_remainder(ent, offset); _set_entity_bitfield_offset(ent, offset);
}
unsigned (get_entity_bitfield_size)(const ir_entity *ent)
{
return _get_entity_bitfield_size(ent);
}
void (set_entity_bitfield_size)(ir_entity *ent, unsigned size)
{
_set_entity_bitfield_size(ent, size);
} }
void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten) void add_entity_overwrites(ir_entity *ent, ir_entity *overwritten)
......
...@@ -40,8 +40,10 @@ ...@@ -40,8 +40,10 @@
#define set_entity_usage(ent, flags) _set_entity_usage(ent, flags) #define set_entity_usage(ent, flags) _set_entity_usage(ent, flags)
#define get_entity_offset(ent) _get_entity_offset(ent) #define get_entity_offset(ent) _get_entity_offset(ent)
#define set_entity_offset(ent, offset) _set_entity_offset(ent, offset) #define set_entity_offset(ent, offset) _set_entity_offset(ent, offset)
#define get_entity_offset_bits_remainder(ent) _get_entity_offset_bits_remainder(ent) #define get_entity_bitfield_offset(ent) _get_entity_bitfield_offset(ent)
#define set_entity_offset_bits_remainder(ent, o) _set_entity_offset_bits_remainder(ent, o) #define set_entity_bitfield_offset(ent, o) _set_entity_bitfield_offset(ent, o)
#define get_entity_bitfield_size(ent) _get_entity_bitfield_size(ent)
#define set_entity_bitfield_size(ent, s) _set_entity_bitfield_size(ent, s)
#define get_entity_link(ent) _get_entity_link(ent) #define get_entity_link(ent) _get_entity_link(ent)
#define set_entity_link(ent, l) _set_entity_link(ent, l) #define set_entity_link(ent, l) _set_entity_link(ent, l)
#define get_entity_irg(ent) _get_entity_irg(ent) #define get_entity_irg(ent) _get_entity_irg(ent)
...@@ -112,7 +114,17 @@ typedef struct code_ent_attr { ...@@ -112,7 +114,17 @@ typedef struct code_ent_attr {
ir_label_t label; /** label of the basic block */ ir_label_t label; /** label of the basic block */
} code_ent_attr; } code_ent_attr;
typedef struct compound_member_ent_attr {
int offset; /**< Offset in bytes for this entity. Fixed
when layout of owner is determined. */
unsigned bitfield_offset; /**< for bitfields: offset in bits from base */
unsigned bitfield_size; /**< for bitfields: size of entity in bits,
0 if entity is not a bitfield. */
} compound_member_ent_attr;
typedef struct parameter_ent_attr { typedef struct parameter_ent_attr {
compound_member_ent_attr base; /**< a parameter is also a compound_member
of the frame type. */
size_t number; /**< corresponding parameter number */ size_t number; /**< corresponding parameter number */
ir_mode *doubleword_low_mode;/**< entity is a lowered doubleword parameter, ir_mode *doubleword_low_mode;/**< entity is a lowered doubleword parameter,
so additional stores because of calling so additional stores because of calling
...@@ -156,12 +168,6 @@ struct ir_entity { ...@@ -156,12 +168,6 @@ struct ir_entity {
unsigned allocation:3; /**< @deprecated */ unsigned allocation:3; /**< @deprecated */
unsigned peculiarity:3; /**< @deprecated */ unsigned peculiarity:3; /**< @deprecated */
unsigned final:1; /**< @deprecated */ unsigned final:1; /**< @deprecated */
unsigned offset_bit_remainder:8;
/**< If the entity is a bit field, this is the
offset of the start of the bit field
within the byte specified by offset. */
int offset; /**< Offset in bytes for this entity. Fixed
when layout of owner is determined. */
unsigned alignment; /**< entity alignment in bytes */ unsigned alignment; /**< entity alignment in bytes */
ir_visited_t visit; /**< visited counter for walks of the type ir_visited_t visit; /**< visited counter for walks of the type
information. */ information. */
...@@ -179,12 +185,14 @@ struct ir_entity { ...@@ -179,12 +185,14 @@ struct ir_entity {
#endif #endif
union { union {
/* ------------- fields for method entities ---------------- */ /** attributes for method entities */
method_ent_attr mtd_attr; method_ent_attr mtd_attr;
/* fields for code entities */ /** fields for code entities */
code_ent_attr code_attr; code_ent_attr code_attr;
/** compound member attributes */
compound_member_ent_attr compound_member;
/** parameter number for parameter entities */ /** parameter number for parameter entities */
parameter_ent_attr parameter; parameter_ent_attr parameter;
} attr; /**< type specific attributes */ } attr; /**< type specific attributes */
}; };
...@@ -330,26 +338,44 @@ static inline void _set_entity_usage(ir_entity *ent, ir_entity_usage state) ...@@ -330,26 +338,44 @@ static inline void _set_entity_usage(ir_entity *ent, ir_entity_usage state)
static inline int _get_entity_offset(const ir_entity *ent) static inline int _get_entity_offset(const ir_entity *ent)
{ {
assert(ent->kind == k_entity); assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
return ent->offset; || ent->entity_kind == IR_ENTITY_PARAMETER);
return ent->attr.compound_member.offset;
} }
static inline void _set_entity_offset(ir_entity *ent, int offset) static inline void _set_entity_offset(ir_entity *ent, int offset)
{ {
assert(ent->kind == k_entity); assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
ent->offset = offset; || ent->entity_kind == IR_ENTITY_PARAMETER);
ent->attr.compound_member.offset = offset;
} }
static inline unsigned char _get_entity_offset_bits_remainder(const ir_entity *ent) static inline unsigned _get_entity_bitfield_offset(const ir_entity *ent)
{ {
assert(ent->kind == k_entity); assert(ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER
return ent->offset_bit_remainder; || ent->entity_kind == IR_ENTITY_PARAMETER);
return ent->attr.compound_member.bitfield_offset;
} }
static inline void _set_entity_offset_bits_remainder(ir_entity *ent, unsigned char offset)