# [hackers] [scc] Add algebraic identities simplifications || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 26 Aug 2015 22:32:48 +0200 (CEST)

commit cd9f71bbfc1f5bf8fc7a63931c29cce9acabda97
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Aug 26 21:44:06 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Aug 26 21:44:06 2015 +0200

These kind of expressions are common in array expressions, so this commit
simmplify a lot the intermediate file, and makes easier to validate the
regression tests.

diff --git a/cc1/expr.c b/cc1/expr.c
index 9ffa3a8..7414c00 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -40,9 +40,19 @@ static Node *
simplify(unsigned char op, Type *tp, Node *lp, Node *rp)
{
Symbol *sym, *ls, *rs, aux;
+ int iszero, isone, noconst = 0;

- if (!lp->constant || !rp->constant)
+ if (!lp->constant && !rp->constant)
goto no_simplify;
+ if (!rp->constant) {
+ Node *np;
+ np = lp;
+ lp = rp;
+ rp = np;
+ }
+ if (!lp->constant)
+ noconst = 1;
+
ls = lp->sym, rs = rp->sym;
aux.type = tp;

_AT_@ -62,71 +72,143 @@ simplify(unsigned char op, Type *tp, Node *lp, Node *rp)
}

switch (tp->op) {
+ case PTR:
case INT:
cmp_integers:
+ iszero = SYMICMP(rs, 0);
+ isone = SYMICMP(rs, 1);
switch (op) {
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, +);
break;
case OSUB:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, -);
break;
case OMUL:
+ if (isone)
+ return lp;
+ if (iszero)
+ return constnode(zero);
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, *);
break;
case ODIV:
- if (SYMICMP(&aux, 0))
+ if (isone)
+ return lp;
+ if (iszero)
goto division_by_0;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, /);
break;
case OMOD:
- if (SYMICMP(&aux, 0))
+ if (iszero)
goto division_by_0;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, %);
break;
case OSHL:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, <<);
break;
case OSHR:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, >>);
break;
case OBAND:
+ if (SYMICMP(rs, ~0))
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, &);
break;
case OBXOR:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, ^);
break;
case OBOR:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, |);
break;
case OAND:
+ if (!iszero)
+ return lp;
+ /* TODO: What happens with something like f(0) && 0? */
+ if (noconst)
+ goto no_simplify;
FOLDINT(&aux, ls, rs, &&);
break;
case OOR:
+ if (iszero)
+ return lp;
+ if (noconst)
+ goto no_simplify;
+ /* TODO: What happens with something like f(0) || 1? */
FOLDINT(&aux, ls, rs, ||);
break;
case OLT:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, <);
break;
case OGT:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, >);
break;
case OGE:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, >=);
break;
case OLE:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, <=);
break;
case OEQ:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, ==);
break;
case ONE:
+ /* TODO: what happens with signess? */
+ if (noconst)
+ goto no_simplify;
aux.u.i = CMPISYM(&aux, ls, rs, !=);
break;
}
break;
case FLOAT:
cmp_floats:
+ /* TODO: Add algebraic reductions for floats */
switch (op) {