scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

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:
Msrc/cmd/scc-cc/cc2/cc2.h | 11++++++-----
Msrc/cmd/scc-cc/cc2/cfg.c | 21+++++++++++----------
Msrc/cmd/scc-cc/cc2/node.c | 93+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Msrc/cmd/scc-cc/cc2/parser.c | 10+++++-----
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 32++++++++++++++++----------------
Msrc/cmd/scc-cc/cc2/z80-scc/cgen.c | 12++++++------
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); }