From c1bd56d11a4f3ca77c05355fd72e16854ce71749 Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 1 Oct 2018 00:29:56 +0200 Subject: [PATCH] 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. --- mach/proto/mcg/hop.c | 6 ++++- mach/proto/mcg/ir.c | 1 + mach/proto/mcg/ir.h | 2 ++ mach/proto/mcg/pass_assignvregs.c | 19 ++++++++++--- mach/proto/mcg/pass_instructionselection.c | 1 + mach/proto/mcg/pass_lowerpushes.c | 2 ++ mach/proto/mcg/pass_registerallocator.c | 31 ++++++++++++++++++++++ mach/proto/mcg/procedure.c | 8 ++++-- mach/proto/mcg/treebuilder.c | 2 +- util/mcgg/build.lua | 1 + util/mcgg/registers.h | 2 +- 11 files changed, 66 insertions(+), 9 deletions(-) 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 -- 2.34.1