#include "c.h"
#include <float.h>
Include dependency graph for simp.c:

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 |
|
|
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(). |
|
|
Value: Definition at line 8 of file simp.c. Referenced by simplify(). |
|
|
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(). |
|
|
Value: Definition at line 5 of file simp.c. Referenced by simplify(). |
|
|
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(). |
|
|
Definition at line 50 of file simp.c. Referenced by simplify(). |
|
|
Definition at line 25 of file simp.c. Referenced by simplify(). |
|
|
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(). |
|
|
Definition at line 41 of file simp.c. Referenced by simplify(). |
|
|
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(). |
|
|
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(). |
|
|
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(). |
|
||||||||||||||||||||||||
|
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:

|
||||||||||||||||||||||||
|
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:

|
||||||||||||||||
|
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:

|
|
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:

|
||||||||||||||||||||||||
|
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:

|
||||||||||||||||||||||||
|
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:

|
||||||||||||
|
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:

|
|
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 }
|
|
||||||||||||||||||||||||
|
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:

|
||||||||||||||||||||||||
|
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:

|
||||||||||||||||||||
|
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);
|