root/branches/dmdfe-2.0/constfold.c

Revision 914, 36.6 kB (checked in by Gregor, 3 months ago)

MERGE: DMD 2.019

Line 
1 // Compiler implementation of the D programming language
2 // Copyright (c) 1999-2007 by Digital Mars
3 // All Rights Reserved
4 // written by Walter Bright
5 // http://www.digitalmars.com
6 // License for redistribution is by either the Artistic License
7 // in artistic.txt, or the GNU General Public License in gnu.txt.
8 // See the included readme.txt for details.
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <assert.h>
13 #include <math.h>
14
15 #if __DMC__
16 #include <complex.h>
17 #endif
18
19 #include "mem.h"
20 #include "root.h"
21
22 #include "mtype.h"
23 #include "expression.h"
24 #include "aggregate.h"
25 #include "declaration.h"
26
27 #ifdef IN_GCC
28 #include "d-gcc-real.h"
29
30 /* %% fix? */
31 extern "C" bool real_isnan (const real_t *);
32 #endif
33
34 static real_t zero; // work around DMC bug for now
35
36 #define LOG 0
37
38 Expression *expType(Type *type, Expression *e)
39 {
40     if (type != e->type)
41     {
42     e = e->copy();
43     e->type = type;
44     }
45     return e;
46 }
47
48 /* ================================== isConst() ============================== */
49
50 int Expression::isConst()
51 {
52     //printf("Expression::isConst(): %s\n", toChars());
53     return 0;
54 }
55
56 int IntegerExp::isConst()
57 {
58     return 1;
59 }
60
61 int RealExp::isConst()
62 {
63     return 1;
64 }
65
66 int ComplexExp::isConst()
67 {
68     return 1;
69 }
70
71 int SymOffExp::isConst()
72 {
73     return 2;
74 }
75
76 /* =============================== constFold() ============================== */
77
78 /* The constFold() functions were redundant with the optimize() ones,
79  * and so have been folded in with them.
80  */
81
82 /* ========================================================================== */
83
84 Expression *Neg(Type *type, Expression *e1)
85 {   Expression *e;
86     Loc loc = e1->loc;
87
88     if (e1->type->isreal())
89     {
90     e = new RealExp(loc, -e1->toReal(), type);
91     }
92     else if (e1->type->isimaginary())
93     {
94     e = new RealExp(loc, -e1->toImaginary(), type);
95     }
96     else if (e1->type->iscomplex())
97     {
98     e = new ComplexExp(loc, -e1->toComplex(), type);
99     }
100     else
101     e = new IntegerExp(loc, -e1->toInteger(), type);
102     return e;
103 }
104
105 Expression *Com(Type *type, Expression *e1)
106 {   Expression *e;
107     Loc loc = e1->loc;
108
109     e = new IntegerExp(loc, ~e1->toInteger(), type);
110     return e;
111 }
112
113 Expression *Not(Type *type, Expression *e1)
114 {   Expression *e;
115     Loc loc = e1->loc;
116
117     e = new IntegerExp(loc, e1->isBool(0), type);
118     return e;
119 }
120
121 Expression *Bool(Type *type, Expression *e1)
122 {   Expression *e;
123     Loc loc = e1->loc;
124
125     e = new IntegerExp(loc, e1->isBool(1), type);
126     return e;
127 }
128
129 Expression *Add(Type *type, Expression *e1, Expression *e2)
130 {   Expression *e;
131     Loc loc = e1->loc;
132
133 #if LOG
134     printf("Add(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
135 #endif
136     if (type->isreal())
137     {
138     e = new RealExp(loc, e1->toReal() + e2->toReal(), type);
139     }
140     else if (type->isimaginary())
141     {
142     e = new RealExp(loc, e1->toImaginary() + e2->toImaginary(), type);
143     }
144     else if (type->iscomplex())
145     {
146     // This rigamarole is necessary so that -0.0 doesn't get
147     // converted to +0.0 by doing an extraneous add with +0.0
148     complex_t c1;
149     real_t r1;
150     real_t i1;
151
152     complex_t c2;
153     real_t r2;
154     real_t i2;
155
156     complex_t v;
157     int x;
158
159     if (e1->type->isreal())
160     {   r1 = e1->toReal();
161         x = 0;
162     }
163     else if (e1->type->isimaginary())
164     {   i1 = e1->toImaginary();
165         x = 3;
166     }
167     else
168     {   c1 = e1->toComplex();
169         x = 6;
170     }
171
172     if (e2->type->isreal())
173     {   r2 = e2->toReal();
174     }
175     else if (e2->type->isimaginary())
176     {   i2 = e2->toImaginary();
177         x += 1;
178     }
179     else
180     {   c2 = e2->toComplex();
181         x += 2;
182     }
183
184     switch (x)
185     {
186 #if __DMC__
187         case 0+0:   v = (complex_t) (r1 + r2);  break;
188         case 0+1:   v = r1 + i2 * I;        break;
189         case 0+2:   v = r1 + c2;            break;
190         case 3+0:   v = i1 * I + r2;        break;
191         case 3+1:   v = (complex_t) ((i1 + i2) * I); break;
192         case 3+2:   v = i1 * I + c2;        break;
193         case 6+0:   v = c1 + r2;            break;
194         case 6+1:   v = c1 + i2 * I;        break;
195         case 6+2:   v = c1 + c2;            break;
196 #else
197         case 0+0:   v = complex_t(r1 + r2, 0);  break;
198         case 0+1:   v = complex_t(r1, i2);      break;
199         case 0+2:   v = complex_t(r1 + creall(c2), cimagl(c2)); break;
200         case 3+0:   v = complex_t(r2, i1);      break;
201         case 3+1:   v = complex_t(0, i1 + i2);  break;
202         case 3+2:   v = complex_t(creall(c2), i1 + cimagl(c2)); break;
203         case 6+0:   v = complex_t(creall(c1) + r2, cimagl(c2)); break;
204         case 6+1:   v = complex_t(creall(c1), cimagl(c1) + i2); break;
205         case 6+2:   v = c1 + c2;            break;
206 #endif
207         default: assert(0);
208     }
209     e = new ComplexExp(loc, v, type);
210     }
211     else if (e1->op == TOKsymoff)
212     {
213     SymOffExp *soe = (SymOffExp *)e1;
214     e = new SymOffExp(loc, soe->var, soe->offset + e2->toInteger());
215     e->type = type;
216     }
217     else if (e2->op == TOKsymoff)
218     {
219     SymOffExp *soe = (SymOffExp *)e2;
220     e = new SymOffExp(loc, soe->var, soe->offset + e1->toInteger());
221     e->type = type;
222     }
223     else
224     e = new IntegerExp(loc, e1->toInteger() + e2->toInteger(), type);
225     return e;
226 }
227
228
229 Expression *Min(Type *type, Expression *e1, Expression *e2)
230 {   Expression *e;
231     Loc loc = e1->loc;
232
233     if (type->isreal())
234     {
235     e = new RealExp(loc, e1->toReal() - e2->toReal(), type);
236     }
237     else if (type->isimaginary())
238     {
239     e = new RealExp(loc, e1->toImaginary() - e2->toImaginary(), type);
240     }
241     else if (type->iscomplex())
242     {
243     // This rigamarole is necessary so that -0.0 doesn't get
244     // converted to +0.0 by doing an extraneous add with +0.0
245     complex_t c1;
246     real_t r1;
247     real_t i1;
248
249     complex_t c2;
250     real_t r2;
251     real_t i2;
252
253     complex_t v;
254     int x;
255
256     if (e1->type->isreal())
257     {   r1 = e1->toReal();
258         x = 0;
259     }
260     else if (e1->type->isimaginary())
261     {   i1 = e1->toImaginary();
262         x = 3;
263     }
264     else
265     {   c1 = e1->toComplex();
266         x = 6;
267     }
268
269     if (e2->type->isreal())
270     {   r2 = e2->toReal();
271     }
272     else if (e2->type->isimaginary())
273     {   i2 = e2->toImaginary();
274         x += 1;
275     }
276     else
277     {   c2 = e2->toComplex();
278         x += 2;
279     }
280
281     switch (x)
282     {
283 #if __DMC__
284         case 0+0:   v = (complex_t) (r1 - r2);  break;
285         case 0+1:   v = r1 - i2 * I;        break;
286         case 0+2:   v = r1 - c2;            break;
287         case 3+0:   v = i1 * I - r2;        break;
288         case 3+1:   v = (complex_t) ((i1 - i2) * I); break;
289         case 3+2:   v = i1 * I - c2;        break;
290         case 6+0:   v = c1 - r2;            break;
291         case 6+1:   v = c1 - i2 * I;        break;
292         case 6+2:   v = c1 - c2;            break;
293 #else
294         case 0+0:   v = complex_t(r1 - r2, 0);  break;
295         case 0+1:   v = complex_t(r1, -i2);     break;
296         case 0+2:   v = complex_t(r1 - creall(c2), -cimagl(c2));    break;
297         case 3+0:   v = complex_t(-r2, i1);     break;
298         case 3+1:   v = complex_t(0, i1 - i2);  break;
299         case 3+2:   v = complex_t(-creall(c2), i1 - cimagl(c2));    break;
300         case 6+0:   v = complex_t(creall(c1) - r2, cimagl(c1)); break;
301         case 6+1:   v = complex_t(creall(c1), cimagl(c1) - i2); break;
302         case 6+2:   v = c1 - c2;            break;
303 #endif
304         default: assert(0);
305     }
306     e = new ComplexExp(loc, v, type);
307     }
308     else if (e1->op == TOKsymoff)
309     {
310     SymOffExp *soe = (SymOffExp *)e1;
311     e = new SymOffExp(loc, soe->var, soe->offset - e2->toInteger());
312     e->type = type;
313     }
314     else
315     {
316     e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type);
317     }
318     return e;
319 }
320
321 Expression *Mul(Type *type, Expression *e1, Expression *e2)
322 {   Expression *e;
323     Loc loc = e1->loc;
324
325     if (type->isfloating())
326     {   complex_t c;
327 #ifdef IN_GCC
328     real_t r;
329 #else
330     d_float80 r;
331 #endif
332
333     if (e1->type->isreal())
334     {
335 #if __DMC__
336         c = e1->toReal() * e2->toComplex();
337 #else
338         r = e1->toReal();
339         c = e2->toComplex();
340         c = complex_t(r * creall(c), r * cimagl(c));
341 #endif
342     }
343     else if (e1->type->isimaginary())
344     {
345 #if __DMC__
346         c = e1->toImaginary() * I * e2->toComplex();
347 #else
348         r = e1->toImaginary();
349         c = e2->toComplex();
350         c = complex_t(-r * cimagl(c), r * creall(c));
351 #endif
352     }
353     else if (e2->type->isreal())
354     {
355 #if __DMC__
356         c = e2->toReal() * e1->toComplex();
357 #else
358         r = e2->toReal();
359         c = e1->toComplex();
360         c = complex_t(r * creall(c), r * cimagl(c));
361 #endif
362     }
363     else if (e2->type->isimaginary())
364     {
365 #if __DMC__
366         c = e1->toComplex() * e2->toImaginary() * I;
367 #else
368         r = e2->toImaginary();
369         c = e1->toComplex();
370         c = complex_t(-r * cimagl(c), r * creall(c));
371 #endif
372     }
373     else
374         c = e1->toComplex() * e2->toComplex();
375
376     if (type->isreal())
377         e = new RealExp(loc, creall(c), type);
378     else if (type->isimaginary())
379         e = new RealExp(loc, cimagl(c), type);
380     else if (type->iscomplex())
381         e = new ComplexExp(loc, c, type);
382     else
383         assert(0);
384     }
385     else
386     {
387     e = new IntegerExp(loc, e1->toInteger() * e2->toInteger(), type);
388     }
389     return e;
390 }
391
392 Expression *Div(Type *type, Expression *e1, Expression *e2)
393 {   Expression *e;
394     Loc loc = e1->loc;
395
396     if (type->isfloating())
397     {   complex_t c;
398 #ifdef IN_GCC
399     real_t r;
400 #else
401     d_float80 r;
402 #endif
403
404     //e1->type->print();
405     //e2->type->print();
406     if (e2->type->isreal())
407     {
408         if (e1->type->isreal())
409         {
410         e = new RealExp(loc, e1->toReal() / e2->toReal(), type);
411         return e;
412         }
413 #if __DMC__
414         //r = e2->toReal();
415         //c = e1->toComplex();
416         //printf("(%Lg + %Lgi) / %Lg\n", creall(c), cimagl(c), r);
417
418         c = e1->toComplex() / e2->toReal();
419 #else
420         r = e2->toReal();
421         c = e1->toComplex();
422         c = complex_t(creall(c) / r, cimagl(c) / r);
423 #endif
424     }
425     else if (e2->type->isimaginary())
426     {
427 #if __DMC__
428         //r = e2->toImaginary();
429         //c = e1->toComplex();
430         //printf("(%Lg + %Lgi) / %Lgi\n", creall(c), cimagl(c), r);
431
432         c = e1->toComplex() / (e2->toImaginary() * I);
433 #else
434         r = e2->toImaginary();
435         c = e1->toComplex();
436         c = complex_t(cimagl(c) / r, -creall(c) / r);
437 #endif
438     }
439     else
440     {
441         c = e1->toComplex() / e2->toComplex();
442     }
443
444     if (type->isreal())
445         e = new RealExp(loc, creall(c), type);
446     else if (type->isimaginary())
447         e = new RealExp(loc, cimagl(c), type);
448     else if (type->iscomplex())
449         e = new ComplexExp(loc, c, type);
450     else
451         assert(0);
452     }
453     else
454     {   sinteger_t n1;
455     sinteger_t n2;
456     sinteger_t n;
457
458     n1 = e1->toInteger();
459     n2 = e2->toInteger();
460     if (n2 == 0)
461     {   e2->error("divide by 0");
462         e2 = new IntegerExp(loc, 1, e2->type);
463         n2 = 1;
464     }
465     if (e1->type->isunsigned() || e2->type->isunsigned())
466         n = ((d_uns64) n1) / ((d_uns64) n2);
467     else
468         n = n1 / n2;
469     e = new IntegerExp(loc, n, type);
470     }
471     return e;
472 }
473
474 Expression *Mod(Type *type, Expression *e1, Expression *e2)
475 {   Expression *e;
476     Loc loc = e1->loc;
477
478     if (type->isfloating())
479     {
480     complex_t c;
481
482     if (e2->type->isreal())
483     {   real_t r2 = e2->toReal();
484
485 #ifdef __DMC__
486         c = fmodl(e1->toReal(), r2) + fmodl(e1->toImaginary(), r2) * I;
487 #elif defined(IN_GCC)
488         c = complex_t(e1->toReal() % r2, e1->toImaginary() % r2);
489 #else
490         c = complex_t(fmodl(e1->toReal(), r2), fmodl(e1->toImaginary(), r2));
491 #endif
492     }
493     else if (e2->type->isimaginary())
494     {   real_t i2 = e2->toImaginary();
495
496 #ifdef __DMC__
497         c = fmodl(e1->toReal(), i2) + fmodl(e1->toImaginary(), i2) * I;
498 #elif defined(IN_GCC)
499         c = complex_t(e1->toReal() % i2, e1->toImaginary() % i2);
500 #else
501         c = complex_t(fmodl(e1->toReal(), i2), fmodl(e1->toImaginary(), i2));
502 #endif
503     }
504     else
505         assert(0);
506
507     if (type->isreal())
508         e = new RealExp(loc, creall(c), type);
509     else if (type->isimaginary())
510         e = new RealExp(loc, cimagl(c), type);
511     else if (type->iscomplex())
512         e = new ComplexExp(loc, c, type);
513     else
514         assert(0);
515     }
516     else
517     {   sinteger_t n1;
518     sinteger_t n2;
519     sinteger_t n;
520
521     n1 = e1->toInteger();
522     n2 = e2->toInteger();
523     if (n2 == 0)
524     {   e2->error("divide by 0");
525         e2 = new IntegerExp(loc, 1, e2->type);
526         n2 = 1;
527     }
528     if (e1->type->isunsigned() || e2->type->isunsigned())
529         n = ((d_uns64) n1) % ((d_uns64) n2);
530     else
531         n = n1 % n2;
532     e = new IntegerExp(loc, n, type);
533     }
534     return e;
535 }
536
537 Expression *Shl(Type *type, Expression *e1, Expression *e2)
538 {   Expression *e;
539     Loc loc = e1->loc;
540
541     e = new IntegerExp(loc, e1->toInteger() << e2->toInteger(), type);
542     return e;
543 }
544
545 Expression *Shr(Type *type, Expression *e1, Expression *e2)
546 {   Expression *e;
547     Loc loc = e1->loc;
548     unsigned count;
549     integer_t value;
550
551     value = e1->toInteger();
552     count = e2->toInteger();
553     switch (e1->type->toBasetype()->ty)
554     {
555     case Tint8:
556         value = (d_int8)(value) >> count;
557         break;
558
559     case Tuns8:
560         value = (d_uns8)(value) >> count;
561         break;
562
563     case Tint16:
564         value = (d_int16)(value) >> count;
565         break;
566
567     case Tuns16:
568         value = (d_uns16)(value) >> count;
569         break;
570
571     case Tint32:
572         value = (d_int32)(value) >> count;
573         break;
574
575     case Tuns32:
576         value = (d_uns32)(value) >> count;
577         break;
578
579     case Tint64:
580         value = (d_int64)(value) >> count;
581         break;<