Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

simp.c File Reference

#include "c.h"
#include <float.h>

Include dependency graph for simp.c:

Include dependency graph

Go to the source code of this file.

Defines

#define cfoldcnst(TYPE, VAR, OP)
#define commute(L, R)
#define foldaddp(L, R, RTYPE, VAR)
#define foldcnst(TYPE, VAR, OP)
#define geu(L, R, V)
#define idempotent(OP)   if (l->op == OP) return l->kids[0]
#define identity(X, Y, TYPE, VAR, VAL)   if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
#define sfoldcnst(OP)
#define ufoldcnst(TYPE, EXP)   if (l->op == CNST+TYPE) return EXP
#define xcvtcnst(FTYPE, SRC, DST, VAR, EXPR)
#define xfoldcnst(TYPE, VAR, OP, FUNC)
#define zerofield(OP, TYPE, VAR)

Functions

int addd (double x, double y, double min, double max, int needconst)
int addi (long x, long y, long min, long max, int needconst)
Tree addrtree (Tree e, long n, Type ty)
Tree constexpr (int tok)
int divd (double x, double y, double min, double max, int needconst)
int divi (long x, long y, long min, long max, int needconst)
int intexpr (int tok, int n)
int ispow2 (unsigned long u)
int muld (double x, double y, double min, double max, int needconst)
int muli (long x, long y, long min, long max, int needconst)
Tree simplify (int op, Type ty, Tree l, Tree r)
int subd (double x, double y, double min, double max, int needconst)
int subi (long x, long y, long min, long max, int needconst)

Variables

int explicitCast
int needconst


Define Documentation

#define cfoldcnst TYPE,
VAR,
OP   ) 
 

Value:

if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
        return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR))

Definition at line 33 of file simp.c.

Referenced by simplify().

#define commute L,
R   ) 
 

Value:

if (generic(R->op) == CNST && generic(L->op) != CNST) \
        do { Tree t = L; L = R; R = t; } while(0)

Definition at line 8 of file simp.c.

Referenced by simplify().

#define foldaddp L,
R,
RTYPE,
VAR   ) 
 

Value:

if (L->op == CNST+P && R->op == CNST+RTYPE) { \
        Tree e = tree(CNST+P, ty, NULL, NULL);\
        e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\
        return e; }

Definition at line 36 of file simp.c.

Referenced by simplify().

#define foldcnst TYPE,
VAR,
OP   ) 
 

Value:

if (l->op == CNST+TYPE && r->op == CNST+TYPE) \
        return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)

Definition at line 5 of file simp.c.

Referenced by simplify().

#define geu L,
R,
 ) 
 

Value:

if (R->op == CNST+U && R->u.v.u == 0) do { \
        warning("result of unsigned comparison is constant\n"); \
        return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0)

Definition at line 46 of file simp.c.

Referenced by simplify().

#define idempotent OP   )     if (l->op == OP) return l->kids[0]
 

Definition at line 50 of file simp.c.

Referenced by simplify().

#define identity X,
Y,
TYPE,
VAR,
VAL   )     if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y
 

Definition at line 25 of file simp.c.

Referenced by simplify().

#define sfoldcnst OP   ) 
 

Value:

if (l->op == CNST+U && r->op == CNST+I \
    && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \
        return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i))

Definition at line 42 of file simp.c.

Referenced by simplify().

#define ufoldcnst TYPE,
EXP   )     if (l->op == CNST+TYPE) return EXP
 

Definition at line 41 of file simp.c.

Referenced by simplify().

#define xcvtcnst FTYPE,
SRC,
DST,
VAR,
EXPR   ) 
 

Value:

if (l->op == CNST+FTYPE) do {\
        if (!explicitCast\
        &&  ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
            warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\
        if (needconst\
        || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\
            return cnsttree(ty, (EXPR)); } while(0)

Definition at line 17 of file simp.c.

Referenced by simplify().

#define xfoldcnst TYPE,
VAR,
OP,
FUNC   ) 
 

Value:

if (l->op == CNST+TYPE && r->op == CNST+TYPE\
    && FUNC(l->u.v.VAR,r->u.v.VAR,\
        ty->u.sym->u.limits.min.VAR,\
        ty->u.sym->u.limits.max.VAR, needconst)) \
        return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR)

Definition at line 11 of file simp.c.

Referenced by simplify().

#define zerofield OP,
TYPE,
VAR   ) 
 

Value:

