From: David Given Date: Thu, 12 Jan 2017 22:29:23 +0000 (+0100) Subject: Start putting the vreg stuff back in; vregs are now assigned (but we're not in X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3be05b80ae5d6cb4a6c2531668e1ab79dbe1764f;p=ack.git Start putting the vreg stuff back in; vregs are now assigned (but we're not in elementary form yet). --- diff --git a/mach/proto/mcg/basicblock.h b/mach/proto/mcg/basicblock.h index 00298f6c9..6edafad5e 100644 --- a/mach/proto/mcg/basicblock.h +++ b/mach/proto/mcg/basicblock.h @@ -21,6 +21,9 @@ struct basicblock PMAPOF(struct ir, struct ir) imports; PMAPOF(struct ir, struct ir) exports; + struct hashtable* inputmapping; + struct hashtable* outputmapping; + bool is_fake : 1; bool is_root : 1; bool is_terminated : 1; diff --git a/mach/proto/mcg/build.lua b/mach/proto/mcg/build.lua index a2ed528d2..df068449c 100644 --- a/mach/proto/mcg/build.lua +++ b/mach/proto/mcg/build.lua @@ -45,6 +45,9 @@ definerule("build_mcg", headers, tables, -- for .h file }, + vars = { + ["+cflags"] = "-Werror" + } } end ) diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index 1d9e857f9..5899275e3 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -187,36 +187,6 @@ void hop_walk(hop_walker_t* callback, void* user) } } -static void print_header(char k, struct hop* hop) -{ - int i; - - tracef(k, "%c: %d", k, hop->id); - if (hop->ir) - tracef(k, " from $%d", hop->ir->id); - tracef(k, ":"); - - for (i=0; iinputs.count; i++) - { - struct value* value = hop->inputs.item[i]; - tracef(k, " r$%d:%d", value->ir->id, value->subid); - } - - for (i=0; ioutputs.count; i++) - { - struct value* value = hop->outputs.item[i]; - tracef(k, " w$%d:%d", value->ir->id, value->subid); - } - - for (i=0; ithroughs.count; i++) - { - struct value* value = hop->throughs.item[i]; - tracef(k, " =$%d:%d", value->ir->id, value->subid); - } - - tracef(k, " "); -} - static char* appendf(const char* fmt, ...) { int n; @@ -243,6 +213,49 @@ static char* appendf(const char* fmt, ...) return p; } +void appendvalue(struct hop* hop, struct value* value) +{ + struct vreg* vreg; + + if (hop->vregmapping && ((vreg = hashtable_get(hop->vregmapping, value)))) + appendf("%%%d", vreg->id); + else + appendf("$%d:%d", value->ir->id, value->subid); +} + +static void appendheader(struct hop* hop) +{ + int i; + + appendf("%d", hop->id); + if (hop->ir) + appendf(" from $%d", hop->ir->id); + appendf(":"); + + for (i=0; iinputs.count; i++) + { + struct value* value = hop->inputs.item[i]; + appendf(" r"); + appendvalue(hop, value); + } + + for (i=0; ioutputs.count; i++) + { + struct value* value = hop->outputs.item[i]; + appendf(" w"); + appendvalue(hop, value); + } + + for (i=0; ithroughs.count; i++) + { + struct value* value = hop->throughs.item[i]; + appendf(" ="); + appendvalue(hop, value); + } + + appendf(" "); +} + char* hop_render(struct hop* hop) { int i; @@ -279,17 +292,7 @@ char* hop_render(struct hop* hop) case INSEL_VREG: { - struct value* value = insel->u.value; - #if 0 - struct hreg* hreg = pmap_findright(&hop->regsin, vreg); - if (!hreg) - hreg = pmap_findright(&hop->regsout, vreg); - if (hreg) - appendf("%s", hreg->brd->names[insel->index]); - else - appendf("%%%d.%d", vreg->id, insel->index); - #endif - appendf("$%d:%d", value->ir->id, value->subid); + appendvalue(hop, insel->u.value); if (insel->index) appendf(".%d", insel->index); break; @@ -357,11 +360,19 @@ void hop_print(char k, struct hop* hop) int i; bool soi = false; char* p; + char* header; + + appendf(""); /* ensure the buffer has been allocated */ + bufferlen = 0; + buffer[0] = '\0'; + + appendheader(hop); + header = strdup(buffer); hop_render(hop); p = strtok(buffer, "\n"); - print_header(k, hop); + tracef(k, "%c: %s", k, header); while (p) { tracef(k, "%s", p); @@ -369,7 +380,7 @@ void hop_print(char k, struct hop* hop) if (p) { tracef(k, "\n"); - print_header(k, hop); + tracef(k, "%c: %s", k, header); } } tracef(k, "\n"); diff --git a/mach/proto/mcg/hop.h b/mach/proto/mcg/hop.h index b97ed9b0e..6a97d8535 100644 --- a/mach/proto/mcg/hop.h +++ b/mach/proto/mcg/hop.h @@ -43,6 +43,8 @@ struct hop ARRAYOF(struct value) inputs; ARRAYOF(struct value) outputs; ARRAYOF(struct value) throughs; + + struct hashtable* vregmapping; }; extern struct hop* new_hop(struct basicblock* bb, struct ir* ir); diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index e8b46592e..19f259018 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -8,6 +8,7 @@ #include #include #include +#include "hashtable.h" #include "flt_arith.h" #include "em_arith.h" #include "em_label.h" @@ -30,7 +31,6 @@ #include "graph.h" #include "tables.h" #include "mcgg.h" -#include "hashtable.h" #include "set.h" #include "bigraph.h" @@ -107,6 +107,7 @@ extern void tb_fileend(void); extern void tb_procedure(void); extern void tb_regvar(struct procedure* proc, arith offset, int size, int type, int priority); +extern void pass_assign_vregs(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_assignvregs.c b/mach/proto/mcg/pass_assignvregs.c new file mode 100644 index 000000000..57bd2f42e --- /dev/null +++ b/mach/proto/mcg/pass_assignvregs.c @@ -0,0 +1,103 @@ +#include "mcg.h" + +static const struct hashtable empty_hashtable_of_values = HASHTABLE_OF_VALUES; + +static struct basicblock* current_bb; + +static int vregcount = 0; + +static void create_and_map_vreg(struct hashtable* mapping, struct value* value) +{ + struct vreg* vreg = heap_alloc(&proc_heap, 1, sizeof(*vreg)); + vreg->id = vregcount++; + vreg->value = value; + + assert(!hashtable_get(mapping, value)); + hashtable_put(mapping, value, vreg); +} + +static bool hop_reads_value(struct hop* hop, struct value* value) +{ + int i; + + for (i=0; iinputs.count; i++) + if (value_comparison_function(hop->inputs.item[i], value)) + return true; + + for (i=0; ithroughs.count; i++) + if (value_comparison_function(hop->throughs.item[i], value)) + return true; + + return false; +} + +static void assign_vregs(void) +{ + int i, j; + struct hashtable* previous_mapping; + struct hashtable* current_mapping; + struct hop* hop; + + /* Preload the mapping from the first hop. It might be a move, but that + * does no harm. */ + + hop = current_bb->hops.item[0]; + current_bb->inputmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable)); + *current_bb->inputmapping = empty_hashtable_of_values; + hashtable_empty(current_bb->inputmapping); + for (i=0; iinputs.count; i++) + create_and_map_vreg(current_bb->inputmapping, hop->inputs.item[i]); + for (i=0; ithroughs.count; i++) + create_and_map_vreg(current_bb->inputmapping, hop->throughs.item[i]); + + previous_mapping = current_bb->inputmapping; + for (i=0; ihops.count; i++) + { + hop = current_bb->hops.item[i]; + + /* TODO: clone vregs here */ + + /* Copy the previous mapping to this hop, pruning out any unused values. */ + + current_mapping = hop->vregmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));; + *current_mapping = empty_hashtable_of_values; + { + struct hashtable_iterator hit = {}; + while (hashtable_next(previous_mapping, &hit)) + { + struct value* value = hit.key; + if (hop_reads_value(hop, value)) + hashtable_put(current_mapping, value, hit.value); + } + } + + /* Create vregs for any new outputs. */ + + for (j=0; joutputs.count; j++) + create_and_map_vreg(current_mapping, hop->outputs.item[j]); + + /* And move on to the next one. */ + + previous_mapping = current_mapping; + } + + current_bb->outputmapping = previous_mapping; +} + +void pass_assign_vregs(void) +{ + int i; + + vregcount = 0; + + for (i=0; i