[hackers] [scc] Move fold stuff to an own file || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Thu, 27 Aug 2015 18:17:48 +0200 (CEST)

commit 138e890629e9b4059e62fd6111be6ec01afb97ec
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Thu Aug 27 17:24:14 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Thu Aug 27 17:24:14 2015 +0200

    Move fold stuff to an own file
    
    This is going to be large, so it is better move it away
    from expr.c, because it is increasing the size of it too much.

diff --git a/cc1/Makefile b/cc1/Makefile
index b49fab3..3042462 100644
--- a/cc1/Makefile
+++ b/cc1/Makefile
_AT_@ -1,7 +1,7 @@
 include ../config.mk
 
 OBJS = types.o decl.o lex.o error.o symbol.o main.o expr.o \
- code.o stmt.o cpp.o
+ code.o stmt.o cpp.o fold.o
 
 all: cc1
 
diff --git a/cc1/cc1.h b/cc1/cc1.h
index 4515125..a49ce87 100644
--- a/cc1/cc1.h
+++ b/cc1/cc1.h
_AT_@ -347,11 +347,17 @@ extern Node *sizeofnode(Type *tp);
 extern void freetree(Node *np);
 #define BTYPE(np) ((np)->type->op)
 
+/* fold.c */
+extern Node *simplify(unsigned char op, Type *tp, Node *lp, Node *rp);
+extern Node *usimplify(unsigned char op, Type *tp, Node *np);
+extern Node *constconv(Node *np, Type *newtp);
+
 /* expr.c */
 extern Node *expr(void), *negate(Node *np), *constexpr(void);
 extern Node *convert(Node *np, Type *tp1, char iscast);
 extern Node *eval(Node *np), *iconstexpr(void), *condition(void);
 extern Node *exp2cond(Node *np, char neg);
+extern bool isnodecmp(int op);
 
 /* cpp.c */
 extern void icpp(void);
diff --git a/cc1/expr.c b/cc1/expr.c
index b4cc289..dadc2d3 100644
--- a/cc1/expr.c
+++ b/cc1/expr.c
_AT_@ -8,9 +8,12 @@
 #include "cc1.h"
 
 
+#define SYMICMP(sym, val) (((sym)->type->sign) ? \
+ (sym)->u.i == (val) : (sym)->u.u == (val))
+
 Node *expr(void);
 
-static bool
+bool
 isnodecmp(int op)
 {
         switch (op) {
_AT_@ -26,285 +29,6 @@ isnodecmp(int op)
         }
 }
 
