[hackers] [scc] Simplify multiplicative expressions || Roberto E. Vargas Caballero
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