[hackers] [scc] Simplify multiplicative expressions || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 22 Jul 2015 18:01:42 +0200 (CEST)

commit 04eaf8bf9813e47819a823534b8b53e481088f77
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Jul 22 14:30:27 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Jul 22 14:30:27 2015 +0200

    Simplify multiplicative expressions

diff --git a/cc1/code.c b/cc1/code.c
index b1fdbe9..4610876 100644
--- a/cc1/code.c
+++ b/cc1/code.c
_AT_@ -124,15 +124,20 @@ void (*opcode[])(unsigned, void *) = {
         [OSWITCH] = emitswitch
 };
 
-static Node *simple_sub(Node *), *simple_add(Node *);
+static Node *simple_add(Type *, Node *, Node *),
+ *simple_sub(Type *, Node *, Node *),
+ *simple_mul(Type *, Node *, Node *),
+ *simple_div(Type *, Node *, Node *),
+ *simple_mod(Type *, Node *, Node *);
 
-static Node *(*opsimp[])(Node *) = {
+static Node *(*opsimp[])(Type *, Node *, Node *) = {
         [OADD] = simple_add,
- [OSUB] = simple_sub
-
+ [OSUB] = simple_sub,
+ [OMUL] = simple_mul,
+ [ODIV] = simple_div,
+ [OMOD] = simple_mod
 };
 
-
 void
 freetree(Node *np)
 {
_AT_@ -388,10 +393,83 @@ sizeofnode(Type *tp)
 }
 
 static Node *
-simple_add(Node *np)
+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;
+ }
+
+division_by_0:
+ warn("division by 0");
+ return NULL;
+}
+
+static Node *
+simple_div(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;
+ }
+
+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)
 {
- Node *lp = np->left, *rp = np->right;
- Type *tp = np->type;
         Symbol *sym, *ls = lp->sym, *rs = rp->sym;
 
         switch (tp->op) {
_AT_@ -402,18 +480,15 @@ simple_add(Node *np)
                         sym->u.i = ls->u.i + rs->u.i;
                 else
                         sym->u.u = ls->u.u + rs->u.u;
- freetree(np);
                 return constnode(sym);
         default:
- return np;
+ return NULL;
         }
 }
 
 static Node *
-simple_sub(Node *np)
+simple_sub(Type *tp, Node *lp, Node *rp)
 {
- Node *lp = np->left, *rp = np->right;
- Type *tp = np->type;
         Symbol *sym, *ls = lp->sym, *rs = rp->sym;
 
         switch (tp->op) {
_AT_@ -424,17 +499,23 @@ simple_sub(Node *np)
                         sym->u.i = ls->u.i - rs->u.i;
                 else
                         sym->u.u = ls->u.u - rs->u.u;
- freetree(np);
                 return constnode(sym);
         default:
- return np;
+ return NULL;
         }
 }
 
 Node *
 simplify(Node *np)
 {
- if (!np->left->constant || !np->right->constant)
+ Node *new, *lp = np->left, *rp = np->right;
+
+ if (!lp->constant || !rp->constant)
                 return np;
- return (*opsimp[np->op])(np);
+ new = (*opsimp[np->op])(np->type, lp, rp);
+ if (new) {
+ freetree(np);
+ np = new;
+ }
+ return np;
 }
diff --git a/cc1/expr.c b/cc1/expr.c
index a00db59..8432df1 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -667,6 +667,7 @@ mul(void)
                 }
                 next();
                 np = (*fun)(op, np, cast());
+ np = simplify(np);
         }
 }
 
Received on Wed Jul 22 2015 - 18:01:42 CEST

This archive was generated by hypermail 2.3.0 : Wed Jul 22 2015 - 18:12:17 CEST