-#define SYMICMP(sym, val) (((sym)->type->sign) ? \
- (sym)->u.i == (val) : (sym)->u.u == (val))
-
-#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)))
-
-#define CMPISYM(sym, ls, rs, op) (((sym)->type->sign) ? \
- ((ls)->u.i op (rs)->u.i) : ((ls)->u.u op (rs)->u.u))
-
-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)
- 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;
-
- /* TODO: Add overflow checkings */
-
- if (isnodecmp(op)) {
- /*
- * Comparision nodes have integer type
- * but the operands can have different
- * type.
- */
- switch (BTYPE(lp)) {
- case INT: goto cmp_integers;
- case FLOAT: goto cmp_floats;
- default: goto no_simplify;
- }
- }
-
- switch (tp->op) {
- case PTR:
- case INT:
- cmp_integers:
- iszero = SYMICMP(rs, 0);
- isone = SYMICMP(rs, 1);
- switch (op) {
- case OADD:
- 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 (isone)
- return lp;
- if (iszero)
- goto division_by_0;
- if (noconst)
- goto no_simplify;
- FOLDINT(&aux, ls, rs, /);
- break;
- case OMOD:
- 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) {
- case OADD:
- aux.u.f = ls->u.f + rs->u.f;
- break;
- case OSUB:
- aux.u.f = ls->u.f - rs->u.f;
- break;
- case OMUL:
- aux.u.f = ls->u.f * rs->u.f;
- break;
- case ODIV:
- if (rs->u.f == 0.0)
- goto division_by_0;
- aux.u.f = ls->u.f / rs->u.f;
- break;
- case OLT:
- aux.u.i = ls->u.f < rs->u.f;
- break;
- case OGT:
- aux.u.i = ls->u.f > rs->u.f;
- break;
- case OGE:
- aux.u.i = ls->u.f >= rs->u.f;
- break;
- case OLE:
- aux.u.i = ls->u.f <= rs->u.f;
- break;
- case OEQ:
- aux.u.i = ls->u.f == rs->u.f;
- break;
- case ONE:
- aux.u.i = ls->u.f != rs->u.f;
- break;
- }
- break;
- default:
- goto no_simplify;
- }
-
- sym = newsym(NS_IDEN);
- sym->type = tp;
- sym->u = aux.u;
- return constnode(sym);
-
-division_by_0:
- warn("division by 0");
-
-no_simplify:
- return node(op, tp, lp, rp);
-}
-
-#define UFOLDINT(sym, ls, op) (((sym)->type->sign) ? \
- ((sym)->u.i = (op (ls)->u.i)) : \
- ((sym)->u.u = (op (ls)->u.u)))
-
-static Node *
-usimplify(unsigned char op, Type *tp, Node *np)
-{
- Symbol *sym, *ns, aux;
-
- if (!np->constant)
- goto no_simplify;
- ns = np->sym;
- aux.type = tp;
-
- switch (tp->op) {
- case INT:
- switch (op) {
- case ONEG:
- UFOLDINT(&aux, ns, -);
- break;
- case OCPL:
- UFOLDINT(&aux, ns, ~);
- break;
- default:
- goto no_simplify;
- }
- break;
- case FLOAT:
- if (op != ONEG)
- goto no_simplify;
- aux.u.f = -ns->u.f;
- break;
- default:
- goto no_simplify;
- }
-
- sym = newsym(NS_IDEN);
- sym->type = tp;
- sym->u = aux.u;
- return constnode(sym);
-
-no_simplify:
- return node(op, tp, np, NULL);
-}
-
 static Node *
 promote(Node *np)
 {
_AT_@ -423,54 +147,6 @@ integeruop(char op, Node *np)
         return usimplify(op, np->type, np);
 }
 
-/* TODO: check validity of types */
-
-static Node *
-constconv(Node *np, Type *newtp)
-{
- Type *oldtp = np->type;
- Symbol aux, *sym, *osym = np->sym;
-
- switch (newtp->op) {
- case PTR:
- case INT:
- case ENUM:
- switch (oldtp->op) {
- case PTR:
- case INT:
- case ENUM:
- if (newtp->sign == oldtp->sign)
- aux.u = osym->u;
- if (newtp->sign && !oldtp->sign)
- aux.u.i = osym->u.u;
- else if (!newtp->sign && oldtp->sign)
- aux.u.u = osym->u.u;
- break;
- case FLOAT:
- if (newtp->sign)
- aux.u.i = osym->u.f;
- else
- aux.u.u = osym->u.f;
- break;
- default:
- return NULL;
- }
- break;
- case FLOAT:
- aux.u.f = (oldtp->sign) ? osym->u.i : osym->u.u;
- break;
- default:
- return NULL;
- }
-
- sym = newsym(NS_IDEN);
- np->type = sym->type = newtp;
- np->sym = sym;
- sym->u = aux.u;
-
- return np;
-}
-
 /*
  * Convert a Node to a type
  */
