differntiate entity kinds
authorMatthias Braun <matze@braunis.de>
Wed, 16 Nov 2011 23:08:12 +0000 (00:08 +0100)
committerMatthias Braun <matze@braunis.de>
Thu, 17 Nov 2011 15:37:13 +0000 (16:37 +0100)
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.

ir/ir/irnode.c
ir/ir/irprog.c
ir/tr/entity.c
ir/tr/entity_t.h
ir/tr/type_t.h

index 63816e6..0f9e404 100644 (file)
@@ -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;
index e6abb6e..51e3637 100644 (file)
@@ -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. */
index b70c0d7..bd019b5 100644 (file)
@@ -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;
 }
 
index 3e7c44f..fe33ade 100644 (file)
@@ -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)
index 013e82b..ba5f2a2 100644 (file)
@@ -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)