scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 7e457b1611c514787ce2f3c7c04b0fc46aa32850
parent 03a906c70a3836ad264de982a5c7fc0bfe9cf0ef
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Fri,  4 Sep 2015 22:47:56 +0200

Fix algebraic identities about logical operators

If the right part of a logic operator is a constant (which comes from
the folding of some comparision), then the logic operator can be
changed to a comma operator.

Diffstat:
Mcc1/fold.c | 34++++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)

diff --git a/cc1/fold.c b/cc1/fold.c @@ -377,8 +377,10 @@ ones(int n) } /* - * i || k => i,k - * i && k => i,k + * 0 || i => i + * 1 || i => 1 + * 0 && i => 0 + * 1 && i => i * i >> 0 => i * i << 0 => i * i + 0 => i @@ -394,7 +396,7 @@ ones(int n) static Node * identity(int *op, Node *lp, Node *rp) { - int iszero, isone, istrue; + int iszero, isone, istrue, val; if (!rp) return NULL; @@ -404,11 +406,12 @@ identity(int *op, Node *lp, Node *rp) istrue = !iszero && rp->constant; switch (*op) { - case OAND: case OOR: - if (rp->constant) - goto change_to_comma; - return NULL; + val = 1; + goto logic_operator; + case OAND: + val = 0; + goto logic_operator; case OSHL: case OSHR: case OBXOR: @@ -416,18 +419,18 @@ identity(int *op, Node *lp, Node *rp) case OBOR: case OSUB: if (iszero) - break; + goto free_right; return NULL; case OMUL: if (iszero) goto change_to_comma; case ODIV: if (isone) - break; + goto free_right; return NULL; case OBAND: if (cmpnode(rp, ones(lp->type->size * 8))) - break; + goto free_right; return NULL; case OMOD: if (isone) @@ -436,6 +439,17 @@ identity(int *op, Node *lp, Node *rp) return NULL; } +logic_operator: + if (!lp->constant) + return NULL; + if (cmpnode(lp, val)) + goto free_right; + +free_left: + freetree(lp); + return rp; + +free_right: freetree(rp); return lp;