diff --git a/cc1/fold.c b/cc1/fold.c
new file mode 100644
index 0000000..45b143b
--- /dev/null
+++ b/cc1/fold.c
_AT_@ -0,0 +1,333 @@
+
+#include <stdio.h>
+
+#include "../inc/cc.h"
+#include "cc1.h"
+
+
+#define SYMICMP(sym, val) (((sym)->type->sign) ? \
+ (sym)->u.i == (val) : (sym)->u.u == (val))
+
+#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)))
+
+#define CMPISYM(sym, ls, rs, op) (((sym)->type->sign) ? \
+ ((ls)->u.i op (rs)->u.i) : ((ls)->u.u op (rs)->u.u))
+
+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)
+ 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;
+
+ /* TODO: Add overflow checkings */
+
+ if (isnodecmp(op)) {
+ /*
+ * Comparision nodes have integer type
+ * but the operands can have different
+ * type.
+ */
+ switch (BTYPE(lp)) {
+ case INT: goto cmp_integers;
+ case FLOAT: goto cmp_floats;
+ default: goto no_simplify;
+ }
+ }
+
+ switch (tp->op) {
+ case PTR:
+ case INT:
+ cmp_integers:
+ iszero = SYMICMP(rs, 0);
+ isone = SYMICMP(rs, 1);
+ switch (op) {
+ case OADD:
+ 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 (isone)
+ return lp;
+ if (iszero)
+ goto division_by_0;
+ if (noconst)
+ goto no_simplify;
+ FOLDINT(&aux, ls, rs, /);
+ break;
+ case OMOD:
+ 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) {
+ case OADD:
+ aux.u.f = ls->u.f + rs->u.f;
+ break;
+ case OSUB:
+ aux.u.f = ls->u.f - rs->u.f;
+ break;
+ case OMUL:
+ aux.u.f = ls->u.f * rs->u.f;
+ break;
+ case ODIV:
+ if (rs->u.f == 0.0)
+ goto division_by_0;
+ aux.u.f = ls->u.f / rs->u.f;
+ break;
+ case OLT:
+ aux.u.i = ls->u.f < rs->u.f;
+ break;
+ case OGT:
+ aux.u.i = ls->u.f > rs->u.f;
+ break;
+ case OGE:
+ aux.u.i = ls->u.f >= rs->u.f;
+ break;
+ case OLE:
+ aux.u.i = ls->u.f <= rs->u.f;
+ break;
+ case OEQ:
+ aux.u.i = ls->u.f == rs->u.f;
+ break;
+ case ONE:
+ aux.u.i = ls->u.f != rs->u.f;
+ break;
+ }
+ break;
+ default:
+ goto no_simplify;
+ }
+
+ sym = newsym(NS_IDEN);
+ sym->type = tp;
+ sym->u = aux.u;
+ return constnode(sym);
+
+division_by_0:
+ warn("division by 0");
+
+no_simplify:
+ return node(op, tp, lp, rp);
+}
+
+#define UFOLDINT(sym, ls, op) (((sym)->type->sign) ? \
+ ((sym)->u.i = (op (ls)->u.i)) : \
+ ((sym)->u.u = (op (ls)->u.u)))
+
+Node *
+usimplify(unsigned char op, Type *tp, Node *np)
+{
+ Symbol *sym, *ns, aux;
+
+ if (!np->constant)
+ goto no_simplify;
+ ns = np->sym;
+ aux.type = tp;
+
+ switch (tp->op) {
+ case INT:
+ switch (op) {
+ case ONEG:
+ UFOLDINT(&aux, ns, -);
+ break;
+ case OCPL:
+ UFOLDINT(&aux, ns, ~);
+ break;
+ default:
+ goto no_simplify;
+ }
+ break;
+ case FLOAT:
+ if (op != ONEG)
+ goto no_simplify;
+ aux.u.f = -ns->u.f;
+ break;
+ default:
+ goto no_simplify;
+ }
+
+ sym = newsym(NS_IDEN);
+ sym->type = tp;
+ sym->u = aux.u;
+ return constnode(sym);
+
+no_simplify:
+ return node(op, tp, np, NULL);
+}
+
+/* TODO: check validity of types */
+
+Node *
+constconv(Node *np, Type *newtp)
+{
+ Type *oldtp = np->type;
+ Symbol aux, *sym, *osym = np->sym;
+
+ switch (newtp->op) {
+ case PTR:
+ case INT:
+ case ENUM:
+ switch (oldtp->op) {
+ case PTR:
+ case INT:
+ case ENUM:
+ if (newtp->sign == oldtp->sign)
+ aux.u = osym->u;
+ if (newtp->sign && !oldtp->sign)
+ aux.u.i = osym->u.u;
+ else if (!newtp->sign && oldtp->sign)
+ aux.u.u = osym->u.u;
+ break;
+ case FLOAT:
+ if (newtp->sign)
+ aux.u.i = osym->u.f;
+ else
+ aux.u.u = osym->u.f;
+ break;
+ default:
+ return NULL;
+ }
+ break;
+ case FLOAT:
+ aux.u.f = (oldtp->sign) ? osym->u.i : osym->u.u;
+ break;
+ default:
+ return NULL;
+ }
+
+ sym = newsym(NS_IDEN);
+ np->type = sym->type = newtp;
+ np->sym = sym;
+ sym->u = aux.u;
+
+ return np;
+}
Received on Thu Aug 27 2015 - 18:17:48 CEST

This archive was generated by hypermail 2.3.0 : Thu Aug 27 2015 - 18:24:22 CEST