commit 0df9109d9a61da94d0db74c699d305334b4a0948
parent 28e3b95fd0357a08de74aba65d7dbdfa5dd43695
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 28 Dec 2024 11:24:11 +0100
cc2: Add range parameter to statement functions
This makes easier to reuse these functions with narrow ranges
that don't cover the full function.
Diffstat:
6 files changed, 100 insertions(+), 79 deletions(-)
diff --git a/src/cmd/scc-cc/cc2/cc2.h b/src/cmd/scc-cc/cc2/cc2.h
@@ -1,4 +1,5 @@
#define ASLABEL 0
+#define fbody() (curfun->u.body)
enum iflags {
BBENTRY = 1, /* basic block entry */
@@ -267,16 +268,16 @@ extern void deftype(Type *);
#define SETCUR 1
#define KEEPCUR 0
extern void newfun(Symbol *);
-extern void apply(Node *(*fun)(Node *));
+extern void apply(Range *, Node *(*fun)(Range *, Node *));
extern void cleannodes(void);
extern void delnode(Node *np);
extern void deltree(Node *np);
extern void prtree(Node *np), prforest(char *msg);
extern Node *node(int op);
-extern Node *addstmt(Node *np, int flags);
-extern Node *delstmt(void);
-extern Node *nextstmt(void);
-extern Node *insstmt(Node *, Node *, int);
+extern Node *addstmt(Range *, Node *np, int flags);
+extern Node *delstmt(Range *);
+extern Node *nextstmt(Range *, int);
+extern Node *insstmt(Range *, Node *, Node *, int);
extern void delrange(Range *);
extern Range range(Node *, Node *);
diff --git a/src/cmd/scc-cc/cc2/cfg.c b/src/cmd/scc-cc/cc2/cfg.c
@@ -102,7 +102,7 @@ newbb(Node *np)
}
static Node *
-mkcfg(Node *np)
+mkcfg(Range *rp, Node *np)
{
if ((np->flags & (BBENTRY|BBEXIT)) == 0)
return np;
@@ -123,7 +123,7 @@ mkcfg(Node *np)
cfg.exitb = cfg.cur;
break;
case ORET:
- cfg.cur->true = curfun->u.body->end->bb;
+ cfg.cur->true = fbody()->end->bb;
break;
case OBRANCH:
cfg.cur->false = np->next->bb;
@@ -136,7 +136,7 @@ mkcfg(Node *np)
}
static Node *
-mkbb(Node *np)
+mkbb(Range *rp, Node *np)
{
if (np->flags & BBENTRY)
newbb(np);
@@ -157,14 +157,14 @@ newentry(Node *np)
}
static Node *
-markbb(Node *np)
+markbb(Range *rp, Node *np)
{
switch (np->op) {
case OBFUN:
newentry(np);
break;
case ORET:
- newentry(curfun->u.body->end);
+ newentry(rp->end);
newentry(np->next);
break;
case OBRANCH:
@@ -209,17 +209,17 @@ buildcfg(void)
{
int nr;
- apply(markbb);
+ apply(fbody(), markbb);
PRTREE("bb_mark");
cfg.blocks = xcalloc(cfg.nr, sizeof(Block));
nr = cfg.nr;
cfg.nr = 0;
- apply(mkbb);
+ apply(fbody(), mkbb);
assert(cfg.nr == nr);
PRTREE("bb_mk");
- apply(mkcfg);
+ apply(fbody(), mkcfg);
PRCFG("cfg");
}
@@ -233,7 +233,7 @@ gencfg(void)
}
static Node *
-cleanbb(Node *np)
+cleanbb(Range *rp, Node *np)
{
np->flags &= ~(BBENTRY | BBEXIT);
return np;
@@ -244,5 +244,6 @@ cleancfg(void)
{
free(cfg.blocks);
memset(&cfg, 0, sizeof(cfg));
- apply(cleanbb);
+ if (curfun)
+ apply(fbody(), cleanbb);
}
diff --git a/src/cmd/scc-cc/cc2/node.c b/src/cmd/scc-cc/cc2/node.c
@@ -12,6 +12,13 @@ Symbol *curfun;
static Alloc *arena;
static Range body;
+/*
+ * This file defines all the functions required to deal with nodes,
+ * and statement ranges. It is usually safe to deal with a subrange
+ * of a function because all the functions have an initial beginning
+ * statement and an ending statement that are never removed and
+ * the begin and end pointer always point to them.
+ */
Node *
node(int op)
{
@@ -74,76 +81,80 @@ prforest(char *msg)
* current statement
*/
Node *
-insstmt(Node *np, Node *at, int mode)
+insstmt(Range *rp, Node *np, Node *at, int mode)
{
Node *save;
- save = body.cur;
- body.cur = at;
- addstmt(np, KEEPCUR);
+ save = rp->cur;
+ rp->cur = at;
+ addstmt(rp, np, KEEPCUR);
if (mode == KEEPCUR)
- body.cur = save;
+ rp->cur = save;
else
- body.cur = (save == at) ? np : save;
+ rp->cur = (save == at) ? np : save;
return np;
}
Node *
-addstmt(Node *np, int mode)
+addstmt(Range *rp, Node *np, int mode)
{
Node *next;
next = NULL;
- if (body.cur) {
- next = body.cur->next;
+ if (rp->cur) {
+ next = rp->cur->next;
if (next)
next->prev = np;
- body.cur->next = np;
+ rp->cur->next = np;
}
np->next = next;
- np->prev = body.cur;
+ np->prev = rp->cur;
- if (!body.begin)
- body.begin = np;
- if (!body.end || !np->next)
- body.end = np;
+ if (!rp->begin)
+ rp->begin = np;
+ if (!rp->end || !np->next)
+ rp->end = np;
if (mode == SETCUR)
- body.cur = np;
+ rp->cur = np;
return np;
}
Node *
-delstmt(void)
+delstmt(Range *rp)
{
Node *next, *prev;
- if (!body.cur)
- return NULL;
-
- next = body.cur->next;
- prev = body.cur->prev;
+ next = rp->cur->next;
+ prev = rp->cur->prev;
if (next)
next->prev = prev;
if (prev)
prev->next = next;
- if (body.begin == body.cur)
- body.begin = next;
- if (body.end == body.cur)
- body.end = prev;
- deltree(body.cur);
+ if (rp->begin == rp->cur)
+ rp->begin = next;
+ if (rp->end == rp->cur)
+ rp->end = prev;
+ deltree(rp->cur);
- return body.cur = next;
+ if (rp->cur == rp->end)
+ return rp->cur = NULL;
+ return rp->cur = next;
}
Node *
-nextstmt(void)
+nextstmt(Range *rp, int mode)
{
- return body.cur = body.cur->next;
+ Node *next;
+
+ next = (rp->cur == rp->end) ? NULL : rp->cur->next;
+ if (mode == SETCUR)
+ rp->cur = next;
+ return next;
}
void
@@ -169,16 +180,15 @@ cleannodes(void)
dealloc(arena);
arena = NULL;
}
- body.cur = NULL;
curfun = NULL;
- memset(&body, 0, sizeof(body));
}
void
newfun(Symbol *sym)
{
curfun = sym;
- curfun->u.body = memset(&body, 0, sizeof(body));
+ body = range(NULL, NULL);
+ curfun->u.body = &body;
}
void
@@ -213,9 +223,18 @@ range(Node *begin, Node *end)
}
void
-apply(Node *(*fun)(Node *))
+apply(Range *rp, Node *(*fun)(Range *, Node *))
{
- body.cur = body.begin;
- while (body.cur)
- (*fun)(body.cur) ? nextstmt() : delstmt();
+ Node *np;
+
+ rp->cur = rp->begin;
+ while (rp->cur) {
+ np = (*fun)(rp, rp->cur);
+ if (!np) {
+ delstmt(rp);
+ } else {
+ rp->cur = np;
+ nextstmt(rp, SETCUR);
+ }
+ }
}
diff --git a/src/cmd/scc-cc/cc2/parser.c b/src/cmd/scc-cc/cc2/parser.c
@@ -354,7 +354,7 @@ waft(Node *np)
cur = swp - 1;
lastcase = cur->last;
- insstmt(np, cur->last, SETCUR);
+ insstmt(fbody(), np, cur->last, SETCUR);
cur->last = np;
cur->nr++;
@@ -661,7 +661,7 @@ labeldcl(void)
sym->kind = SLABEL;
sym->u.stmt = np;
np->label = sym;
- addstmt(np, SETCUR);
+ addstmt(fbody(), np, SETCUR);
}
static void
@@ -677,7 +677,7 @@ stmt(void)
deltree(np);
return;
}
- addstmt(np, SETCUR);
+ addstmt(fbody(), np, SETCUR);
}
static void
@@ -686,14 +686,14 @@ beginfun(void)
newfun(lastfun);
beginf = inpars = 1;
pushctx();
- addstmt(node(OBFUN), SETCUR);
+ addstmt(fbody(), node(OBFUN), SETCUR);
}
static void
endfun(void)
{
endf = 1;
- addstmt(node(OEFUN), SETCUR);
+ addstmt(fbody(), node(OEFUN), SETCUR);
}
void
diff --git a/src/cmd/scc-cc/cc2/qbe/cgen.c b/src/cmd/scc-cc/cc2/qbe/cgen.c
@@ -12,7 +12,7 @@
#define I4BYTES 2
#define I8BYTES 3
-static Node *cgen(Node *);
+static Node *cgen(Range *, Node *);
static unsigned char opasmw[][2] = {
[OADD] = {ASADDW, ASADDW},
@@ -160,7 +160,7 @@ complex(Node *np)
}
static Node *
-sethi(Node *np)
+sethi(Range *rp, Node *np)
{
Node *l, *r;
@@ -189,8 +189,8 @@ sethi(Node *np)
goto binary;
default:
binary:
- l = sethi(l);
- r = sethi(r);
+ l = sethi(rp, l);
+ r = sethi(rp, r);
break;
}
np->left = l;
@@ -490,7 +490,7 @@ swtch(Node *idx)
Symbol *deflabel = NULL;
for (;;) {
- np = delstmt();
+ np = delstmt(fbody());
setlabel(np->label);
switch (np->op) {
@@ -500,7 +500,7 @@ swtch(Node *idx)
aux1.op = OJMP;
aux1.label = NULL;
aux1.u.sym = deflabel;
- cgen(&aux1);
+ cgen(fbody(), &aux1);
return;
case OCASE:
aux1 = *np;
@@ -513,7 +513,7 @@ swtch(Node *idx)
aux2.left = np->left;
aux2.right = idx;
- cgen(&aux1);
+ cgen(fbody(), &aux1);
break;
case ODEFAULT:
deflabel = np->u.sym;
@@ -599,7 +599,7 @@ assign(Node *np)
aux.left = ret;
aux.right = r;
aux.type = np->type;
- r = rhs(sethi(&aux));
+ r = rhs(sethi(fbody(), &aux));
break;
default:
/* assign abbreviation */
@@ -611,7 +611,7 @@ assign(Node *np)
aux.right = r;
aux.type = int32type;
aux.address = np->address;
- ret = r = sethi(rhs(&aux));
+ ret = r = sethi(fbody(), rhs(&aux));
break;
}
@@ -620,7 +620,7 @@ assign(Node *np)
aux.right = r;
aux.type = np->type;
aux.address = np->address;
- r = sethi(&aux);
+ r = sethi(fbody(), &aux);
case 0:
lhs_rhs(&l, &r);
ret = r;
@@ -749,7 +749,7 @@ rhs(Node *np)
}
static Node *
-cgen(Node *np)
+cgen(Range *rp, Node *np)
{
Node aux, *p, *next;
@@ -788,7 +788,7 @@ cgen(Node *np)
}
static Node *
-norm(Node *np)
+norm(Range *rp, Node *np)
{
int op = np->op;
Node *p, *dst, *next = np->next;
@@ -808,7 +808,7 @@ norm(Node *np)
*/
op = (np->prev) ? np->prev->op : 0;
if (!op || op == ONOP || op == OBRANCH || (op != ORET && op != OJMP))
- addstmt(node(ORET), KEEPCUR);
+ addstmt(rp, node(ORET), KEEPCUR);
break;
case OBRANCH:
if (!next->label) {
@@ -841,12 +841,12 @@ norm(Node *np)
void
genasm(void)
{
- apply(norm);
- apply(cgen);
+ apply(fbody(), norm);
+ apply(fbody(), cgen);
}
void
genaddr(void)
{
- apply(sethi);
+ apply(fbody(), sethi);
}
diff --git a/src/cmd/scc-cc/cc2/z80-scc/cgen.c b/src/cmd/scc-cc/cc2/z80-scc/cgen.c
@@ -519,7 +519,7 @@ ret(Node *np)
}
static Node *
-cgen(Node *np)
+cgen(Range *rp, Node *np)
{
Node aux, *p, *next;
@@ -568,7 +568,7 @@ cgen(Node *np)
* CONST => 20 $value
*/
static Node *
-sethi(Node *np)
+sethi(Range *rp, Node *np)
{
Node *l, *r;
@@ -593,8 +593,8 @@ sethi(Node *np)
np->address = 20;
break;
default:
- sethi(l);
- sethi(r);
+ sethi(rp, l);
+ sethi(rp, r);
break;
}
@@ -618,11 +618,11 @@ sethi(Node *np)
void
genasm(void)
{
- apply(cgen);
+ apply(fbody(), cgen);
}
void
genaddr(void)
{
- apply(sethi);
+ apply(fbody(), sethi);
}