summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-11-22 21:44:44 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2022-11-22 21:56:21 +0100
commitcbee74bdb4f85d6d8d4f192f0018ea023418e216 (patch)
tree4ea3eb41265e44336d81fecf719193c67540f3d3
parent04e26409011389f7b5759114905195a4fb0b0286 (diff)
downloadroux-cbee74bdb4f85d6d8d4f192f0018ea023418e216.tar.gz
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.
-rw-r--r--alias.c5
-rw-r--r--all.h21
-rw-r--r--amd64/emit.c6
-rw-r--r--amd64/isel.c7
-rw-r--r--arm64/emit.c14
-rw-r--r--arm64/isel.c4
-rw-r--r--fold.c23
-rw-r--r--load.c4
-rw-r--r--parse.c6
-rw-r--r--rv64/emit.c21
-rw-r--r--rv64/isel.c2
-rw-r--r--util.c13
12 files changed, 68 insertions, 58 deletions
diff --git a/alias.c b/alias.c
index 19aca2a..6f082bc 100644
--- 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
index 00b8628..d852609 100644
--- 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
index 37dd1e9..a034a66 100644
--- 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
index 8c89378..63c304a 100644
--- 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
index 292dc79..38b7e1a 100644
--- 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
index 31ef242..9b062d8 100644
--- 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
index 2bb3a2f..75554bf 100644
--- 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
index 0d7944c..b16edd2 100644
--- 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
index 98ede39..04ef8be 100644
--- 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
index bb53c83..4ce6555 100644
--- 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
index 42c0097..8921a07 100644
--- 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
index a4bdb29..41b2625 100644
--- 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;
 	}