summaryrefslogtreecommitdiffhomepage
path: root/ir/tr
diff options
context:
space:
mode:
authorMatthias Braun <matze@braunis.de>2016-02-14 10:58:46 +0100
committerMatthias Braun <matze@braunis.de>2016-04-04 00:07:49 +0200
commitf2b6fca42c0970aa27fcdc5657968995b818a477 (patch)
tree90612104391774570d2238678096f4e6353ed6a5 /ir/tr
parentd4846b5b34b38e47db38da18d108ccab56188d37 (diff)
entity: Introduce spillslot entities
They are not used yet as we need an adapted layout algorithm for them.
Diffstat (limited to 'ir/tr')
-rw-r--r--ir/tr/entity.c16
-rw-r--r--ir/tr/entity_t.h15
-rw-r--r--ir/tr/trverify.c11
-rw-r--r--ir/tr/type.c3
-rw-r--r--ir/tr/typewalk.c1
5 files changed, 43 insertions, 3 deletions
diff --git a/ir/tr/entity.c b/ir/tr/entity.c
index 39915ec..92e4d64 100644
--- a/ir/tr/entity.c
+++ b/ir/tr/entity.c
@@ -118,6 +118,19 @@ ir_entity *new_label_entity(ir_label_t label)
return res;
}
+ir_entity *new_spillslot(ir_type *const frame, unsigned const size,
+ unsigned const alignment)
+{
+ assert(is_frame_type(frame));
+ ir_type *const type = get_unknown_type();
+ ir_entity *const res = intern_new_entity(frame, IR_ENTITY_SPILLSLOT, NULL,
+ type, ir_visibility_private);
+ set_entity_alignment(res, alignment);
+ res->attr.spillslot.base.offset = INVALID_OFFSET;
+ res->attr.spillslot.size = size;
+ return res;
+}
+
ir_entity *new_alias_entity(ir_type *owner, ident *name, ir_entity *aliased,
ir_type *type, ir_visibility visibility)
{
@@ -295,6 +308,8 @@ void set_entity_type(ir_entity *ent, ir_type *type)
case IR_ENTITY_UNKNOWN:
case IR_ENTITY_COMPOUND_MEMBER:
break;
+ case IR_ENTITY_SPILLSLOT:
+ panic("Cannot set type of this entity");
}
ent->type = type;
}
@@ -888,6 +903,7 @@ int entity_has_definition(const ir_entity *entity)
case IR_ENTITY_PARAMETER:
case IR_ENTITY_UNKNOWN:
case IR_ENTITY_COMPOUND_MEMBER:
+ case IR_ENTITY_SPILLSLOT:
return false;
}
panic("invalid entity kind");
diff --git a/ir/tr/entity_t.h b/ir/tr/entity_t.h
index 7eaba49..54ba086 100644
--- a/ir/tr/entity_t.h
+++ b/ir/tr/entity_t.h
@@ -154,6 +154,11 @@ typedef struct alias_ent_attr {
ir_entity *aliased;
} alias_ent_attr;
+typedef struct spillslot_ent_attr {
+ compound_member_ent_attr base;
+ unsigned size;
+} spillslot_ent_attr;
+
typedef enum ir_entity_kind {
IR_ENTITY_ALIAS,
IR_ENTITY_COMPOUND_MEMBER,
@@ -161,6 +166,7 @@ typedef enum ir_entity_kind {
IR_ENTITY_METHOD,
IR_ENTITY_NORMAL,
IR_ENTITY_PARAMETER,
+ IR_ENTITY_SPILLSLOT,
IR_ENTITY_UNKNOWN,
} ir_entity_kind;
@@ -208,6 +214,8 @@ struct ir_entity {
alias_ent_attr alias;
/** properties shared by global entities */
global_ent_attr global;
+ /** properties of spill slot entities */
+ spillslot_ent_attr spillslot;
} attr; /**< type specific attributes */
};
@@ -220,6 +228,8 @@ void ir_init_entity(ir_prog *irp);
*/
ir_entity *new_label_entity(ir_label_t label);
+ir_entity *new_spillslot(ir_type *frame, unsigned size, unsigned alignment);
+
void set_entity_irg(ir_entity *ent, ir_graph *irg);
/* ----------------------- inline functions ------------------------ */
@@ -274,6 +284,7 @@ static inline const char *_get_entity_ld_name(const ir_entity *ent)
static inline ir_type *_get_entity_type(const ir_entity *ent)
{
assert(ent->firm_tag == k_entity);
+ assert(ent->kind != IR_ENTITY_SPILLSLOT);
return ent->type;
}
@@ -334,7 +345,8 @@ static inline void _set_entity_usage(ir_entity *ent, ir_entity_usage state)
static inline bool is_entity_compound_member(const ir_entity *entity)
{
return entity->kind == IR_ENTITY_COMPOUND_MEMBER
- || entity->kind == IR_ENTITY_PARAMETER;
+ || entity->kind == IR_ENTITY_PARAMETER
+ || entity->kind == IR_ENTITY_SPILLSLOT;
}
static inline ir_initializer_t *_get_entity_initializer(ir_entity const *const ent)
@@ -470,6 +482,7 @@ static inline bool is_global_entity(ir_entity const *const entity)
case IR_ENTITY_LABEL:
case IR_ENTITY_PARAMETER:
case IR_ENTITY_UNKNOWN:
+ case IR_ENTITY_SPILLSLOT:
return false;
}
panic("Invalid entity");
diff --git a/ir/tr/trverify.c b/ir/tr/trverify.c
index 5e19b38..3b5b22d 100644
--- a/ir/tr/trverify.c
+++ b/ir/tr/trverify.c
@@ -330,6 +330,17 @@ int check_entity(const ir_entity *entity)
case IR_ENTITY_UNKNOWN:
break;
+
+ case IR_ENTITY_SPILLSLOT:
+ if (is_frame_type(owner)) {
+ report_error("spillslot %+F must be on frame type", entity);
+ fine = false;
+ }
+ break;
+ }
+ if (is_frame_type(owner) && entity_has_definition(entity)) {
+ report_error("entity %+F on frame %+F has initialized", entity, owner);
+ fine = false;
}
return fine;
diff --git a/ir/tr/type.c b/ir/tr/type.c
index 395b00e..1ef596f 100644
--- a/ir/tr/type.c
+++ b/ir/tr/type.c
@@ -285,7 +285,7 @@ void set_type_state(ir_type *tp, ir_type_state state)
for (size_t i = 0, n_mem = get_compound_n_members(tp);
i < n_mem; i++) {
ir_entity *entity = get_compound_member(tp, i);
- if (is_Method_type(get_entity_type(entity)))
+ if (is_method_entity(entity))
continue;
assert(get_entity_offset(entity) != INVALID_OFFSET);
}
@@ -991,7 +991,6 @@ void add_compound_member(ir_type *type, ir_entity *entity)
{
assert(is_compound_type(type));
/* try to detect double-add */
- assert(get_entity_type(entity) != type);
ARR_APP1(ir_entity *, type->attr.compound.members, entity);
/* Add segment members to globals map. */
if (is_segment_type(type) && !(type->flags & tf_info)
diff --git a/ir/tr/typewalk.c b/ir/tr/typewalk.c
index fcf348d..d0f797a 100644
--- a/ir/tr/typewalk.c
+++ b/ir/tr/typewalk.c
@@ -112,6 +112,7 @@ static void do_type_walk(ir_type *const tp, ir_entity *const ent,
case IR_ENTITY_PARAMETER:
case IR_ENTITY_LABEL:
case IR_ENTITY_COMPOUND_MEMBER:
+ case IR_ENTITY_SPILLSLOT:
break;
}
} else {