scc

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

commit 96d3397e927cf497d7d25116dbd25dc965f80ac8
parent 9ff031d254906ced8bc498a0db070afdc420f0ac
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 30 Dec 2024 10:12:56 +0100

cc2: Remove the Range datatype

It only introduced more complexity without a big benefit.
Too many changes just to avoid a global variable.

Diffstat:
Msrc/cmd/scc-cc/cc2/cc2.h | 25++++++++-----------------
Msrc/cmd/scc-cc/cc2/cfg.c | 47+++++++++++++++++++++++------------------------
Msrc/cmd/scc-cc/cc2/node.c | 126+++++++++++++++++++++++++++++++++----------------------------------------------
Msrc/cmd/scc-cc/cc2/parser.c | 18+++++++-----------
Msrc/cmd/scc-cc/cc2/qbe/cgen.c | 32++++++++++++++++----------------
Msrc/cmd/scc-cc/cc2/z80-scc/cgen.c | 12++++++------
6 files changed, 112 insertions(+), 148 deletions(-)

diff --git a/src/cmd/scc-cc/cc2/cc2.h b/src/cmd/scc-cc/cc2/cc2.h @@ -1,5 +1,4 @@ #define ASLABEL 0 -#define fbody() (curfun->u.body) enum iflags { BBENTRY = 1, /* basic block entry */ @@ -156,7 +155,6 @@ typedef struct symbol Symbol; typedef struct addr Addr; typedef struct inst Inst; typedef struct block Block; -typedef struct range Range; struct type { unsigned long size; @@ -165,12 +163,6 @@ struct type { short flags; }; -struct range { - Node *begin; - Node *end; - Node *cur; -}; - struct symbol { Type type; Type rtype; @@ -183,7 +175,6 @@ struct symbol { long off; Node *stmt; Inst *inst; - Range *body; } u; Symbol *next, *prev; Symbol *h_next; @@ -267,19 +258,18 @@ extern void deftype(Type *); /* node.c */ #define SETCUR 1 #define KEEPCUR 0 -extern void newfun(Symbol *); -extern void apply(Range *, Node *(*fun)(Range *, Node *)); +extern void newfun(Symbol *, Node *); +extern void apply(Node *(*fun)(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(Range *, Node *np, int flags); -extern Node *delstmt(Range *); -extern Node *nextstmt(Range *, int); -extern Node *insstmt(Range *, Node *, Node *); -extern void delrange(Range *); -extern Range range(Node *, Node *); +extern Node *addstmt(Node *np, int flags); +extern Node *delstmt(void); +extern Node *insstmt(Node *, Node *); +extern void delrange(Node *, Node *); +extern Node *waftstmt(Node *); /* symbol.c */ #define TMPSYM 0 @@ -296,6 +286,7 @@ extern void cleancfg(void); extern Symbol *curfun; extern Symbol *locals; extern Inst *pc, *prog; +extern Node *laststmt; /* target */ extern Type int8type, int16type, int32type, int64type, diff --git a/src/cmd/scc-cc/cc2/cfg.c b/src/cmd/scc-cc/cc2/cfg.c @@ -96,13 +96,13 @@ newbb(Node *np) bb->true = bb->false = NULL; bb->id = cfg.nr++; bb->visited = 0; - np->bb = bb; + cfg.cur = bb; return bb; } static Node * -mkcfg(Range *rp, Node *np) +mkcfg(Node *np) { if ((np->flags & (BBENTRY|BBEXIT)) == 0) return np; @@ -123,7 +123,7 @@ mkcfg(Range *rp, Node *np) cfg.exitb = cfg.cur; break; case ORET: - cfg.cur->true = fbody()->end->bb; + cfg.cur->true = laststmt->bb; break; case OBRANCH: cfg.cur->false = np->next->bb; @@ -136,10 +136,12 @@ mkcfg(Range *rp, Node *np) } static Node * -mkbb(Range *rp, Node *np) +mkbb(Node *np) { if (np->flags & BBENTRY) newbb(np); + np->bb = cfg.cur; + return np; } @@ -157,14 +159,14 @@ newentry(Node *np) } static Node * -markbb(Range *rp, Node *np) +markbb(Node *np) { switch (np->op) { case OBFUN: newentry(np); break; case ORET: - newentry(rp->end); + newentry(laststmt); newentry(np->next); break; case OBRANCH: @@ -190,15 +192,12 @@ static void trimcfg(void) { Block *bb, *prev, *next; - Range r; visit(cfg.entryb); for (bb = cfg.blocks; bb < &cfg.blocks[cfg.nr]; ++bb) { if (bb->visited) continue; - - r = range(bb->entryp, bb->exitp); - delrange(&r); + delrange(bb->entryp, bb->exitp); bb->id = -1; } PRCFG("trimmed_cfg"); @@ -209,22 +208,22 @@ buildcfg(void) { int nr; - apply(fbody(), markbb); + apply(markbb); PRTREE("bb_mark"); cfg.blocks = xcalloc(cfg.nr, sizeof(Block)); nr = cfg.nr; cfg.nr = 0; - apply(fbody(), mkbb); + apply(mkbb); assert(cfg.nr == nr); PRTREE("bb_mk"); - apply(fbody(), mkcfg); + apply(mkcfg); PRCFG("cfg"); } static Node * -optlabels(Range *rp, Node *np) +optlabels(Node *np) { if (np->op == ONOP && np->label->refcnt == 0) { cfg.dirty = 1; @@ -234,9 +233,8 @@ optlabels(Range *rp, Node *np) } static Node * -optjmps(Range *rp, Node *np) +optjmps(Node *np) { - Range r; Symbol *label; Node *p, *stmt, *last; @@ -250,8 +248,7 @@ optjmps(Range *rp, Node *np) stmt = label->u.stmt; /* Avoid jump over a set of NOPs */ - r = range(np, rp->end); - for (p = nextstmt(&r, SETCUR); p; p = nextstmt(&r, SETCUR)) { + for (p = np->next; p; p = p->next) { if (p == stmt) { cfg.dirty = 1; label->refcnt--; @@ -263,8 +260,7 @@ optjmps(Range *rp, Node *np) chain_jumps: /* avoid chain of jumps to jumps */ - r = range(stmt, rp->end); - for (p = stmt; p && p->op == ONOP; p = nextstmt(&r, SETCUR)) + for (p = stmt; p && p->op == ONOP; p = p->next) ; if (p && p != np && p->op == OJMP) { cfg.dirty = 1; @@ -275,6 +271,8 @@ optjmps(Range *rp, Node *np) goto chain_jumps; } } + + return np; } void @@ -294,17 +292,18 @@ gencfg(void) * because any change in the jumps make invalid the cfg * automatically */ - apply(fbody(), optjmps); - apply(fbody(), optlabels); + apply(optjmps); + apply(optlabels); } PRTREE("after_gencfg"); } static Node * -cleanbb(Range *rp, Node *np) +cleanbb(Node *np) { np->flags &= ~(BBENTRY | BBEXIT); + np->bb = NULL; return np; } @@ -314,5 +313,5 @@ cleancfg(void) free(cfg.blocks); memset(&cfg, 0, sizeof(cfg)); if (curfun) - apply(fbody(), cleanbb); + apply(cleanbb); } diff --git a/src/cmd/scc-cc/cc2/node.c b/src/cmd/scc-cc/cc2/node.c @@ -10,15 +10,8 @@ Symbol *curfun; static Alloc *arena; -static Range body; +static Node *curstmt; -/* - * 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) { @@ -69,77 +62,76 @@ prforest(char *msg) Node *np; fprintf(stderr, "tree %s {\n", msg); - for (np = body.begin; np; np = np->next) + for (np = curfun->u.stmt; np; np = np->next) prtree(np); fputs("}\n", stderr); } #endif Node * -insstmt(Range *rp, Node *np, Node *at) +insstmt(Node *np, Node *at) { Node *next; - next = NULL; - if (at) { - next = at->next; - if (next) - next->prev = np; - at->next = np; - } + next = at->next; + if (next) + next->prev = np; + at->next = np; np->next = next; np->prev = at; - if (!rp->begin) - rp->begin = np; - if (!rp->end || !next) - rp->end = np; - - return np; -} - -Node * -addstmt(Range *rp, Node *np, int mode) -{ - insstmt(rp, np, rp->cur); - if (mode == SETCUR) - rp->cur = np; return np; } -Node * -delstmt(Range *rp) +static Node * +unlink(Node *np) { Node *next, *prev; - next = rp->cur->next; - prev = rp->cur->prev; + next = np->next; + prev = np->prev; if (next) next->prev = prev; if (prev) prev->next = next; + np->next = np->prev = NULL; - if (rp->begin == rp->cur) - rp->begin = next; - if (rp->end == rp->cur) - rp->end = prev; - deltree(rp->cur); + return np; +} - if (rp->cur == rp->end) - return rp->cur = NULL; - return rp->cur = next; +/* + * Move current node after `at' and keep the current + * pointer to the end of the list + */ +Node * +waftstmt(Node *at) +{ + Node *np = curstmt, *prev = np->prev; + + if (prev == at) + return np; + curstmt = prev; + return insstmt(unlink(np), at); } Node * -nextstmt(Range *rp, int mode) +addstmt(Node *np, int mode) +{ + insstmt(np, curstmt); + if (mode == SETCUR) + curstmt = np; + return np; +} + +Node * +delstmt(void) { Node *next; - next = (rp->cur == rp->end) ? NULL : rp->cur->next; - if (mode == SETCUR) - rp->cur = next; - return next; + next = curstmt->next; + deltree(unlink(curstmt)); + return curstmt = next; } void @@ -169,57 +161,43 @@ cleannodes(void) } void -newfun(Symbol *sym) +newfun(Symbol *sym, Node *np) { curfun = sym; - body = range(NULL, NULL); - curfun->u.body = &body; + curstmt = curfun->u.stmt = np; } void -delrange(Range *rp) +delrange(Node *begin, Node *end) { Node *lprev, *rnext, *next, *np; - lprev = rp->begin->prev; - rnext = rp->end->next; + lprev = begin->prev; + rnext = end->next; if (lprev) lprev->next = rnext; if (rnext) rnext->prev = lprev; - for (np = rp->begin; np != rnext; np = next) { + for (np = begin; np != rnext; np = next) { next = np->next; deltree(np); } - - rp->begin = rp->end = rp->cur = NULL; -} - -Range -range(Node *begin, Node *end) -{ - Range r; - - r.cur = r.begin = begin; - r.end = end; - return r; } void -apply(Range *rp, Node *(*fun)(Range *, Node *)) +apply(Node *(*fun)(Node *)) { Node *np; - rp->cur = rp->begin; - while (rp->cur) { - np = (*fun)(rp, rp->cur); + curstmt = curfun->u.stmt; + while (curstmt) { + np = (*fun)(curstmt); if (!np) { - delstmt(rp); + delstmt(); } else { - rp->cur = np; - nextstmt(rp, SETCUR); + curstmt = np->next; } } } diff --git a/src/cmd/scc-cc/cc2/parser.c b/src/cmd/scc-cc/cc2/parser.c @@ -30,6 +30,7 @@ struct swtch { Node *last; }; +Node *laststmt; static struct swtch swtbl[NR_BLOCK], *swp = swtbl; static Symbol *lastfun; @@ -346,18 +347,14 @@ oreturn(char *token, union tokenop u) static void waft(Node *np) { - Range *rp; struct swtch *cur; if (swp == swtbl) error(EWTACKU); cur = swp - 1; - rp = fbody(); - insstmt(rp, np, cur->last); - if (rp->cur == cur->last) - rp->cur = np; - + addstmt(np, SETCUR); + waftstmt(cur->last); cur->last = np; cur->nr++; } @@ -663,7 +660,7 @@ labeldcl(void) sym->kind = SLABEL; sym->u.stmt = np; np->label = sym; - addstmt(fbody(), np, SETCUR); + addstmt(np, SETCUR); } static void @@ -679,23 +676,22 @@ stmt(void) deltree(np); return; } - addstmt(fbody(), np, SETCUR); + addstmt(np, SETCUR); } static void beginfun(void) { - newfun(lastfun); + newfun(lastfun, node(OBFUN)); beginf = inpars = 1; pushctx(); - addstmt(fbody(), node(OBFUN), SETCUR); } static void endfun(void) { endf = 1; - addstmt(fbody(), node(OEFUN), SETCUR); + laststmt = addstmt(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(Range *, Node *); +static Node *cgen(Node *); static unsigned char opasmw[][2] = { [OADD] = {ASADDW, ASADDW}, @@ -160,7 +160,7 @@ complex(Node *np) } static Node * -sethi(Range *rp, Node *np) +sethi(Node *np) { Node *l, *r; @@ -189,8 +189,8 @@ sethi(Range *rp, Node *np) goto binary; default: binary: - l = sethi(rp, l); - r = sethi(rp, r); + l = sethi(l); + r = sethi(r); break; } np->left = l; @@ -490,7 +490,7 @@ swtch(Node *idx) Symbol *deflabel = NULL; for (;;) { - np = delstmt(fbody()); + np = delstmt(); setlabel(np->label); switch (np->op) { @@ -500,7 +500,7 @@ swtch(Node *idx) aux1.op = OJMP; aux1.label = NULL; aux1.u.sym = deflabel; - cgen(fbody(), &aux1); + cgen(&aux1); return; case OCASE: aux1 = *np; @@ -513,7 +513,7 @@ swtch(Node *idx) aux2.left = np->left; aux2.right = idx; - cgen(fbody(), &aux1); + cgen(&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(fbody(), &aux)); + r = rhs(sethi(&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(fbody(), rhs(&aux)); + ret = r = sethi(rhs(&aux)); break; } @@ -620,7 +620,7 @@ assign(Node *np) aux.right = r; aux.type = np->type; aux.address = np->address; - r = sethi(fbody(), &aux); + r = sethi(&aux); case 0: lhs_rhs(&l, &r); ret = r; @@ -749,7 +749,7 @@ rhs(Node *np) } static Node * -cgen(Range *rp, Node *np) +cgen(Node *np) { Node aux, *p, *next; @@ -788,7 +788,7 @@ cgen(Range *rp, Node *np) } static Node * -norm(Range *rp, Node *np) +norm(Node *np) { int op = np->op; Node *p, *dst, *next = np->next; @@ -808,7 +808,7 @@ norm(Range *rp, Node *np) */ op = (np->prev) ? np->prev->op : 0; if (!op || op == ONOP || op == OBRANCH || (op != ORET && op != OJMP)) - addstmt(rp, node(ORET), KEEPCUR); + addstmt(node(ORET), KEEPCUR); break; case OBRANCH: if (!next->label) { @@ -823,12 +823,12 @@ norm(Range *rp, Node *np) void genasm(void) { - apply(fbody(), norm); - apply(fbody(), cgen); + apply(norm); + apply(cgen); } void genaddr(void) { - apply(fbody(), sethi); + apply(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(Range *rp, Node *np) +cgen(Node *np) { Node aux, *next; @@ -540,7 +540,7 @@ cgen(Range *rp, Node *np) code(ASJP, NULL, &aux, NULL); break; case OBRANCH: - next = nextstmt(rp, KEEPCUR); + next = np->next; if (!next->label) next->label = newlabel(); bool(np->left, np->u.sym, next->label); @@ -568,7 +568,7 @@ cgen(Range *rp, Node *np) * CONST => 20 $value */ static Node * -sethi(Range *rp, Node *np) +sethi(Node *np) { Node *l, *r; @@ -593,8 +593,8 @@ sethi(Range *rp, Node *np) np->address = 20; break; default: - sethi(rp, l); - sethi(rp, r); + sethi(l); + sethi(r); break; } @@ -624,5 +624,5 @@ genasm(void) void genaddr(void) { - apply(fbody(), sethi); + apply(sethi); }