From 5e46b36476c57418c0bd3cfced2d4c63eb7d1048 Mon Sep 17 00:00:00 2001 From: lemon Date: Wed, 31 May 2023 08:57:22 +0200 Subject: '!' optimizations --- lex.c | 11 +++++++---- parse.c | 22 ++++++++++++++++++++-- test.c | 12 ++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/lex.c b/lex.c index f82f255..a41bd0d 100644 --- a/lex.c +++ b/lex.c @@ -376,10 +376,13 @@ Begin: case ' ': case '\r': case '\t': goto Begin; break; - case '!': case '(': case ')': case ',': - case ':': case ';': case '?': case '[': - case ']': case '{': case '}': case '~': - case '$': case '@': case '`': case '\\': case TKEOF: case '\n': + case '(': case ')': case ',': case ':': + case ';': case '?': case '[': case ']': + case '{': case '}': case '~': case '$': + case '@': case '`': case '\\': case TKEOF: case '\n': + RET(c); + case '!': + if (match(pr, '=')) RET(TKNEQ); RET(c); case '#': if (match(pr, '#')) RET(TKPPCAT); diff --git a/parse.c b/parse.c index 16293f9..d3a5f99 100644 --- a/parse.c +++ b/parse.c @@ -1149,6 +1149,19 @@ Loop: condjump(fn, &ex->sub[1], tr, fl); useblk(fn, next2); condjump(fn, &ex->sub[2], tr, fl); + } else if (ex->t == ELOGNOT) { + Negate: + /* swap tr,fl */ + next = tr; + tr = fl; + fl = next; + ex = &ex->sub[0]; + goto Loop; + } else if (ex->t == EEQU && isnullpo(&ex->sub[1])) { /* == 0 */ + goto Negate; + } else if (ex->t == ENEQ && isnullpo(&ex->sub[1])) { /* != 0 */ + ex = &ex->sub[0]; + goto Loop; } else { putjump(fn, Jbcnd, exprvalue(fn, ex), tr, fl); } @@ -1204,7 +1217,10 @@ condexprrec(struct function *fn, const struct expr *ex, bool tobool, static union ref condexprvalue(struct function *fn, const struct expr *ex) { - struct condphis phis = {0}; + struct block *blkbuf[8]; + union ref refbuf[8]; + struct condphis phis = { VINIT(blkbuf, arraylength(blkbuf)), + VINIT(refbuf, arraylength(refbuf))}; struct block *dst = newblk(fn); union ref r; condexprrec(fn, ex, 0, &phis, dst, NULL); @@ -1258,7 +1274,9 @@ exprvalue(struct function *fn, const struct expr *ex) ins.cls = cls; return addinstr(fn, ins); case ELOGNOT: - ins.op = Oequ; + for (; sub->t == ELOGNOT; ex = sub, sub = sub->sub) + swp ^= 1; + ins.op = Oequ + swp; ins.l = exprvalue(fn, sub); ins.l = cvt(fn, ex->ty.t, sub->ty.t, ins.l); ins.r = mkintcon(fn, cls, 0); diff --git a/test.c b/test.c index e16e415..5adb14f 100644 --- a/test.c +++ b/test.c @@ -7,6 +7,8 @@ wawa #else boop #endif + +#define NULL ((void *)0) int glob [ wow+wow]; struct foo { @@ -32,4 +34,14 @@ int test4(int c) { : 0; } +int test5(int *p) +{ + return p ? *p : 0; +} + +int test6(int x) +{ + return !!!!x; +} + // -- cgit v1.2.3