From: David Given Date: Sun, 22 Jan 2017 22:31:22 +0000 (+0100) Subject: Add a fairly clunky pass which converts @copy pseudos into moves. Seems to X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=03fd47756056ee726041caae70d2da212fd4f99b;p=ack.git Add a fairly clunky pass which converts @copy pseudos into moves. Seems to work, but needs more thought. --- diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index a6b57f9c6..67ebfa09c 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -55,9 +55,21 @@ static struct insel* new_insel(enum insel_type type) void hop_add_string_insel(struct hop* hop, const char* string) { - struct insel* insel = new_insel(INSEL_STRING); - insel->u.string = string; - array_append(&hop->insels, insel); + if ((hop->insels.count == 0) && (string[0] == '@')) + { + char* pseudo = strdup(string+1); + char* end = strchr(pseudo, ' '); + if (end) + *end = '\0'; + + hop->pseudo = pseudo; + } + else if (!hop->pseudo) + { + struct insel* insel = new_insel(INSEL_STRING); + insel->u.string = string; + array_append(&hop->insels, insel); + } } void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index) @@ -326,21 +338,25 @@ char* hop_render(struct hop* hop) while (hashtable_next(hop->valueusage, &hit)) { struct valueusage* usage = hit.value; - struct vreg* left = actual(usage->invreg); - struct vreg* right = actual(usage->outvreg); - if (left != right) + if (usage->input && usage->output) { - appendf(" "); - appendvreg(usage->invreg); - appendf("->"); - appendvreg(usage->outvreg); + struct vreg* left = actual(usage->invreg); + struct vreg* right = actual(usage->outvreg); + if (left != right) + { + appendf(" "); + appendvreg(usage->invreg); + appendf("->"); + appendvreg(usage->outvreg); + } } } appendf("\n"); + return buffer; } if (hop->pseudo) - appendf("@"); + appendf("@%s ", hop->pseudo); for (i=0; iinsels.count; i++) { diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index 692127e6d..c7a81f0bb 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -109,6 +109,7 @@ extern void tb_regvar(struct procedure* proc, arith offset, int size, int type, extern void pass_assign_vregs(void); extern void pass_calculate_vreg_spillibility(void); +extern void pass_convert_copies_to_moves(void); extern void pass_convert_inputs_to_phis(void); extern void pass_convert_locals_to_ssa(void); extern void pass_convert_nonlocal_phis(void); diff --git a/mach/proto/mcg/pass_copiestomoves.c b/mach/proto/mcg/pass_copiestomoves.c new file mode 100644 index 000000000..f13b42b2c --- /dev/null +++ b/mach/proto/mcg/pass_copiestomoves.c @@ -0,0 +1,46 @@ +#include "mcg.h" + +void pass_convert_copies_to_moves(void) +{ + int i, j; + + for (i=0; ihops.count; j++) + { + struct hop* hop = bb->hops.item[j]; + if (hop->pseudo && (strcmp(hop->pseudo, "copy") == 0)) + { + struct valueusage* usage; + struct hashtable_iterator hit = {}; + struct vreg* invreg = NULL; + struct vreg* outvreg = NULL; + while (hashtable_next(hop->valueusage, &hit)) + { + usage = hit.value; + if (usage->input) + { + assert(!invreg); + invreg = usage->invreg; + } + if (usage->output) + { + assert(!outvreg); + outvreg = usage->outvreg; + } + } + assert(invreg && outvreg); + + usage = hop_get_value_usage(hop, outvreg->value); + assert(!usage->invreg); + assert(!usage->input); + usage->input = true; + usage->invreg = invreg; + hop->is_move = true; + } + } + } +} + +/* vim: set sw=4 ts=4 expandtab : */ diff --git a/mach/proto/mcg/procedure.c b/mach/proto/mcg/procedure.c index 100bbb44a..32bf39306 100644 --- a/mach/proto/mcg/procedure.c +++ b/mach/proto/mcg/procedure.c @@ -223,6 +223,7 @@ void procedure_compile(struct procedure* proc) print_hops('8'); pass_assign_vregs(); pass_calculate_vreg_spillibility(); + pass_convert_copies_to_moves(); print_hops('9'); pass_register_allocator(); #if 0