summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/live.c29
-rw-r--r--lisc/parse.c26
-rw-r--r--lisc/test/live.ssa19
3 files changed, 54 insertions, 20 deletions
diff --git a/lisc/live.c b/lisc/live.c
index 82acae9..56dda71 100644
--- a/lisc/live.c
+++ b/lisc/live.c
@@ -1,5 +1,11 @@
 #include "lisc.h"
 
+static inline int
+issym(Ref r)
+{
+	return !req(r, R) && r.type == RSym;
+}
+
 /* liveness analysis
  * requires rpo computation
  */
@@ -10,30 +16,35 @@ filllive(Fn *f)
 	Ins *i;
 	Phi *p;
 	int z, n, chg;
+	uint a;
 	Bits *kill, *use, *k, *u, bt;
 
 	assert(f->ntmp <= NBit*BITS);
 	kill = alloc(f->ntmp * sizeof kill[0]);
 	use = alloc(f->ntmp * sizeof use[0]);
 	for (b=f->start; b; b=b->link) {
+		memset(&b->in, 0, sizeof(Bits));
+		memset(&b->out, 0, sizeof(Bits));
+	}
+	for (b=f->start; b; b=b->link) {
 		k = &kill[b->id];
 		u = &use[b->id];
-		for (p=b->phi; p; p=p->link)
+		for (p=b->phi; p; p=p->link) {
+			for (a=0; a<p->narg; a++)
+				if (issym(p->arg[a]))
+					BSET(p->blk[a]->out, p->arg[a].val);
 			BSET(*k, p->to.val);
+		}
 		for (i=b->ins; i-b->ins < b->nins; i++) {
-			if (!req(i->to, R))
+			if (issym(i->to))
 				BSET(*k, i->to.val);
-			if (!req(i->arg[0], R))
+			if (issym(i->arg[0]))
 				BSET(*u, i->arg[0].val);
-			if (!req(i->arg[1], R))
+			if (issym(i->arg[1]))
 				BSET(*u, i->arg[1].val);
 		}
-		if (!req(b->jmp.arg, R))
+		if (issym(b->jmp.arg))
 			BSET(*u, b->jmp.arg.val);
-		for (z=0; z<BITS; z++)
-			u->t[z] &= ~k->t[z];
-		memset(&b->in, 0, sizeof(Bits));
-		memset(&b->out, 0, sizeof(Bits));
 	}
 Again:
 	chg = 0;
diff --git a/lisc/parse.c b/lisc/parse.c
index d8e2095..47f9ec8 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -540,19 +540,19 @@ dumprset(Bits *b, Fn *fn)
 	int t;
 
 	for (t=Tmp0; t<fn->ntmp; t++)
-		if (BSET(*b, t))
-			fprintf(stderr, " %s", fn->sym[t].name);
-	fprintf(stderr, "\n");
+		if (BGET(*b, t))
+			printf(" %s", fn->sym[t].name);
 }
 
 int
 main(int ac, char *av[])
 {
-	int opt;
+	int opt, pr;
 	Fn *fn;
 
 	fn = parsefn(stdin);
 
+	pr = 1;
 	opt = 0;
 	if (ac > 1 && av[1][0] == '-')
 		opt = av[1][1];
@@ -561,7 +561,7 @@ main(int ac, char *av[])
 	case 'f': {
 		int tx, ntmp;
 
-		fprintf(stderr, "[test ssafix:");
+		fprintf(stderr, "[Testing SSA Reconstruction:");
 		fillpreds(fn);
 		for (ntmp=fn->ntmp, tx=Tmp0; tx<ntmp; tx++) {
 			fprintf(stderr, " %s", fn->sym[tx].name);
@@ -573,7 +573,7 @@ main(int ac, char *av[])
 	case 'r': {
 		int n;
 
-		fprintf(stderr, "[test rpo]\n");
+		fprintf(stderr, "[Testing RPO]\n");
 		fillrpo(fn);
 		assert(fn->rpo[0] == fn->start);
 		for (n=0;; n++)
@@ -587,22 +587,26 @@ main(int ac, char *av[])
 	case 'l': {
 		Blk *b;
 
-		fprintf(stderr, "[test liveness]\n");
+		fprintf(stderr, "[Testing Liveness]\n");
 		fillrpo(fn);
 		filllive(fn);
 		for (b=fn->start; b; b=b->link) {
-			fprintf(stderr, "> Block %s\n", b->name);
-			fprintf(stderr, "\tlive in :");
+			printf("> Block %s\n", b->name);
+			printf("\t in: [");
 			dumprset(&b->in, fn);
-			fprintf(stderr, "\tlive out:");
+			printf(" ]\n");
+			printf("\tout: [");
 			dumprset(&b->out, fn);
+			printf(" ]\n");
 		}
+		pr = 0;
 		break;
 	}
 	default:
 		break;
 	}
 
-	printfn(fn, stdout);
+	if (pr)
+		printfn(fn, stdout);
 	return 0;
 }
diff --git a/lisc/test/live.ssa b/lisc/test/live.ssa
new file mode 100644
index 0000000..2d5546d
--- /dev/null
+++ b/lisc/test/live.ssa
@@ -0,0 +1,19 @@
+# this control flow graph is irreducible
+# yet, we expecet the liveness analysis
+# to work properly and make %x live in
+# the block @left
+#
+# nothing should ever be live at the entry
+
+@start
+	%b = copy 0
+	%x = copy 10
+	jez 0, @left, @loop
+@left
+	jmp @inloop
+@loop
+	%x1 = add %x, 1
+@inloop
+	%b1 = add %b, 1
+@endloop
+	jmp @loop