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

differntiate entity kinds

We already saved different entity attributes depending on the entity
type and an is_parameter flag. This unifies handling of different entity
types and introduces normal, method, parameter, label and
compound_member entities.
parent bd019d8c
......@@ -627,15 +627,10 @@ ir_entity *create_Block_entity(ir_node *block)
entity = block->attr.block.entity;
if (entity == NULL) {
ir_label_t nr;
ir_type *glob;
glob = get_glob_type();
entity = new_entity(glob, id_unique("block_%u"), get_code_type());
ir_label_t nr = get_irp_next_label_nr();
entity = new_label_entity(nr);
set_entity_visibility(entity, ir_visibility_local);
set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
nr = get_irp_next_label_nr();
set_entity_label(entity, nr);
set_entity_compiler_generated(entity, 1);
block->attr.block.entity = entity;
......
......@@ -92,10 +92,10 @@ static ir_prog *complete_ir_prog(ir_prog *irp, const char *module_name)
= new_type_class(IDENT("Destructors"));
/* Set these flags for debugging. */
irp->segment_types[IR_SEGMENT_GLOBAL]->flags |= tf_global_type;
irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_tls_type;
irp->segment_types[IR_SEGMENT_CONSTRUCTORS]->flags |= tf_constructors;
irp->segment_types[IR_SEGMENT_DESTRUCTORS]->flags |= tf_destructors;
irp->segment_types[IR_SEGMENT_GLOBAL]->flags |= tf_segment|tf_global_type;
irp->segment_types[IR_SEGMENT_THREAD_LOCAL]->flags |= tf_segment|tf_tls_type;
irp->segment_types[IR_SEGMENT_CONSTRUCTORS]->flags |= tf_segment|tf_constructors;
irp->segment_types[IR_SEGMENT_DESTRUCTORS]->flags |= tf_segment|tf_destructors;
/* The global type is a class, but we cannot derive from it, so set
the final property to assist optimizations that checks for it. */
......
......@@ -59,8 +59,8 @@ ir_entity *get_unknown_entity(void) { return unknown_entity; }
/* ENTITY */
/*-----------------------------------------------------------------*/
static ir_entity *intern_new_entity(ir_type *owner, ident *name, ir_type *type,
dbg_info *dbgi)
static ir_entity *intern_new_entity(ir_type *owner, ir_entity_kind kind,
ident *name, ir_type *type, dbg_info *dbgi)
{
ir_entity *res;
......@@ -72,6 +72,7 @@ static ir_entity *intern_new_entity(ir_type *owner, ident *name, ir_type *type,
res->type = type;
res->owner = owner;
res->entity_kind = kind;
res->volatility = volatility_non_volatile;
res->aligned = align_is_aligned;
res->usage = ir_usage_unknown;
......@@ -99,12 +100,13 @@ static ir_entity *intern_new_entity(ir_type *owner, ident *name, ir_type *type,
ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
dbg_info *db)
{
ir_entity *res = intern_new_entity(owner, name, type, db);
ir_entity *res;
if (is_Method_type(type)) {
ir_graph *irg = get_const_code_irg();
symconst_symbol sym;
ir_mode *mode = is_Method_type(type) ? mode_P_code : mode_P_data;
res = intern_new_entity(owner, IR_ENTITY_METHOD, name, type, db);
sym.entity_p = res;
set_atomic_ent_value(res, new_r_SymConst(irg, mode, sym, symconst_addr_ent));
res->linkage = IR_LINKAGE_CONSTANT;
......@@ -113,11 +115,13 @@ ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type,
res->attr.mtd_attr.param_access = NULL;
res->attr.mtd_attr.param_weight = NULL;
res->attr.mtd_attr.irg = NULL;
} else if (is_compound_type(type)) {
} else if (owner != NULL
&& (is_compound_type(owner) && !(owner->flags & tf_segment))) {
res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db);
res->attr.cmpd_attr.values = NULL;
res->attr.cmpd_attr.val_paths = NULL;
} else if (is_code_type(type)) {
res->attr.code_attr.label = (ir_label_t) -1;
} else {
res = intern_new_entity(owner, IR_ENTITY_NORMAL, name, type, db);
}
hook_new_entity(res);
......@@ -139,9 +143,9 @@ static ident *make_parameter_entity_name(size_t pos)
ir_entity *new_d_parameter_entity(ir_type *owner, size_t pos, ir_type *type,
dbg_info *dbgi)
{
ident *name = make_parameter_entity_name(pos);
ir_entity *res = intern_new_entity(owner, name, type, dbgi);
res->is_parameter = true;
ident *name = make_parameter_entity_name(pos);
ir_entity *res
= intern_new_entity(owner, IR_ENTITY_PARAMETER, name, type, dbgi);
res->attr.parameter.number = pos;
hook_new_entity(res);
return res;
......@@ -152,6 +156,23 @@ ir_entity *new_parameter_entity(ir_type *owner, size_t pos, ir_type *type)
return new_d_parameter_entity(owner, pos, type, NULL);
}
ir_entity *new_d_label_entity(ir_label_t label, dbg_info *dbgi)
{
ident *name = id_unique("label_%u");
ir_type *global_type = get_glob_type();
ir_entity *res
= intern_new_entity(global_type, IR_ENTITY_LABEL, name, firm_code_type,
dbgi);
res->attr.code_attr.label = label;
hook_new_entity(res);
return res;
}
ir_entity *new_label_entity(ir_label_t label)
{
return new_d_label_entity(label, NULL);
}
/**
* Free entity attributes.
*
......@@ -175,9 +196,9 @@ static void free_entity_attrs(ir_entity *ent)
* multiple times */
ent->attr.cmpd_attr.val_paths = NULL;
}
if (is_compound_entity(ent)) {
if (ent->entity_kind == IR_ENTITY_COMPOUND_MEMBER) {
ent->attr.cmpd_attr.values = NULL;
} else if (is_method_entity(ent)) {
} else if (ent->entity_kind == IR_ENTITY_METHOD) {
if (ent->attr.mtd_attr.param_access) {
DEL_ARR_F(ent->attr.mtd_attr.param_access);
ent->attr.mtd_attr.param_access = NULL;
......@@ -338,9 +359,22 @@ ir_type *(get_entity_type)(const ir_entity *ent)
return _get_entity_type(ent);
}
void (set_entity_type)(ir_entity *ent, ir_type *type)
void set_entity_type(ir_entity *ent, ir_type *type)
{
_set_entity_type(ent, type);
switch (ent->entity_kind) {
case IR_ENTITY_METHOD:
assert(is_Method_type(type));
break;
case IR_ENTITY_NORMAL:
assert(!is_Method_type(type));
break;
case IR_ENTITY_LABEL:
assert(type == firm_code_type);
break;
case IR_ENTITY_COMPOUND_MEMBER:
break;
}
ent->type = type;
}
ir_volatility (get_entity_volatility)(const ir_entity *ent)
......@@ -399,11 +433,13 @@ const char *get_align_name(ir_align a)
void set_entity_label(ir_entity *ent, ir_label_t label)
{
assert(ent->entity_kind == IR_ENTITY_LABEL);
ent->attr.code_attr.label = label;
}
ir_label_t get_entity_label(const ir_entity *ent)
{
assert(ent->entity_kind == IR_ENTITY_LABEL);
return ent->attr.code_attr.label;
}
......
......@@ -111,6 +111,13 @@ typedef struct parameter_ent_attr {
lowering...) */
} parameter_ent_attr;
typedef enum ir_entity_kind {
IR_ENTITY_NORMAL,
IR_ENTITY_METHOD,
IR_ENTITY_COMPOUND_MEMBER,
IR_ENTITY_PARAMETER,
IR_ENTITY_LABEL,
} ir_entity_kind;
/**
* An abstract data type to represent program entities.
......@@ -124,6 +131,7 @@ struct ir_entity {
ir_type *type; /**< The type of this entity */
ir_type *owner; /**< The compound type (e.g. class type) this
entity belongs to. */
unsigned entity_kind:3; /**< entity kind */
unsigned linkage:10; /**< Specifies linkage type */
unsigned volatility:1; /**< Specifies volatility of entities content.*/
unsigned aligned:1; /**< Specifies alignment of entities content. */
......@@ -139,7 +147,6 @@ struct ir_entity {
/**< If the entity is a bit field, this is the
offset of the start of the bit field
within the byte specified by offset. */
unsigned is_parameter:1; /**< 1 if this represents a function parameter */
int offset; /**< Offset in bytes for this entity. Fixed
when layout of owner is determined. */
unsigned alignment; /**< entity alignment in bytes */
......@@ -177,6 +184,17 @@ void ir_init_entity(void);
/** Cleanup entity module */
void ir_finish_entity(void);
/**
* Creates an entity corresponding to the start address of a basic block
* (the basic block is marked with a label id).
*/
ir_entity *new_label_entity(ir_label_t label);
/**
* Like new_label_entity() but with debug information.
*/
ir_entity *new_d_label_entity(ir_label_t label, dbg_info *dbgi);
/* ----------------------- inline functions ------------------------ */
static inline int _is_entity(const void *thing)
{
......@@ -233,12 +251,6 @@ static inline ir_type *_get_entity_type(const ir_entity *ent)
return ent->type;
}
static inline void _set_entity_type(ir_entity *ent, ir_type *type)
{
assert(ent && ent->kind == k_entity);
ent->type = type;
}
static inline ir_linkage _get_entity_linkage(const ir_entity *ent)
{
assert(ent && ent->kind == k_entity);
......@@ -381,12 +393,12 @@ static inline int _entity_not_visited(const ir_entity *ent)
static inline int _is_parameter_entity(const ir_entity *entity)
{
return entity->is_parameter;
return entity->entity_kind == IR_ENTITY_PARAMETER;
}
static inline size_t _get_entity_parameter_number(const ir_entity *entity)
{
assert(entity->is_parameter);
assert(entity->entity_kind == IR_ENTITY_PARAMETER);
return entity->attr.parameter.number;
}
......@@ -415,7 +427,6 @@ static inline void _set_entity_dbg_info(ir_entity *ent, dbg_info *db)
#define set_entity_ld_ident(ent, ld_ident) _set_entity_ld_ident(ent, ld_ident)
#define get_entity_ld_name(ent) _get_entity_ld_name(ent)
#define get_entity_type(ent) _get_entity_type(ent)
#define set_entity_type(ent, type) _set_entity_type(ent, type)
#define get_entity_linkage(ent) _get_entity_linkage(ent)
#define get_entity_volatility(ent) _get_entity_volatility(ent)
#define set_entity_volatility(ent, vol) _set_entity_volatility(ent, vol)
......
......@@ -134,10 +134,11 @@ enum type_flags {
tf_layout_fixed = 1U << 1, /**< Set if the layout of a type is fixed */
tf_frame_type = 1U << 2, /**< Set if this is a frame type. */
tf_global_type = 1U << 3, /**< Set only for the global type */
tf_tls_type = 1U << 4, /**< Set only for the tls type */
tf_constructors = 1U << 5, /**< Set only for the constructors segment type */
tf_destructors = 1U << 6, /**< Set only for the destructors segment type */
tf_segment = 1U << 3, /**< type represents a linker segment */
tf_global_type = 1U << 4, /**< Set only for the global type */
tf_tls_type = 1U << 5, /**< Set only for the tls type */
tf_constructors = 1U << 6, /**< Set only for the constructors segment type */
tf_destructors = 1U << 7, /**< Set only for the destructors segment type */
};
ENUM_BITSET(type_flags)
......
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