qbe

Internal scc patchset buffer for QBE
Log | Files | Refs | README | LICENSE

commit cbee74bdb4f85d6d8d4f192f0018ea023418e216
parent 04e26409011389f7b5759114905195a4fb0b0286
Author: Quentin Carbonneaux <quentin@c9x.me>
Date:   Tue, 22 Nov 2022 21:44:44 +0100

use a new struct for symbols

Symbols are a useful abstraction
that occurs in both Con and Alias.
In this patch they get their own
struct. This new struct packages
a symbol name and a type; the type
tells us where the symbol name
must be interpreted (currently, in
gobal memory or in thread-local
storage).

The refactor fixed a bug in
addcon(), proving the value of
packaging symbol names with their
type.

Diffstat:
Malias.c | 5++---
Mall.h | 21++++++++++++---------
Mamd64/emit.c | 6+++---
Mamd64/isel.c | 7++++---
Marm64/emit.c | 14++++++++------
Marm64/isel.c | 4++--
Mfold.c | 23+++++++++--------------
Mload.c | 4+++-
Mparse.c | 6+++---
Mrv64/emit.c | 21++++++++++++---------
Mrv64/isel.c | 2+-
Mutil.c | 13+++++++++----
12 files changed, 68 insertions(+), 58 deletions(-)

