From: David Given Date: Sun, 30 Sep 2018 22:29:56 +0000 (+0200) Subject: values and vregs for which we have no register class information don't default X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c1bd56d11a4f3ca77c05355fd72e16854ce71749;p=ack.git values and vregs for which we have no register class information don't default to ints now (as this was causing empty register sets when trying to coalesce an int and a double). It seems to work now, although painfully slowly. --- diff --git a/mach/proto/mcg/hop.c b/mach/proto/mcg/hop.c index 0c0f88b77..c96af168b 100644 --- a/mach/proto/mcg/hop.c +++ b/mach/proto/mcg/hop.c @@ -318,7 +318,9 @@ static struct vreg* actual(struct vreg* vreg) void appendvreg(struct vreg* vreg) { - appendf("($%d:%d=%%%d", vreg->value->ir->id, vreg->value->subid, vreg->id); + appendf("($%d:%d=%%%d:%s", + vreg->value->ir->id, vreg->value->subid, vreg->id, + vreg->regclass ? vreg->regclass->name : "?"); if (vreg->hreg != -1) appendf("=R%d", vreg->hreg); if (vreg->is_spilt) @@ -357,6 +359,8 @@ static void appendheader(struct hop* hop) if (usage->corrupted) appendf("!"); appendf("$%d:%d", value->ir->id, value->subid); + if (value->regclass != UNASSIGNED_REGCLASS) + appendf(",%d", value->regclass); } } } diff --git a/mach/proto/mcg/ir.c b/mach/proto/mcg/ir.c index e6e5d6b69..c6a9160a7 100644 --- a/mach/proto/mcg/ir.c +++ b/mach/proto/mcg/ir.c @@ -22,6 +22,7 @@ struct ir* new_ir0(int opcode, int size) { struct ir* ir = calloc(1, sizeof(struct ir)); ir->value.ir = ir; + ir->value.regclass = UNASSIGNED_REGCLASS; ir->id = next_id++; ir->opcode = opcode; ir->size = size; diff --git a/mach/proto/mcg/ir.h b/mach/proto/mcg/ir.h index 0da01a091..4389766ba 100644 --- a/mach/proto/mcg/ir.h +++ b/mach/proto/mcg/ir.h @@ -3,6 +3,8 @@ #include "ircodes.h" +#define UNASSIGNED_REGCLASS (-1) + struct value { struct ir* ir; diff --git a/mach/proto/mcg/pass_assignvregs.c b/mach/proto/mcg/pass_assignvregs.c index 3a6f3011a..de8207587 100644 --- a/mach/proto/mcg/pass_assignvregs.c +++ b/mach/proto/mcg/pass_assignvregs.c @@ -51,11 +51,22 @@ static bool hop_reads_value(struct hop* hop, struct value* value) static void setup_regclass(struct vreg* vreg, struct value* value) { - const struct burm_regclass_data* regclass = &burm_regclass_data[value->regclass]; - assert(!vreg->regclass || (vreg->regclass == regclass)); - - if (!vreg->regclass) + const struct burm_regclass_data* regclass = + (value->regclass == UNASSIGNED_REGCLASS) + ? NULL + : &burm_regclass_data[value->regclass]; + assert(!vreg->regclass || !regclass || (vreg->regclass == regclass)); + + tracef('V', "V: %%%d has class %s; value $%d has class %s\n", + vreg->id, + vreg->regclass ? vreg->regclass->name : "?", + value->ir->id, + regclass ? regclass->name : "?"); + + if (!vreg->regclass && regclass) { + tracef('V', "V: assigning register class %s to %%%d from $%d\n", + regclass->name, vreg->id, value->ir->id); memcpy(vreg->registers, regclass->bitmap, sizeof(burm_register_bitmap_t)); vreg->regclass = regclass; } diff --git a/mach/proto/mcg/pass_instructionselection.c b/mach/proto/mcg/pass_instructionselection.c index 2631c1d92..a9f5f87fd 100644 --- a/mach/proto/mcg/pass_instructionselection.c +++ b/mach/proto/mcg/pass_instructionselection.c @@ -141,6 +141,7 @@ static struct insn* walk_instructions(struct burm_node* node, int goal) int i; insn->value.ir = current_ir; + insn->value.regclass = UNASSIGNED_REGCLASS; /* hop IDs count in preorder, so the result is always in $thing:0. */ insn->value.subid = hop_id++; diff --git a/mach/proto/mcg/pass_lowerpushes.c b/mach/proto/mcg/pass_lowerpushes.c index c990f862e..3550d8c91 100644 --- a/mach/proto/mcg/pass_lowerpushes.c +++ b/mach/proto/mcg/pass_lowerpushes.c @@ -108,6 +108,7 @@ static void consider_push(struct ir* ir) new_wordir(delta) ); ir->left->root = ir->left->left->root = ir->left->right->root = ir->root; + ir->left->bb = ir->left->left->bb = ir->left->right->bb = current_bb; ir->right = value_ir; delta += ir->size; @@ -119,6 +120,7 @@ static void consider_push(struct ir* ir) ir = new_ir1(IR_STACKADJUST, EM_pointersize, new_wordir(-delta)); ir->left->root = ir->root = ir; + ir->left->bb = ir->bb = current_bb; array_insert(¤t_bb->irs, ir, runstart); cursor++; } diff --git a/mach/proto/mcg/pass_registerallocator.c b/mach/proto/mcg/pass_registerallocator.c index 8678b382f..d6e889d0d 100644 --- a/mach/proto/mcg/pass_registerallocator.c +++ b/mach/proto/mcg/pass_registerallocator.c @@ -15,6 +15,16 @@ static struct graph interference; static struct graph affinity; static ARRAYOF(struct vreg) simplified; +static void bitmap_trace(void* bitmap, int size) +{ + uint8_t* p = bitmap; + int bytes = ((size-1) / 8) + 1; + int i; + + for (i=0; iregclass) + { + tracef('R', "R: master is %10s ", vmaster->regclass->name); + bitmap_trace(vmaster->registers, burm_register_count); + tracef('R', "\n"); + } + if (vslave->regclass) + { + tracef('R', "R: slave is %10s ", vslave->regclass->name); + bitmap_trace(vslave->registers, burm_register_count); + tracef('R', "\n"); + } + } + if (vmaster->regclass && vslave->regclass) { bitmap_and(vmaster->registers, burm_register_count, vslave->registers); @@ -101,7 +127,12 @@ static void generate_graph(void) } if (hop->is_move && invreg1 && outvreg1) + { + tracef('R', "R: adding affinity edge between %%%d and %%%d:\n", + invreg1->id, outvreg1->id); + hop_print('R', hop); graph_add_edge(&affinity, invreg1, outvreg1); + } } /* Ensure that registers which are constrained to be in the same hreg for input diff --git a/mach/proto/mcg/procedure.c b/mach/proto/mcg/procedure.c index f7dc813d1..418d09955 100644 --- a/mach/proto/mcg/procedure.c +++ b/mach/proto/mcg/procedure.c @@ -106,7 +106,9 @@ static void print_hops(char k) { struct value* value = hit.key; struct vreg* vreg = hit.value; - tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id); + tracef(k, " $%d.%d->%%%d(%s)", + value->ir->id, value->subid, vreg->id, + vreg->regclass ? vreg->regclass->name : "?"); } tracef(k, "\n"); } @@ -119,7 +121,9 @@ static void print_hops(char k) { struct value* value = hit.key; struct vreg* vreg = hit.value; - tracef(k, " $%d.%d->%%%d", value->ir->id, value->subid, vreg->id); + tracef(k, " $%d.%d->%%%d(%s)", + value->ir->id, value->subid, vreg->id, + vreg->regclass ? vreg->regclass->name : "?"); } tracef(k, "\n"); } diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 0e9c9a879..d0e8fe989 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -1859,7 +1859,7 @@ static void emit_jumptable(struct ir* targetvalue, struct jumptable* jumptable) materialise_stack(); while (hashtable_next(&jumptable->targets, &hit)) { - int value = (int) hit.key; + int value = (int)(intptr_t) hit.key; struct basicblock* target = hit.value; struct basicblock* nextblock = bb_get(NULL); diff --git a/util/mcgg/build.lua b/util/mcgg/build.lua index 1bd242a10..ebb4e721d 100644 --- a/util/mcgg/build.lua +++ b/util/mcgg/build.lua @@ -47,6 +47,7 @@ cprogram { matching(filenamesof("+yacc"), "%.c$") }, deps = { + "./registers.h", "./iburg.h", "+lib", "+yacc", diff --git a/util/mcgg/registers.h b/util/mcgg/registers.h index 53145f1c5..7162a7e6d 100644 --- a/util/mcgg/registers.h +++ b/util/mcgg/registers.h @@ -30,7 +30,6 @@ extern struct reg* makereg(const char* name); extern void setregnames(struct reg* reg, struct stringlist* names); extern void addregattr(struct reg* reg, const char* regattr); extern void addregusage(struct reg* reg, struct stringlist* uses); -extern struct regattr* getregattr(const char* name); extern void analyse_registers(void); @@ -38,6 +37,7 @@ extern void emitregisterattrs(void); extern void emitregisters(void); extern struct regattr* findregattr(const char* name); +extern struct regattr* makeregattr(const char* name); #endif