From 27a20bdf994614f76cef8c317f3cb4f41925c9fa Mon Sep 17 00:00:00 2001 From: David Given Date: Fri, 13 Jan 2017 21:17:16 +0100 Subject: [PATCH] Clone all the vregs just before and after every instruction, so converting the program into elementary form. --- mach/proto/mcg/hop.c | 9 ++++++- mach/proto/mcg/hop.h | 1 + mach/proto/mcg/pass_assignvregs.c | 41 ++++++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 5 deletions(-) diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index 5899275e3..85c859520 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -268,7 +268,14 @@ char* hop_render(struct hop* hop) appendf("@"); if (hop->is_move && (hop->insels.count == 0)) - appendf("(move)\n"); + { + appendf("(move"); + for (i=0; icopies.count; i++) + appendf(" %%%d->%%%d", + hop->copies.item[i].left->id, + hop->copies.item[i].right->id); + appendf(")"); + } for (i=0; iinsels.count; i++) { diff --git a/mach/proto/mcg/hop.h b/mach/proto/mcg/hop.h index 7e4b443e2..0c56984fd 100644 --- a/mach/proto/mcg/hop.h +++ b/mach/proto/mcg/hop.h @@ -46,6 +46,7 @@ struct hop ARRAYOF(struct value) corrupted; struct hashtable* vregmapping; + PMAPOF(struct vreg, struct vreg) copies; }; extern struct hop* new_hop(struct basicblock* bb, struct ir* ir); diff --git a/mach/proto/mcg/pass_assignvregs.c b/mach/proto/mcg/pass_assignvregs.c index 57bd2f42e..e58a52814 100644 --- a/mach/proto/mcg/pass_assignvregs.c +++ b/mach/proto/mcg/pass_assignvregs.c @@ -6,16 +6,41 @@ static struct basicblock* current_bb; static int vregcount = 0; -static void create_and_map_vreg(struct hashtable* mapping, struct value* value) +static struct vreg* create_vreg(struct value* value) { struct vreg* vreg = heap_alloc(&proc_heap, 1, sizeof(*vreg)); vreg->id = vregcount++; vreg->value = value; + return vreg; +} +static void create_and_map_vreg(struct hashtable* mapping, struct value* value) +{ + struct vreg* vreg = create_vreg(value); assert(!hashtable_get(mapping, value)); hashtable_put(mapping, value, vreg); } +static struct hop* create_move(struct hashtable* previous_mapping) +{ + struct hop* hop = new_hop(current_bb, NULL); + hop->vregmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));; + *hop->vregmapping = empty_hashtable_of_values; + hop->is_move = true; + + struct hashtable_iterator hit = {}; + while (hashtable_next(previous_mapping, &hit)) + { + struct value* value = hit.key; + struct vreg* oldvreg = hit.value; + struct vreg* newvreg = create_vreg(value); + hashtable_put(hop->vregmapping, value, newvreg); + pmap_add(&hop->copies, oldvreg, newvreg); + } + + return hop; +} + static bool hop_reads_value(struct hop* hop, struct value* value) { int i; @@ -53,12 +78,16 @@ static void assign_vregs(void) previous_mapping = current_bb->inputmapping; for (i=0; ihops.count; i++) { - hop = current_bb->hops.item[i]; + /* Insert a parallel-move hop to copy all the vregs. */ - /* TODO: clone vregs here */ + struct hop* move = create_move(previous_mapping); + array_insert(¤t_bb->hops, move, i); + i++; + previous_mapping = move->vregmapping; /* Copy the previous mapping to this hop, pruning out any unused values. */ + hop = current_bb->hops.item[i]; current_mapping = hop->vregmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));; *current_mapping = empty_hashtable_of_values; { @@ -81,7 +110,11 @@ static void assign_vregs(void) previous_mapping = current_mapping; } - current_bb->outputmapping = previous_mapping; + /* Insert one final move at the end of the block. */ + + hop = create_move(previous_mapping); + array_append(¤t_bb->hops, hop); + current_bb->outputmapping = hop->vregmapping; } void pass_assign_vregs(void) -- 2.34.1