summaryrefslogtreecommitdiffhomepage
path: root/ir/ir
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2018-08-08 11:09:02 +0200
committerSebastian Graf <sebastian.graf@kit.edu>2018-08-08 11:10:32 +0200
commit753fb6ff320a43ec9686dda5ddd12b7b5bbb14f2 (patch)
treeebd7fa49c7d834edb9cb5a5bcc8e570badf226a2 /ir/ir
parent26104c198f8a41b4f4b8a565cc522c76b54934b5 (diff)
irio: Don't squash all imported frame types together
The previous attempt to reduce redundancy in imported and then exported IR files in 26140a7 led to all imported IR graphs referencing the same (global) frame type. This commit partly reverts the aggressive deduplication of 26140a7, while still combining identifying initial types added by `ir_init()` by their `type_nr`. This would again result in many redundant frame types, because the call to `new_ir_graph` generates a new frame type each time it is called, which is not freed when replaced by another frame type (the one we read from the IR file to import) through a call to `set_irg_frame_type`. The solution is of course to free the initially allocated frame type with `free_type`.
Diffstat (limited to 'ir/ir')
-rw-r--r--ir/ir/irio.c95
1 files changed, 19 insertions, 76 deletions
diff --git a/ir/ir/irio.c b/ir/ir/irio.c
index 8aecb8b..db32208 100644
--- a/ir/ir/irio.c
+++ b/ir/ir/irio.c
@@ -1627,21 +1627,23 @@ static void read_type(read_env_t *env)
// That would destroy idempotency for `ir_export . ir_import`
// and bloat the resulting IR files.
+ for (int i = 0; i < n_initial_types; ++i) {
+ ir_type *t = get_irp_type(i);
+ if (typenr != get_type_nr(t)) {
+ continue;
+ }
+ type = t;
+ // There are potentially more fields to compare, but this should
+ // be indicative enough if anything went wrong.
+ assert(type_matches(type, opcode, size, align, state, flags));
+ skip_to(env, '\n');
+ goto extend_env;
+ }
+
switch (opcode) {
case tpo_array: {
ir_type *const elemtype = read_type_ref(env);
unsigned const length = read_unsigned(env);
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && other->attr.array.element_type == elemtype
- && other->attr.array.size == length) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_array(elemtype, length);
set_type_size(type, size);
goto finish_type;
@@ -1650,15 +1652,6 @@ static void read_type(read_env_t *env)
case tpo_class: {
ident *id = read_ident_null(env);
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && streq_null(other->name, id)) {
- type = other;
- goto extend_env;
- }
- }
-
if (typenr == (long) IR_SEGMENT_GLOBAL)
type = get_glob_type();
else
@@ -1689,40 +1682,17 @@ static void read_type(read_env_t *env)
set_method_res_type(type, i, restype);
}
- // Don't try to deduplicate methods for now. AFAICT, these are not added by
- // ir_init(), so it won't matter wrt. idempotence.
-
goto finish_type;
}
case tpo_pointer: {
ir_type *points_to = get_type(env, read_long(env));
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && other->attr.pointer.points_to == points_to) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_pointer(points_to);
goto finish_type;
}
case tpo_primitive: {
ir_mode *mode = read_mode_ref(env);
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && other->mode == mode) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_primitive(mode);
set_type_size(type, size);
goto finish_type;
@@ -1730,16 +1700,6 @@ static void read_type(read_env_t *env)
case tpo_struct: {
ident *id = read_ident_null(env);
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && streq_null(other->name, id)) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_struct(id);
set_type_size(type, size);
goto finish_type;
@@ -1747,16 +1707,6 @@ static void read_type(read_env_t *env)
case tpo_union: {
ident *id = read_ident_null(env);
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && streq_null(other->name, id)) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_union(id);
set_type_size(type, size);
goto finish_type;
@@ -1764,16 +1714,6 @@ static void read_type(read_env_t *env)
case tpo_segment: {
ident *id = read_ident_null(env);
-
- for (int i = 0; i < n_initial_types; ++i) {
- ir_type *other = get_irp_type(i);
- if (type_matches(other, opcode, size, align, state, flags)
- && streq_null(other->name, id)) {
- type = other;
- goto extend_env;
- }
- }
-
type = new_type_segment(id, 0);
goto finish_type;
}
@@ -2171,10 +2111,13 @@ next_delayed_pred: ;
static ir_graph *read_irg(read_env_t *env)
{
- ir_entity *irgent = get_entity(env, read_long(env));
- ir_graph *irg = new_ir_graph(irgent, 0);
- ir_type *frame = read_type_ref(env);
+ ir_entity *irgent = get_entity(env, read_long(env));
+ ir_graph *irg = new_ir_graph(irgent, 0);
+ ir_type *frame = read_type_ref(env);
+ ir_type *old_frame = get_irg_frame_type(irg);
set_irg_frame_type(irg, frame);
+ // Free the old frame type in order to retain idempotency
+ free_type(old_frame);
read_graph(env, irg);
irg_finalize_cons(irg);
return irg;