if (l->op == FIELD \
    &&  r->op == CNST+TYPE && r->u.v.VAR == 0)\
        return eqtree(OP, bittree(BAND, l->kids[0],\
            cnsttree(unsignedtype, \
                (unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r)

Definition at line 27 of file simp.c.

Referenced by simplify().


Function Documentation

int addd double  x,
double  y,
double  min,
double  max,
int  needconst
[static]
 

Definition at line 69 of file simp.c.

References cond(), max, min, warning(), x, and y.

Referenced by simplify(), and subd().

00069                                                                            {
00070     int cond = x == 0 || y == 0
00071     || x < 0 && y < 0 && x >= min - y
00072     || x < 0 && y > 0
00073     || x > 0 && y < 0
00074     || x > 0 && y > 0 && x <= max - y;
00075     if (!cond && needconst) {
00076         warning("overflow in constant expression\n");
00077         cond = 1;
00078     }
00079     return cond;
00080 
00081 
00082 }

Here is the call graph for this function:

int addi long  x,
long  y,
long  min,
long  max,
int  needconst
[static]
 

Definition at line 54 of file simp.c.

References cond(), max, min, warning(), x, and y.

Referenced by simplify(), and subi().

00054                                                                    {
00055     int cond = x == 0 || y == 0
00056     || x < 0 && y < 0 && x >= min - y
00057     || x < 0 && y > 0
00058     || x > 0 && y < 0
00059     || x > 0 && y > 0 && x <= max - y;
00060     if (!cond && needconst) {
00061         warning("overflow in constant expression\n");
00062         cond = 1;
00063     }
00064     return cond;
00065 
00066 
00067 }

Here is the call graph for this function:

Tree addrtree Tree  e,
long  n,
Type  ty
[static]
 

Definition at line 84 of file simp.c.

References addlocal(), code::addr, interface::address, symbol::addressed, assert, code::base, code(), Code, symbol::computed, cp, symbol::defined, e, FUNC, symbol::generated, genlabel(), GLOBAL, IR, isarray, isptr, symbol::name, NEW0, NULL, code::offset, tree::op, p, PERM, q, symbol::ref, symbol::sclass, symbol::scope, stringd(), code::sym, tree::sym, Symbol, symbol::temporary, tree(), Tree, type::type, symbol::type, Type, code::u, and tree::u.

Referenced by simplify().

00084                                               {
00085     Symbol p = e->u.sym, q;
00086 
00087     if (p->scope  == GLOBAL
00088     ||  p->sclass == STATIC || p->sclass == EXTERN)
00089         NEW0(q, PERM);
00090     else
00091         NEW0(q, FUNC);
00092     q->name = stringd(genlabel(1));
00093     q->sclass = p->sclass;
00094     q->scope = p->scope;
00095     assert(isptr(ty) || isarray(ty));
00096     q->type = isptr(ty) ? ty->type : ty;
00097     q->temporary = p->temporary;
00098     q->generated = p->generated;
00099     q->addressed = p->addressed;
00100     q->computed = 1;
00101     q->defined = 1;
00102     q->ref = 1;
00103     if (p->scope  == GLOBAL
00104     ||  p->sclass == STATIC || p->sclass == EXTERN) {
00105         if (p->sclass == AUTO)
00106             q->sclass = STATIC;
00107         (*IR->address)(q, p, n);
00108     } else {
00109         Code cp;
00110         addlocal(p);
00111         cp = code(Address);
00112         cp->u.addr.sym = q;
00113         cp->u.addr.base = p;
00114         cp->u.addr.offset = n;
00115     }
00116     e = tree(e->op, ty, NULL, NULL);
00117     e->u.sym = q;
00118     return e;
00119 }

Here is the call graph for this function:

Tree constexpr int  tok  ) 
 

Definition at line 185 of file simp.c.

References expr1(), needconst, p, and Tree.

Referenced by intexpr(), and statement().

00185                         {
00186     Tree p;
00187 
00188     needconst++;
00189     p = expr1(tok);
00190     needconst--;
00191     return p;
00192 }

Here is the call graph for this function:

int divd double  x,
double  y,
double  min,
double  max,
int  needconst
[static]
 

Definition at line 133 of file simp.c.

References cond(), max, warning(), x, and y.

Referenced by simplify().

00133                                                                            {
00134     int cond;
00135 
00136     if (x < 0) x = -x;
00137     if (y < 0) y = -y;
00138     cond = y != 0 && !(y < 1 && x > max*y);
00139     if (!cond && needconst) {
00140         warning("overflow in constant expression\n");
00141         cond = 1;
00142     }
00143     return cond;
00144 
00145 }

Here is the call graph for this function:

int divi long  x,
long  y,
long  min,
long  max,
int  needconst
[static]
 

Definition at line 122 of file simp.c.

References cond(), min, warning(), x, and y.

Referenced by simplify().

00122                                                                    {
00123     int cond = y != 0 && !(x == min && y == -1);
00124     if (!cond && needconst) {
00125         warning("overflow in constant expression\n");
00126         cond = 1;
00127     }
00128     return cond;
00129 
00130 
00131 }

Here is the call graph for this function:

int intexpr int  tok,
int  n
 

Definition at line 194 of file simp.c.

References cast(), CNST, constexpr(), error(), value::i, I, inttype, n, needconst, tree::op, p, Tree, tree::u, and tree::v.

Referenced by dclr1(), and enumdcl().

00194                             {
00195     Tree p = constexpr(tok);
00196 
00197     needconst++;
00198     if (p->op == CNST+I || p->op == CNST+U)
00199         n = cast(p, inttype)->u.v.i;
00200     else
00201         error("integer expression must be constant\n");
00202     needconst--;
00203     return n;
00204 }

Here is the call graph for this function:

int ispow2 unsigned long  u  ) 
 

Definition at line 578 of file simp.c.

References n.

Referenced by simplify().

00578                             {
00579     int n;
00580 
00581     if (u > 1 && (u&(u-1)) == 0)
00582         for (n = 0; u; u >>= 1, n++)
00583             if (u&1)
00584                 return n;
00585     return 0;
00586 }

int muld double  x,
double  y,
double  min,
double  max,
int  needconst
[static]
 

Definition at line 163 of file simp.c.

References cond(), max, min, warning(), x, and y.

Referenced by simplify().

00163                                                                            {
00164     int cond = x >= -1 && x <= 1 || y >= -1 && y <= 1
00165     || x < 0 && y < 0 && -x <= max/-y
00166     || x < 0 && y > 0 &&  x >= min/y
00167     || x > 0 && y < 0 &&  y >= min/x
00168     || x > 0 && y > 0 &&  x <= max/y;
00169     if (!cond && needconst) {
00170         warning("overflow in constant expression\n");
00171         cond = 1;
00172     }
00173     return cond;
00174 
00175 
00176 }

Here is the call graph for this function:

int muli long  x,
long  y,
long  min,
long  max,
int  needconst
[static]
 

Definition at line 148 of file simp.c.

References cond(), max, min, warning(), x, and y.

Referenced by simplify().

00148                                                                    {
00149     int cond = x > -1 && x <= 1 || y > -1 && y <= 1
00150     || x < 0 && y < 0 && -x <= max/-y
00151     || x < 0 && y > 0 &&  x >= min/y
00152     || x > 0 && y < 0 &&  y >= min/x
00153     || x > 0 && y > 0 &&  x <= max/y;
00154     if (!cond && needconst) {
00155         warning("overflow in constant expression\n");
00156         cond = 1;
00157     }
00158     return cond;
00159 
00160 
00161 }

Here is the call graph for this function:

Tree simplify int  op,
Type  ty,
Tree  l,
Tree  r
 

Definition at line 205 of file simp.c.

References ADD, addd(), addi(), addrtree(), AND, assert, BAND, BCOM, bittree(), BOR, BXOR, cast(), cfoldcnst, CNST, cnsttree(), commute, cond(), CVF, CVI, CVP, CVU, value::d, d, DIV, divd(), divi(), EQ, eqtree(), explicitCast, extend, F, foldaddp, foldcnst, GE, generic, geu, GT, value::i, i, I, idempotent, identity, inttype, isaddrop, ispow2(), tree::kids, L, l, LE, symbol::limits, longtype, LSH, LT, symbol::max, symbol::min, mkop, MOD, MUL, muld(), muli(), n, NE, needconst, NEG, NOT, NULL, ones, type::op, tree::op, op, optype, OR, p, value::p, P, r, retype(), RIGHT, root(), RSH, sfoldcnst, simplify(), type::size, SUB, subd(), subi(), type::sym, tree(), Tree, tree::type, Type, symbol::u, type::u, value::u, tree::u, U, ufoldcnst, tree::v, warning(), xcvtcnst, xfoldcnst, and zerofield.

Referenced by calltree(), condtree(), cvtconst(), foldcond(), and simplify().

00205                                                {
00206     int n;
00207     Tree p;
00208 
00209     if (optype(op) == 0)
00210         op = mkop(op, ty);
00211     switch (op) {
00212         case ADD+U:
00213             foldcnst(U,u,+);
00214             commute(r,l);
00215             identity(r,l,U,u,0);
00216             break;
00217         case ADD+I:
00218             xfoldcnst(I,i,+,addi);
00219             commute(r,l);
00220             identity(r,l,I,i,0);
00221             break;
00222         case CVI+I:
00223             xcvtcnst(I,l->u.v.i,ty,i,(long)extend(l->u.v.i,ty));
00224             break;
00225         case CVU+I:
00226             if (l->op == CNST+U) {
00227                 if (!explicitCast && l->u.v.u > ty->u.sym->u.limits.max.i)
00228                     warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, ty);
00229                 if (needconst || !(l->u.v.u > ty->u.sym->u.limits.max.i))
00230                     return cnsttree(ty, (long)extend(l->u.v.u,ty));
00231             }
00232             break;
00233         case CVP+U:
00234             xcvtcnst(P,(unsigned long)l->u.v.p,ty,u,(unsigned long)l->u.v.p);
00235             break;
00236         case CVU+P:
00237             xcvtcnst(U,(void*)l->u.v.u,ty,p,(void*)l->u.v.u);
00238             break;
00239         case CVP+P:
00240             xcvtcnst(P,l->u.v.p,ty,p,l->u.v.p);
00241             break;
00242         case CVI+U:
00243             xcvtcnst(I,l->u.v.i,ty,u,((unsigned long)l->u.v.i)&ones(8*ty->size));
00244             break;
00245         case CVU+U:
00246             xcvtcnst(U,l->u.v.u,ty,u,l->u.v.u&ones(8*ty->size));
00247             break;
00248 
00249         case CVI+F:
00250             xcvtcnst(I,l->u.v.i,ty,d,(long double)l->u.v.i);
00251         case CVU+F:
00252             xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u);
00253             break;
00254         case CVF+I:
00255             xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d);
00256             break;
00257         case CVF+F: {
00258             float d;
00259             if (l->op == CNST+F)
00260                 if (l->u.v.d < ty->u.sym->u.limits.min.d)
00261                     d = ty->u.sym->u.limits.min.d;
00262                 else if (l->u.v.d > ty->u.sym->u.limits.max.d)
00263                     d = ty->u.sym->u.limits.max.d;
00264                 else
00265                     d = l->u.v.d;
00266             xcvtcnst(F,l->u.v.d,ty,d,(long double)d);
00267             break;
00268             }
00269         case BAND+U:
00270             foldcnst(U,u,&);
00271             commute(r,l);
00272             identity(r,l,U,u,ones(8*ty->size));
00273             if (r->op == CNST+U && r->u.v.u == 0)
00274                 return tree(RIGHT, ty, root(l), cnsttree(ty, 0UL));
00275             break;
00276         case BAND+I:
00277             foldcnst(I,i,&);
00278             commute(r,l);
00279             identity(r,l,I,i,ones(8*ty->size));
00280             if (r->op == CNST+I && r->u.v.u == 0)
00281                 return tree(RIGHT, ty, root(l), cnsttree(ty, 0L));
00282             break;
00283 
00284         case MUL+U:
00285             commute(l,r);
00286             if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0)
00287                 return simplify(LSH, ty, r, cnsttree(inttype, (long)n));
00288             foldcnst(U,u,*);
00289             identity(r,l,U,u,1);
00290             break;
00291         case NE+I:
00292             cfoldcnst(I,i,!=);
00293             commute(r,l);
00294             zerofield(NE,I,i);
00295             break;
00296 
00297         case EQ+I:
00298             cfoldcnst(I,i,==);
00299             commute(r,l);
00300             zerofield(EQ,I,i);
00301             break;
00302         case ADD+P:
00303             foldaddp(l,r,I,i);
00304             foldaddp(l,r,U,u);
00305             foldaddp(r,l,I,i);
00306             foldaddp(r,l,U,u);
00307             commute(r,l);
00308             identity(r,retype(l,ty),I,i,0);
00309             identity(r,retype(l,ty),U,u,0);
00310             if (isaddrop(l->op)
00311             && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
00312                 && r->u.v.i >= longtype->u.sym->u.limits.min.i
00313             || r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
00314                 return addrtree(l, cast(r, longtype)->u.v.i, ty);
00315             if (l->op == ADD+P && isaddrop(l->kids[1]->op)
00316             && (r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i
00317                 && r->u.v.i >= longtype->u.sym->u.limits.min.i
00318             ||  r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))
00319                 return simplify(ADD+P, ty, l->kids[0],
00320                     addrtree(l->kids[1], cast(r, longtype)->u.v.i, ty));
00321             if ((l->op == ADD+I || l->op == SUB+I)
00322             && l->kids[1]->op == CNST+I && isaddrop(r->op))
00323                 return simplify(ADD+P, ty, l->kids[0],
00324                     simplify(generic(l->op)+P, ty, r, l->kids[1]));
00325             if (l->op == ADD+P && generic(l->kids[1]->op) == CNST
00326             && generic(r->op) == CNST)
00327                 return simplify(ADD+P, ty, l->kids[0],
00328                     simplify(ADD, l->kids[1]->type, l->kids[1], r));
00329             if (l->op == ADD+I && generic(l->kids[1]->op) == CNST
00330             &&  r->op == ADD+P && generic(r->kids[1]->op) == CNST)
00331                 return simplify(ADD+P, ty, l->kids[0],
00332                     simplify(ADD+P, ty, r->kids[0],
00333                     simplify(ADD, r->kids[1]->type, l->kids[1], r->kids[1])));
00334             if (l->op == RIGHT && l->kids[1])
00335                 return tree(RIGHT, ty, l->kids[0],
00336                     simplify(ADD+P, ty, l->kids[1], r));
00337             else if (l->op == RIGHT && l->kids[0])
00338                 return tree(RIGHT, ty,
00339                     simplify(ADD+P, ty, l->kids[0], r), NULL);
00340             break;
00341 
00342         case ADD+F:
00343             xfoldcnst(F,d,+,addd);
00344             commute(r,l);
00345             break;
00346         case AND+I:
00347             op = AND;
00348             ufoldcnst(I,l->u.v.i ? cond(r) : l);    /* 0&&r => 0, 1&&r => r */
00349             break;
00350         case OR+I:
00351             op = OR;
00352             /* 0||r => r, 1||r => 1 */
00353             ufoldcnst(I,l->u.v.i ? cnsttree(ty, 1L) : cond(r));
00354             break;
00355         case BCOM+I:
00356             ufoldcnst(I,cnsttree(ty, (long)extend((~l->u.v.i)&ones(8*ty->size), ty)));
00357             idempotent(BCOM+U);
00358             break;
00359         case BCOM+U:
00360             ufoldcnst(U,cnsttree(ty, (unsigned long)((~l->u.v.u)&ones(8*ty->size))));
00361             idempotent(BCOM+U);
00362             break;
00363         case BOR+U:
00364             foldcnst(U,u,|);
00365             commute(r,l);
00366             identity(r,l,U,u,0);
00367             break;
00368         case BOR+I:
00369             foldcnst(I,i,|);
00370             commute(r,l);
00371             identity(r,l,I,i,0);
00372             break;
00373         case BXOR+U:
00374             foldcnst(U,u,^);
00375             commute(r,l);
00376             identity(r,l,U,u,0);
00377             break;
00378         case BXOR+I:
00379             foldcnst(I,i,^);
00380             commute(r,l);
00381             identity(r,l,I,i,0);
00382             break;
00383         case DIV+F:
00384             xfoldcnst(F,d,/,divd);
00385             break;
00386         case DIV+I:
00387             identity(r,l,I,i,1);
00388             if (r->op == CNST+I && r->u.v.i == 0
00389             ||  l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i
00390             &&  r->op == CNST+I && r->u.v.i == -1)
00391                 break;
00392             xfoldcnst(I,i,/,divi);
00393             break;
00394         case DIV+U:     
00395             identity(r,l,U,u,1);
00396             if (r->op == CNST+U && r->u.v.u == 0)
00397                 break;
00398             if (r->op == CNST+U && (n = ispow2(r->u.v.u)) != 0)
00399                 return simplify(RSH, ty, l, cnsttree(inttype, (long)n));
00400             foldcnst(U,u,/);
00401             break;
00402         case EQ+F:
00403             cfoldcnst(F,d,==);
00404             commute(r,l);
00405             break;
00406         case EQ+U:
00407             cfoldcnst(U,u,==);
00408             commute(r,l);
00409             zerofield(EQ,U,u);