~mcf/cproc

Use ceqw/l/s/d for logical not (!) operator instead of jnz+phi v1 PROPOSED

Roland Paterson-Jones: 1
 Use ceqw/l/s/d for logical not (!) operator instead of jnz+phi

 1 files changed, 10 insertions(+), 7 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/55499/mbox | git am -3
Learn more about email & git

[PATCH] Use ceqw/l/s/d for logical not (!) operator instead of jnz+phi Export this patch

This leads to neater code - single instruction, no more
blocks, and facilitates further QBE optimisations.

[Note: applies on top of Quentin's "logflow" patch]

Fixes previous patch which always generates ceqw.

Testing:

cproc bootstrap; cproc->qbe->cproc->qbe double bootstrap
coremark and a few others

Specific tests:

rolandpj@rolandpj-VivoBook-ASUSLaptop-X515DAP-M515DA:~/src/cproc$ cat ../rpj-qbe-test/tlnot.c
int inoti(int v)
{
	return !v;
}

int inotl(long v)
{
	return !v;
}

int inotp(void *p)
{
	return !p;
}

int inotf(float f)
{
	return !f;
}

int inotd(double d)
{
	return !d;
}

long lnotp(void *p)
{
	return !p;
}

rolandpj@rolandpj-VivoBook-ASUSLaptop-X515DAP-M515DA:~/src/cproc$ cproc-qbe ../rpj-qbe-test/tlnot.c
export
function w $inoti(w %.1) {
@start.1
	%.2 =l alloc4 4
	storew %.1, %.2
@body.2
	%.3 =w loadw %.2
	%.4 =w ceqw %.3, 0
	ret %.4
}
export
function w $inotl(l %.1) {
@start.3
	%.2 =l alloc8 8
	storel %.1, %.2
@body.4
	%.3 =l loadl %.2
	%.4 =w ceql %.3, 0
	ret %.4
}
export
function w $inotp(l %.1) {
@start.5
	%.2 =l alloc8 8
	storel %.1, %.2
@body.6
	%.3 =l loadl %.2
	%.4 =w ceql %.3, 0
	ret %.4
}
export
function w $inotf(s %.1) {
@start.7
	%.2 =l alloc4 4
	stores %.1, %.2
@body.8
	%.3 =s loads %.2
	%.4 =w ceqs %.3, s_0
	ret %.4
}
export
function w $inotd(d %.1) {
@start.9
	%.2 =l alloc8 8
	stored %.1, %.2
@body.10
	%.3 =d loadd %.2
	%.4 =w ceqd %.3, d_0
	ret %.4
}
export
function l $lnotp(l %.1) {
@start.11
	%.2 =l alloc8 8
	storel %.1, %.2
@body.12
	%.3 =l loadl %.2
	%.4 =w ceql %.3, 0
	%.5 =l extsw %.4
	ret %.5
}
---
 qbe.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/qbe.c b/qbe.c
index 7951409..9ed9e2a 100644
--- a/qbe.c
+++ b/qbe.c
@@ -702,12 +702,6 @@ funcbranch(struct func *f, struct expr *e, struct block *bt, struct block *bf)

	/* Maybe we we could do something for EXPRCOND as well. */
	switch (e->kind) {
	case EXPRUNARY:
		if (e->op == TLNOT) {
			funcbranch(f, e->base, bf, bt);
			return;
		}
		break;
	case EXPRBINARY:
		if (e->op == TLOR || e->op == TLAND) {
			if (e->op == TLOR) {
@@ -833,7 +827,16 @@ funcexpr(struct func *f, struct expr *e)
	case EXPRUNARY:
		switch (e->op) {
		case TLNOT:
			return funclogical(f, e);
			r = funcexpr(f, e->base);
			switch (qbetype(e->base->type).base) {
			case 'w': op = ICEQW; v = mkintconst(0); break;
			case 'l': op = ICEQL; v = mkintconst(0); break;
			case 's': op = ICEQS; v = mkfltconst(VALUE_FLTCONST, 0); break;
			case 'd': op = ICEQD; v = mkfltconst(VALUE_DBLCONST, 0); break;
			default: fatal("internal error; unexpected unary not arg type");
			}
			assert(qbetype(e->type).base == 'w');
			return funcinst(f, op, 'w', r, v);
		case TBAND:
			lval = funclval(f, e->base);
			return lval.addr;
-- 
2.34.1