diff --git a/alias.c b/alias.c @@ -18,8 +18,7 @@ getalias(Alias *a, Ref r, Fn *fn) c = &fn->con[r.val]; if (c->type == CAddr) { a->type = ASym; - a->u.sym.label = c->label; - a->u.sym.con = r.val; + a->u.sym = c->sym; } else a->type = ACon; a->offset = c->bits.i; @@ -52,7 +51,7 @@ alias(Ref p, int sp, Ref q, int sq, int *delta, Fn *fn) /* they conservatively alias if the * symbols are different, or they * alias for sure if they overlap */ - if (ap.u.sym.label != aq.u.sym.label) + if (!symeq(ap.u.sym, aq.u.sym)) return MayAlias; if (ovlap) return MustAlias; diff --git a/all.h b/all.h @@ -20,6 +20,7 @@ typedef struct Ins Ins; typedef struct Phi Phi; typedef struct Blk Blk; typedef struct Use Use; +typedef struct Sym Sym; typedef struct Alias Alias; typedef struct Tmp Tmp; typedef struct Con Con; @@ -264,6 +265,14 @@ struct Use { } u; }; +struct Sym { + enum { + SGlo, + SThr, + } type; + uint32_t id; +}; + enum { NoAlias, MayAlias, @@ -283,10 +292,7 @@ struct Alias { int base; int64_t offset; union { - struct { - uint32_t label; - int con; - } sym; + Sym sym; struct { int sz; /* -1 if > NBit */ bits m; @@ -329,16 +335,12 @@ struct Con { CBits, CAddr, } type; - uint32_t label; + Sym sym; union { int64_t i; double d; float s; } bits; - enum { - RelDef, - RelThr, - } reloc; char flt; /* 1 to print as s, 2 to print as d */ }; @@ -463,6 +465,7 @@ int clsmerge(short *, short); int phicls(int, Tmp *); Ref newtmp(char *, int, Fn *); void chuse(Ref, int, Fn *); +int symeq(Sym, Sym); Ref newcon(Con *, Fn *); Ref getcon(int64_t, Fn *); int addcon(Con *, Con *); diff --git a/amd64/emit.c b/amd64/emit.c @@ -165,9 +165,9 @@ emitcon(Con *con, FILE *f) switch (con->type) { case CAddr: - l = str(con->label); + l = str(con->sym.id); p = l[0] == '"' ? "" : T.assym; - if (con->reloc == RelThr) { + if (con->sym.type == SThr) { if (T.apple) fprintf(f, "%s%s@TLVP", p, l); else @@ -344,7 +344,7 @@ Next: off = fn->con[ref.val]; emitcon(&off, f); if (off.type == CAddr) - if (off.reloc != RelThr || T.apple) + if (off.sym.type != SThr || T.apple) fprintf(f, "(%%rip)"); break; case RTmp: diff --git a/amd64/isel.c b/amd64/isel.c @@ -81,7 +81,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) a.offset.type = CAddr; n = stashbits(&fn->con[r0.val].bits, KWIDE(k) ? 8 : 4); sprintf(buf, "\"%sfp%d\"", T.asloc, n); - a.offset.label = intern(buf); + a.offset.sym.id = intern(buf); fn->mem[fn->nmem-1] = a; } else if (op != Ocopy && k == Kl && noimm(r0, fn)) { @@ -124,7 +124,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) } } else if (T.apple && rtype(r0) == RCon && (c = &fn->con[r0.val])->type == CAddr - && c->reloc == RelThr) { + && c->sym.type == SThr) { r1 = newtmp("isel", Kl, fn); if (c->bits.i) { r2 = newtmp("isel", Kl, fn); @@ -612,7 +612,8 @@ amatch(Addr *a, Ref r, int n, ANum *ai, Fn *fn) if (rtype(r) == RCon) { if (!addcon(&a->offset, &fn->con[r.val])) err("unlikely sum of $%s and $%s", - str(a->offset.label), str(fn->con[r.val].label)); + str(a->offset.sym.id), + str(fn->con[r.val].sym.id)); return 1; } assert(rtype(r) == RTmp); diff --git a/arm64/emit.c b/arm64/emit.c @@ -247,10 +247,10 @@ loadaddr(Con *c, char *rn, E *e) { char *p, *l, *s; - switch (c->reloc) { + switch (c->sym.type) { default: die("unreachable"); - case RelDef: + case SGlo: if (T.apple) s = "\tadrp\tR, S@pageO\n" "\tadd\tR, R, S@pageoffO\n"; @@ -258,7 +258,7 @@ loadaddr(Con *c, char *rn, E *e) s = "\tadrp\tR, SO\n" "\tadd\tR, R, #:lo12:SO\n"; break; - case RelThr: + case SThr: if (T.apple) s = "\tadrp\tR, S@tlvppage\n" "\tldr\tR, [R, S@tlvppageoff]\n"; @@ -269,7 +269,7 @@ loadaddr(Con *c, char *rn, E *e) break; } - l = str(c->label); + l = str(c->sym.id); p = l[0] == '"' ? "" : T.assym; for (; *s; s++) switch (*s) { @@ -431,9 +431,11 @@ emitins(Ins *i, E *e) if (rtype(i->arg[0]) != RCon) goto Table; c = &e->fn->con[i->arg[0].val]; - if (c->type != CAddr || c->bits.i) + if (c->type != CAddr + || c->sym.type != SGlo + || c->bits.i) die("invalid call argument"); - l = str(c->label); + l = str(c->sym.id); p = l[0] == '"' ? "" : T.assym; fprintf(e->f, "\tbl\t%s%s\n", p, l); break; diff --git a/arm64/isel.c b/arm64/isel.c @@ -80,7 +80,7 @@ fixarg(Ref *pr, int k, int phi, Fn *fn) c = &fn->con[r0.val]; if (T.apple && c->type == CAddr - && c->reloc == RelThr) { + && c->sym.type == SThr) { r1 = newtmp("isel", Kl, fn); *pr = r1; if (c->bits.i) { @@ -114,7 +114,7 @@ fixarg(Ref *pr, int k, int phi, Fn *fn) c = &fn->con[fn->ncon-1]; sprintf(buf, "\"%sfp%d\"", T.asloc, n); *c = (Con){.type = CAddr}; - c->label = intern(buf); + c->sym.id = intern(buf); r2 = newtmp("isel", Kl, fn); emit(Oload, k, r1, r2, R); emit(Ocopy, Kl, r2, CON(c-fn->con), R); diff --git a/fold.c b/fold.c @@ -333,35 +333,31 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) double fd; } l, r; uint64_t x; - uint32_t lab; - int typ, rel; + Sym sym; + int typ; + memset(&sym, 0, sizeof sym); typ = CBits; - rel = RelDef; - lab = 0; l.s = cl->bits.i; r.s = cr->bits.i; if (op == Oadd) { if (cl->type == CAddr) { if (cr->type == CAddr) return 1; - lab = cl->label; - rel = cl->reloc; typ = CAddr; + sym = cl->sym; } else if (cr->type == CAddr) { - lab = cr->label; - rel = cr->reloc; typ = CAddr; + sym = cr->sym; } } else if (op == Osub) { if (cl->type == CAddr) { if (cr->type != CAddr) { - lab = cl->label; - rel = cl->reloc; typ = CAddr; - } else if (cl->label != cr->label) + sym = cl->sym; + } else if (!symeq(cl->sym, cr->sym)) return 1; } else if (cr->type == CAddr) @@ -407,9 +403,8 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) case Ocast: x = l.u; if (cl->type == CAddr) { - lab = cl->label; - rel = cl->reloc; typ = CAddr; + sym = cl->sym; } break; default: @@ -462,7 +457,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) else die("unreachable"); } - *res = (Con){.type=typ, .label=lab, .reloc=rel, .bits={.i=x}}; + *res = (Con){.type=typ, .sym=sym, .bits={.i=x}}; return 0; } diff --git a/load.c b/load.c @@ -152,7 +152,9 @@ load(Slice sl, bits msk, Loc *l) break; case ACon: case ASym: - c = curf->con[a->u.sym.con]; + memset(&c, 0, sizeof c); + c.type = CAddr; + c.sym = a->u.sym; c.bits.i = a->offset; r = newcon(&c, curf); break; diff --git a/parse.c b/parse.c @@ -420,12 +420,12 @@ parseref() c.flt = 2; break; case Tthread: - c.reloc = RelThr; + c.sym.type = SThr; expect(Tglo); /* fall through */ case Tglo: c.type = CAddr; - c.label = intern(tokval.str); + c.sym.id = intern(tokval.str); break; } return newcon(&c, curf); @@ -1174,7 +1174,7 @@ printcon(Con *c, FILE *f) case CUndef: break; case CAddr: - fprintf(f, "$%s", str(c->label)); + fprintf(f, "$%s", str(c->sym.id)); if (c->bits.i) fprintf(f, "%+"PRIi64, c->bits.i); break; diff --git a/rv64/emit.c b/rv64/emit.c @@ -129,8 +129,8 @@ slot(int s, Fn *fn) static void emitaddr(Con *c, FILE *f) { - assert(c->reloc == RelDef); - fputs(str(c->label), f); + assert(c->sym.type == SGlo); + fputs(str(c->sym.id), f); if (c->bits.i) fprintf(f, "+%"PRIi64, c->bits.i); } @@ -229,17 +229,17 @@ loadaddr(Con *c, char *rn, FILE *f) { char off[32]; - if (c->reloc == RelThr) { + if (c->sym.type == SThr) { if (c->bits.i) sprintf(off, "+%"PRIi64, c->bits.i); else off[0] = 0; fprintf(f, "\tlui %s, %%tprel_hi(%s)%s\n", - rn, str(c->label), off); + rn, str(c->sym.id), off); fprintf(f, "\tadd %s, %s, tp, %%tprel_add(%s)%s\n", - rn, rn, str(c->label), off); + rn, rn, str(c->sym.id), off); fprintf(f, "\taddi %s, %s, %%tprel_lo(%s)%s\n", - rn, rn, str(c->label), off); + rn, rn, str(c->sym.id), off); } else { fprintf(f, "\tla %s, ", rn); emitaddr(c, f); @@ -279,7 +279,8 @@ fixmem(Ref *pr, Fn *fn, FILE *f) r = *pr; if (rtype(r) == RCon) { c = &fn->con[r.val]; - if (c->type == CAddr && c->reloc == RelThr) { + if (c->type == CAddr) + if (c->sym.type == SThr) { loadcon(c, T6, Kl, f); *pr = TMP(T6); } @@ -383,9 +384,11 @@ emitins(Ins *i, Fn *fn, FILE *f) switch (rtype(i->arg[0])) { case RCon: con = &fn->con[i->arg[0].val]; - if (con->type != CAddr || con->bits.i) + if (con->type != CAddr + || con->sym.type != SGlo + || con->bits.i) goto Invalid; - fprintf(f, "\tcall %s\n", str(con->label)); + fprintf(f, "\tcall %s\n", str(con->sym.id)); break; case RTmp: emitf("jalr %0", i, fn, f); diff --git a/rv64/isel.c b/rv64/isel.c @@ -46,7 +46,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) c = &fn->con[fn->ncon-1]; sprintf(buf, "\"%sfp%d\"", T.asloc, n); *c = (Con){.type = CAddr}; - c->label = intern(buf); + c->sym.id = intern(buf); emit(Oload, k, r1, CON(c-fn->con), R); break; } diff --git a/util.c b/util.c @@ -349,6 +349,12 @@ chuse(Ref r, int du, Fn *fn) fn->tmp[r.val].nuse += du; } +int +symeq(Sym s0, Sym s1) +{ + return s0.type == s1.type && s0.id == s1.id; +} + Ref newcon(Con *c0, Fn *fn) { @@ -358,9 +364,8 @@ newcon(Con *c0, Fn *fn) for (i=0; i<fn->ncon; i++) { c1 = &fn->con[i]; if (c0->type == c1->type - && c0->label == c1->label - && c0->bits.i == c1->bits.i - && c0->reloc == c1->reloc) + && symeq(c0->sym, c1->sym) + && c0->bits.i == c1->bits.i) return CON(i); } vgrow(&fn->con, ++fn->ncon); @@ -391,7 +396,7 @@ addcon(Con *c0, Con *c1) if (c0->type == CAddr) return 0; c0->type = CAddr; - c0->label = c1->label; + c0->sym = c1->sym; } c0->bits.i += c1->bits.i; }