~mpu/qbe

Extend stack slot promotion rules v1 PROPOSED

Xavier Lambein: 1
 Extend stack slot promotion rules

 1 files changed, 27 insertions(+), 1 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~mpu/qbe/patches/45217/mbox | git am -3
Learn more about email & git

[PATCH] Extend stack slot promotion rules Export this patch

This introduces two changes to the stack slot promotion. First,
`promote` used to only check the first block for potential promotions.
I've changed it so that it now iterates through all the blocks in
a function.

Second, `blit`s were never considered when checking for stack slot
promotions, when in fact they can sometimes be promoted to a `load`. I
added a clause for this in `promote`.
---
Hey! I make heavy use of both `alloca` outside the first block, and of
`blit`s between two allocas, and I noticed that QBE wasn't always doing
a great job at getting rid of them. I think my patch is a good solution
to that, so I was wondering if you'd be interested to upstream it.

Happy to make any change necessary :-) Thanks for your work on QBE!

 mem.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/mem.c b/mem.c
index 944cd2f..b7f970e 100644
--- a/mem.c
+++ b/mem.c
@@ -15,7 +15,7 @@ promote(Fn *fn)
	int s, k;

	/* promote uniform stack slots to temporaries */
	b = fn->start;
	for (b=fn->start; b; b=b->link) {
	for (i=b->ins; i<&b->ins[b->nins]; i++) {
		if (Oalloc > i->op || i->op > Oalloc1)
			continue;
@@ -43,6 +43,18 @@ promote(Fn *fn)
				k = optab[l->op].argcls[0][0];
				continue;
			}
			if (l->op == Oblit0)
			if (req(i->to, l->arg[1]) && !req(i->to, l->arg[0]))
			if (s == -1 || s == rsval((l+1)->arg[0]))
			if (k == -1 || k == optab[l->op].argcls[0][0]) {
				s = rsval((l+1)->arg[0]);
				switch(s) {
				case 1: case 2: case 4: k = Kw; break;
				case 8: k = Kl; break;
				default: goto Skip;
				}
				continue;
			}
			goto Skip;
		}
		/* get rid of the alloc and replace uses */
@@ -58,6 +70,19 @@ promote(Fn *fn)
				l->arg[1] = R;
				t->nuse--;
				t->ndef++;
			} else if (l->op == Oblit0) {
				l->cls = k;
				switch(s) {
				case 1: l->op = Oloadsb; break;
				case 2: l->op = Oloadsh; break;
				case 4: l->op = Oloadsw; break;
				case 8: l->op = Oload; break;
				}
				l->to = l->arg[1];
				l->arg[1] = R;
				t->nuse--;
				t->ndef++;
				*(l+1) = (Ins){.op = Onop};
			} else {
				if (k == -1)
					err("slot %%%s is read but never stored to",
@@ -85,6 +110,7 @@ promote(Fn *fn)
		}
	Skip:;
	}
	}
	if (debug['M']) {
		fprintf(stderr, "\n> After slot promotion:\n");
		printfn(fn, stderr);
-- 
2.40.1
Thank you Xavier, I will try to review your patch shortly.