~mcf/cproc

qbe: Avoid redundant leaf ceq in switch codegen v1 PROPOSED

Roland Paterson-Jones: 1
 qbe: Avoid redundant leaf ceq in switch codegen

 1 files changed, 8 insertions(+), 4 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/~mcf/cproc/patches/53932/mbox | git am -3
Learn more about email & git

[PATCH] qbe: Avoid redundant leaf ceq in switch codegen Export this patch

For compact switch statements, middle-range case values are already
identified exactly by prior adjacent-value if-tree less-than/
greater-than comparisons.

In this case avoid the final ceq block.

Minor improvement to coremark ~3%.

make check && make bootstrap pass
---
 qbe.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/qbe.c b/qbe.c
index 33d6b71..8909617 100644
--- a/qbe.c
+++ b/qbe.c
@@ -1031,7 +1031,7 @@ funcinit(struct func *func, struct decl *d, struct init *init, bool hasinit)
}

static void
casesearch(struct func *f, int class, struct value *v, struct switchcase *c, struct block *defaultlabel)
casesearch(struct func *f, int class, struct value *v, struct switchcase *c, struct block *defaultlabel, struct switchcase *cleft, struct switchcase *cright)
{
	struct value *res, *key;
	struct block *label[3];
@@ -1040,6 +1040,10 @@ casesearch(struct func *f, int class, struct value *v, struct switchcase *c, str
		funcjmp(f, defaultlabel);
		return;
	}
	if (cleft && cright && c->node.key - cleft->node.key == 1 && cright->node.key - c->node.key == 1) {
		funcjmp(f, c->body);
		return;
	}
	label[0] = mkblock("switch_ne");
	label[1] = mkblock("switch_lt");
	label[2] = mkblock("switch_gt");
@@ -1052,15 +1056,15 @@ casesearch(struct func *f, int class, struct value *v, struct switchcase *c, str
	res = funcinst(f, class == 'w' ? ICULTW : ICULTL, 'w', v, key);
	funcjnz(f, res, NULL, label[1], label[2]);
	funclabel(f, label[1]);
	casesearch(f, class, v, c->node.child[0], defaultlabel);
	casesearch(f, class, v, c->node.child[0], defaultlabel, cleft, c);
	funclabel(f, label[2]);
	casesearch(f, class, v, c->node.child[1], defaultlabel);
	casesearch(f, class, v, c->node.child[1], defaultlabel, c, cright);
}

void
funcswitch(struct func *f, struct value *v, struct switchcases *c, struct block *defaultlabel)
{
	casesearch(f, qbetype(c->type).base, v, c->root, defaultlabel);
	casesearch(f, qbetype(c->type).base, v, c->root, defaultlabel, 0, 0);
}

/* emit */
-- 
2.34.1
On Wed, Jul 17, 2024 at 10:43 AM Roland Paterson-Jones
<rolandpj@gmail.com> wrote: