root/trunk/rebuild/constfold.c

Revision 915, 37.1 kB (checked in by Gregor, 3 months ago)

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