commit 022b66c883b41558202c1e602ee98c44e8c6a146
parent f9b9be337e76a5a4c16d48639e4a3379d9fdd639
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Thu, 23 Jul 2015 10:37:25 +0200
Simplify simplify()
Using overloading in symplify() will generate a lot of
functions very similars, so it is better to use a generic
approach with a big switch.
Diffstat:
M | cc1/code.c | | | 153 | +++++++++++++++++++------------------------------------------------------------ |
1 file changed, 37 insertions(+), 116 deletions(-)
diff --git a/cc1/code.c b/cc1/code.c
@@ -130,14 +130,6 @@ static Node *simple_add(Type *, Node *, Node *),
*simple_div(Type *, Node *, Node *),
*simple_mod(Type *, Node *, Node *);
-static Node *(*opsimp[])(Type *, Node *, Node *) = {
- [OADD] = simple_add,
- [OSUB] = simple_sub,
- [OMUL] = simple_mul,
- [ODIV] = simple_div,
- [OMOD] = simple_mod
-};
-
void
freetree(Node *np)
{
@@ -392,130 +384,59 @@ sizeofnode(Type *tp)
return constnode(sym);
}
-static Node *
-simple_mod(Type *tp, Node *lp, Node *rp)
-{
- Symbol *sym, *ls = lp->sym, *rs = rp->sym;
-
- switch (tp->op) {
- case INT:
- sym = newsym(NS_IDEN);
- sym->type = tp;
- if (tp->sign) {
- if (rs->u.i == 0)
- goto division_by_0;
- sym->u.i = ls->u.i % rs->u.i;
- } else {
- if (rs->u.u == 0)
- goto division_by_0;
- sym->u.u = ls->u.u % rs->u.u;
- }
- return constnode(sym);
- default:
- return NULL;
- }
+#define SYMICMP(sym, val) (((sym)->type->sign) ? \
+ (sym)->u.i == (val) : (sym)->u.u == (val))
-division_by_0:
- warn("division by 0");
- return NULL;
-}
+#define FOLDINT(sym, ls, rs, op) (((sym)->type->sign) ? \
+ ((sym)->u.i = ((ls)->u.i op (rs)->u.i)) : \
+ ((sym)->u.u = ((ls)->u.u op (rs)->u.u)))
-static Node *
-simple_div(Type *tp, Node *lp, Node *rp)
+Node *
+simplify(Node *np)
{
+ Node *lp = np->left, *rp = np->right;
Symbol *sym, *ls = lp->sym, *rs = rp->sym;
+ Type *tp = np->type;
+
+ if (!lp->constant || !rp->constant)
+ return np;
switch (tp->op) {
case INT:
sym = newsym(NS_IDEN);
sym->type = tp;
- if (tp->sign) {
- if (rs->u.i == 0)
+ switch (np->op) {
+ case OADD:
+ FOLDINT(sym, ls, rs, +);
+ break;
+ case OSUB:
+ FOLDINT(sym, ls, rs, -);
+ break;
+ case OMUL:
+ FOLDINT(sym, ls, rs, *);
+ break;
+ case ODIV:
+ if (SYMICMP(sym, 0))
goto division_by_0;
- sym->u.i = ls->u.i / rs->u.i;
- } else {
- if (rs->u.u == 0)
+ FOLDINT(sym, ls, rs, /);
+ break;
+ case OMOD:
+ if (SYMICMP(sym, 0))
goto division_by_0;
- sym->u.u = ls->u.u / rs->u.u;
+ FOLDINT(sym, ls, rs, %);
+ break;
+ default:
+ abort();
}
- return constnode(sym);
+ break;
default:
- return NULL;
+ return np;
}
+ freetree(np);
+ return constnode(sym);
+
division_by_0:
warn("division by 0");
- return NULL;
-}
-
-static Node *
-simple_mul(Type *tp, Node *lp, Node *rp)
-{
- Symbol *sym, *ls = lp->sym, *rs = rp->sym;
-
- switch (tp->op) {
- case INT:
- sym = newsym(NS_IDEN);
- sym->type = tp;
- if (tp->sign)
- sym->u.i = ls->u.i * rs->u.i;
- else
- sym->u.u = ls->u.u * rs->u.u;
- return constnode(sym);
- default:
- return NULL;
- }
-}
-
-static Node *
-simple_add(Type *tp, Node *lp, Node *rp)
-{
- Symbol *sym, *ls = lp->sym, *rs = rp->sym;
-
- switch (tp->op) {
- case INT:
- sym = newsym(NS_IDEN);
- sym->type = tp;
- if (tp->sign)
- sym->u.i = ls->u.i + rs->u.i;
- else
- sym->u.u = ls->u.u + rs->u.u;
- return constnode(sym);
- default:
- return NULL;
- }
-}
-
-static Node *
-simple_sub(Type *tp, Node *lp, Node *rp)
-{
- Symbol *sym, *ls = lp->sym, *rs = rp->sym;
-
- switch (tp->op) {
- case INT:
- sym = newsym(NS_IDEN);
- sym->type = tp;
- if (tp->sign)
- sym->u.i = ls->u.i - rs->u.i;
- else
- sym->u.u = ls->u.u - rs->u.u;
- return constnode(sym);
- default:
- return NULL;
- }
-}
-
-Node *
-simplify(Node *np)
-{
- Node *new, *lp = np->left, *rp = np->right;
-
- if (!lp->constant || !rp->constant)
- return np;
- new = (*opsimp[np->op])(np->type, lp, rp);
- if (new) {
- freetree(np);
- np = new;
- }
return np;
}