scc

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

commit 4343d4491f8251b0af5065d3898a2dc7cf8abf2f
parent 198b6ea63a13382db039b8cf21a5b4798d62c659
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat,  5 Sep 2015 19:54:51 +0200

Add more identities for logic operators

Diffstat:
Mcc1/fold.c | 97++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
1 file changed, 59 insertions(+), 38 deletions(-)

diff --git a/cc1/fold.c b/cc1/fold.c @@ -376,83 +376,104 @@ ones(int n) return v; } -/* - * 0 || i => i - * 1 || i => 1 - * 0 && i => 0 - * 1 && i => i - * i >> 0 => i - * i << 0 => i - * i + 0 => i - * i - 0 => i - * i | 0 => i - * i ^ 0 => i - * i * 0 => i,0 - * i * 1 => i - * i / 1 => i - * i & ~0 => i - * i % 1 => i,1 - */ static Node * identity(int *op, Node *lp, Node *rp) { - int iszero, isone, istrue, val; + int iszeror, isoner, istruer, val; + int iszerol, isonel, istruel; if (!rp) return NULL; - iszero = cmpnode(rp, 0); - isone = cmpnode(rp, 1), - istrue = !iszero && rp->constant; + iszeror = cmpnode(rp, 0); + isoner = cmpnode(rp, 1), + istruer = !iszeror && rp->constant; + iszerol = cmpnode(lp, 0); + isonel = cmpnode(lp, 1), + istruel = !iszerol && lp->constant; switch (*op) { case OOR: - val = 1; - goto logic_operator; + /* + * 1 || i => 1 (free right) + * i || 0 => i (free right) + * 0 || i => i (free left) + * i || 1 => i,1 (comma) + */ + if (isonel | iszeror) + goto free_right; + if (iszerol) + goto free_left; + if (isoner) + goto change_to_comma; + return NULL; case OAND: - val = 0; - goto logic_operator; + /* + * 0 && i => 0 (free right) + * i && 1 => i (free right) + * 1 && i => i (free left) + * i && 0 => i,0 (comma) + */ + if (iszerol | isoner) + goto free_right; + if (isonel) + goto free_left; + if (iszeror) + goto change_to_comma; + return NULL; case OSHL: case OSHR: case OBXOR: case OADD: case OBOR: case OSUB: - if (iszero) + /* + * i >> 0 => i + * i << 0 => i + * i + 0 => i + * i - 0 => i + * i | 0 => i + * i ^ 0 => i + */ + if (iszeror) goto free_right; return NULL; case OMUL: - if (iszero) + /* + * i * 0 => i,0 + * i * 1 => i + */ + if (iszeror) goto change_to_comma; + if (isoner) + goto free_right; + return NULL; case ODIV: - if (isone) + /* i / 1 => i */ + if (isoner) goto free_right; return NULL; case OBAND: + /* i & ~0 => i */ if (cmpnode(rp, ones(lp->type->size * 8))) goto free_right; return NULL; case OMOD: - if (isone) + /* i % 1 => i,1 */ + if (isoner) goto change_to_comma; default: return NULL; } -logic_operator: - if (!lp->constant) - return NULL; - if (cmpnode(lp, val)) - goto free_right; +free_right: + freetree(rp); + return lp; free_left: freetree(lp); return rp; -free_right: - freetree(rp); - return lp; - change_to_comma: *op = OCOMMA; return NULL;