summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-11-20 21:47:11 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2022-11-20 21:47:11 +0100
commit45ab1e5aa339c350e3efbbc9ad7abdfc22e73187 (patch)
treea69c872ac4570333237dc9efd282713c79169681
parent72006061950f8080f54d642f04510178e06fc27d (diff)
downloadroux-45ab1e5aa339c350e3efbbc9ad7abdfc22e73187.tar.gz
stored bytes in Alias information
Stack slots may have padding
bytes, and if we want to have
precise liveness information
it's important that we are able
to tell them apart.

This patch extends fillalias()
to remember for every slot
what bytes were ever assigned.
In case the slot address does
not escape we know that only
these bytes matter.

To save space, we only store
this information if the slot
size is less than or equal to
NBit.

The Alias struct was reworked
a bit to save some space. I am
still not very satisfied with
its layout though.
-rw-r--r--alias.c30
-rw-r--r--all.h12
-rw-r--r--load.c4
3 files changed, 38 insertions, 8 deletions
diff --git a/alias.c b/alias.c
index 44686dd..fd11bd2 100644
--- a/alias.c
+++ b/alias.c
@@ -18,8 +18,8 @@ getalias(Alias *a, Ref r, Fn *fn)
 		c = &fn->con[r.val];
 		if (c->type == CAddr) {
 			a->type = ASym;
-			a->label = c->label;
-			a->reloc = c->reloc;
+			a->u.sym.label = c->label;
+			a->u.sym.con = r.val;
 		} else
 			a->type = ACon;
 		a->offset = c->bits.i;
@@ -52,7 +52,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.label != aq.label)
+		if (ap.u.sym.label != aq.u.sym.label)
 			return MayAlias;
 		if (ovlap)
 			return MustAlias;
@@ -108,9 +108,12 @@ void
 fillalias(Fn *fn)
 {
 	uint n, m;
+	int64_t x;
+	bits w;
 	Blk *b;
 	Phi *p;
 	Ins *i;
+	Con *c;
 	Alias *a, a0, a1;
 
 	for (n=0; n<fn->nblk; ++n) {
@@ -135,6 +138,14 @@ fillalias(Fn *fn)
 				if (Oalloc <= i->op && i->op <= Oalloc1) {
 					a->type = ALoc;
 					a->slot = a;
+					a->u.loc.sz = -1;
+					if (rtype(i->arg[0]) == RCon) {
+						c = &fn->con[i->arg[0].val];
+						x = c->bits.i;
+						if (c->type == CBits)
+						if (0 <= x && x <= NBit)
+							a->u.loc.sz = x;
+					}
 				} else {
 					a->type = AUnk;
 					a->slot = 0;
@@ -165,6 +176,19 @@ fillalias(Fn *fn)
 				if (i->op != Oargc)
 					esc(i->arg[1], fn);
 			}
+			if (isstore(i->op))
+			if (rtype(i->arg[1]) == RTmp) {
+				a = &fn->tmp[i->arg[1].val].alias;
+				if (a->slot) {
+					assert(astack(a->type));
+					x = a->offset;
+					if (0 <= x && x < NBit) {
+						w = BIT(storesz(i)) - 1;
+						a->slot->u.loc.m |= w << x;
+					} else
+						a->slot->u.loc.sz = -1;
+				}
+			}
 		}
 		esc(b->jmp.arg, fn);
 	}
diff --git a/all.h b/all.h
index 4c3c35f..43cdd62 100644
--- a/all.h
+++ b/all.h
@@ -281,9 +281,17 @@ struct Alias {
 	#define astack(t) ((t) & 1)
 	} type;
 	int base;
-	uint32_t label;
 	int64_t offset;
-	int reloc;
+	union {
+		struct {
+			uint32_t label;
+			int con;
+		} sym;
+		struct {
+			int sz; /* -1 if > NBit */
+			bits m;
+		} loc;
+	} u;
 	Alias *slot;
 };
 
diff --git a/load.c b/load.c
index 01718c0..0d7944c 100644
--- a/load.c
+++ b/load.c
@@ -152,10 +152,8 @@ load(Slice sl, bits msk, Loc *l)
 			break;
 		case ACon:
 		case ASym:
-			c.type = CAddr;
-			c.label = a->label;
+			c = curf->con[a->u.sym.con];
 			c.bits.i = a->offset;
-			c.reloc = a->reloc;
 			r = newcon(&c, curf);
 			break;
 		}