From b74c8e7fd16184a9fb1f03230258845c78a43dd5 Mon Sep 17 00:00:00 2001 From: Pat Gavlin Date: Tue, 21 May 2019 15:44:01 -0700 Subject: [PATCH] WIP: attempt to fix spill code The results of targeting inserted reloads were being silently discarded, which resulted in #76. These changes stop discarding these results and label/reduce any resulting copies. --- Utils/lcc/lburg/lburg.c | 11 +++++++++++ Utils/lcc/src/config.h | 1 + Utils/lcc/src/gen.c | 19 +++++++++++-------- Utils/lcc/src/gt1.md | 14 +++++++++++++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/Utils/lcc/lburg/lburg.c b/Utils/lcc/lburg/lburg.c index 846556a22..45c044ef5 100755 --- a/Utils/lcc/lburg/lburg.c +++ b/Utils/lcc/lburg/lburg.c @@ -644,6 +644,17 @@ static void emitstring(Rule rules) { print(",%1/* %R */\n", r); } print("};\n"); + print("static char *%Pactionnames[] = {\n"); + print("/* 0 */%10,\n"); + for (r = rules; r; r = r->link) { + print("/* %d */%1", r->ern); + if (r->action->code == 0) + print("0"); + else + print("\"%s\"", r->action->code); + print(",%1/* %R */\n", r); + } + print("};\n"); print("static char *%Ptemplates[] = {\n"); print("/* 0 */%10,\n"); for (r = rules; r; r = r->link) { diff --git a/Utils/lcc/src/config.h b/Utils/lcc/src/config.h index 0a11978ef..7d14a185b 100755 --- a/Utils/lcc/src/config.h +++ b/Utils/lcc/src/config.h @@ -14,6 +14,7 @@ typedef struct { void (*_kids)(Node, int, Node*); char **_string; Action *_actions; + char **_actionnames; char **_templates; char *_isinstruction; char **_ntname; diff --git a/Utils/lcc/src/gen.c b/Utils/lcc/src/gen.c index f4c316d01..dcd2da888 100755 --- a/Utils/lcc/src/gen.c +++ b/Utils/lcc/src/gen.c @@ -333,10 +333,10 @@ static void dumprule(int rulenum) { char *str = IR->x._templates[rulenum]; if (str == 0) - str = "(action)\n"; + str = IR->x._actionnames[rulenum]; fprint(stderr, "%s / %s", IR->x._string[rulenum], str); - if (!IR->x._isinstruction[rulenum]) + if (!IR->x._isinstruction[rulenum] || IR->x._templates[rulenum] == 0) fprint(stderr, "\n"); } unsigned emitasm(Node p, int nt) { @@ -357,7 +357,7 @@ unsigned emitasm(Node p, int nt) { if (rulenum == 0) { debug(fprint(stderr, " (no rule)\n")); } else if (fmt == 0) { - debug(fprint(stderr, " (action)\n")); + debug(fprint(stderr, " %s\n", IR->x._actionnames[rulenum])); } else { debug(fprint(stderr, " %s\n", fmt)); } @@ -775,7 +775,7 @@ static void genspill(Symbol r, Node last, Symbol tmp) { Symbol s; unsigned ty; - debug(fprint(stderr, "(spilling %s to local %s)\n", r->x.name, tmp->x.name)); + debug(fprint(stderr, "(spilling %s to local %s after %x)\n", r->x.name, tmp->x.name, last)); debug(fprint(stderr, "(genspill: ")); debug(dumptree(last)); debug(fprint(stderr, ")\n")); @@ -803,7 +803,7 @@ static void genreload(Node p, Symbol tmp, int i) { Node q; int ty; - debug(fprint(stderr, "(replacing %x with a reload from %s)\n", p->x.kids[i], tmp->x.name)); + debug(fprint(stderr, "(replacing %x with a reload from %s before %x)\n", p->x.kids[i], tmp->x.name, p)); debug(fprint(stderr, "(genreload: ")); debug(dumptree(p->x.kids[i])); debug(fprint(stderr, ")\n")); @@ -817,7 +817,7 @@ static void genreload(Node p, Symbol tmp, int i) { linearize(p->x.kids[i], p); } static int reprune(Node *pp, int k, int n, Node p) { - struct node x, *q = *pp; + struct node *q = *pp; if (q == NULL || k > n) return k; @@ -827,8 +827,11 @@ static int reprune(Node *pp, int k, int n, Node p) { if (k == n) { debug(fprint(stderr, "(reprune changes %x from %x to %x)\n", pp, *pp, p->x.kids[n])); *pp = p->x.kids[n]; - x = *p; - (IR->x.target)(&x); + (IR->x.target)(p); + + (*IR->x._label)(p->kids[n]); + debug(dumpcover(p->kids[n], 1, 0)); + reduce(p->kids[n], 1); } return k + 1; } diff --git a/Utils/lcc/src/gt1.md b/Utils/lcc/src/gt1.md index 30256e43f..945d11c5a 100644 --- a/Utils/lcc/src/gt1.md +++ b/Utils/lcc/src/gt1.md @@ -836,9 +836,20 @@ static void inst_spill(Node p) { // inst_spill is essentially the same as inst_stloc, but covers an entire spill tree to avoid reentry in the // spiller when spilling vAC. Node vregp = p->kids[1]->kids[0]->kids[0]; - assert(getregnum(vregp) == 0); + + // If we are spilling vAC, we're all set. Otherwise we've got some extra work to do to avoid clobbering vAC. + int regnum = vregp->syms[0]->x.regnode->number; + if (regnum != 0) { + print("asm.stw('ht')\n"); + print("asm.ldw('r%d')\n", regnum); + } + setreg(p->kids[1], wregs[0]); inst_stloc(p); + + if (regnum != 0) { + print("asm.ldw('ht')\n"); + } } static void inst_blkcopy(Node p) { @@ -1428,6 +1439,7 @@ Interface gt1IR = { _kids, _string, _actions, + _actionnames, _templates, _isinstruction, _ntname,