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:
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;
}