add missing returns
[libfirm] / ir / ir / iropt.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   iropt --- optimizations intertwined with IR construction.
23  * @author  Christian Schaefer, Goetz Lindenmaier, Michael Beck
24  * @version $Id$
25  */
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <string.h>
31
32 #include "irnode_t.h"
33 #include "irgraph_t.h"
34 #include "iredges_t.h"
35 #include "irmode_t.h"
36 #include "iropt_t.h"
37 #include "ircons_t.h"
38 #include "irgmod.h"
39 #include "irvrfy.h"
40 #include "tv_t.h"
41 #include "dbginfo_t.h"
42 #include "iropt_dbg.h"
43 #include "irflag_t.h"
44 #include "irhooks.h"
45 #include "irarch.h"
46 #include "hashptr.h"
47 #include "archop.h"
48 #include "opt_confirms.h"
49 #include "opt_polymorphy.h"
50 #include "irtools.h"
51 #include "xmalloc.h"
52
53 /* Make types visible to allow most efficient access */
54 #include "entity_t.h"
55
56 /**
57  * Return the value of a Constant.
58  */
59 static tarval *computed_value_Const(ir_node *n) {
60         return get_Const_tarval(n);
61 }  /* computed_value_Const */
62
63 /**
64  * Return the value of a 'sizeof', 'alignof' or 'offsetof' SymConst.
65  */
66 static tarval *computed_value_SymConst(ir_node *n) {
67         ir_type   *type;
68         ir_entity *ent;
69
70         switch (get_SymConst_kind(n)) {
71         case symconst_type_size:
72                 type = get_SymConst_type(n);
73                 if (get_type_state(type) == layout_fixed)
74                         return new_tarval_from_long(get_type_size_bytes(type), get_irn_mode(n));
75                 break;
76         case symconst_type_align:
77                 type = get_SymConst_type(n);
78                 if (get_type_state(type) == layout_fixed)
79                         return new_tarval_from_long(get_type_alignment_bytes(type), get_irn_mode(n));
80                 break;
81         case symconst_ofs_ent:
82                 ent  = get_SymConst_entity(n);
83                 type = get_entity_owner(ent);
84                 if (get_type_state(type) == layout_fixed)
85                         return new_tarval_from_long(get_entity_offset(ent), get_irn_mode(n));
86                 break;
87         default:
88                 break;
89         }
90         return tarval_bad;
91 }  /* computed_value_SymConst */
92
93 /**
94  * Return the value of an Add.
95  */
96 static tarval *computed_value_Add(ir_node *n) {
97         ir_node *a = get_Add_left(n);
98         ir_node *b = get_Add_right(n);
99
100         tarval *ta = value_of(a);
101         tarval *tb = value_of(b);
102
103         if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b)))
104                 return tarval_add(ta, tb);
105
106         return tarval_bad;
107 }  /* computed_value_Add */
108
109 /**
110  * Return the value of a Sub.
111  * Special case: a - a
112  */
113 static tarval *computed_value_Sub(ir_node *n) {
114         ir_node *a = get_Sub_left(n);
115         ir_node *b = get_Sub_right(n);
116         tarval *ta;
117         tarval *tb;
118
119         /* a - a */
120         if (a == b && !is_Bad(a))
121                 return get_mode_null(get_irn_mode(n));
122
123         ta = value_of(a);
124         tb = value_of(b);
125
126         if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b)))
127                 return tarval_sub(ta, tb);
128
129         return tarval_bad;
130 }  /* computed_value_Sub */
131
132 /**
133  * Return the value of a Carry.
134  * Special : a op 0, 0 op b
135  */
136 static tarval *computed_value_Carry(ir_node *n) {
137         ir_node *a = get_binop_left(n);
138         ir_node *b = get_binop_right(n);
139         ir_mode *m = get_irn_mode(n);
140
141         tarval *ta = value_of(a);
142         tarval *tb = value_of(b);
143
144         if ((ta != tarval_bad) && (tb != tarval_bad)) {
145                 tarval_add(ta, tb);
146                 return tarval_carry() ? get_mode_one(m) : get_mode_null(m);
147         } else {
148                 if (tarval_is_null(ta) || tarval_is_null(tb))
149                         return get_mode_null(m);
150         }
151         return tarval_bad;
152 }  /* computed_value_Carry */
153
154 /**
155  * Return the value of a Borrow.
156  * Special : a op 0
157  */
158 static tarval *computed_value_Borrow(ir_node *n) {
159         ir_node *a = get_binop_left(n);
160         ir_node *b = get_binop_right(n);
161         ir_mode *m = get_irn_mode(n);
162
163         tarval *ta = value_of(a);
164         tarval *tb = value_of(b);
165
166         if ((ta != tarval_bad) && (tb != tarval_bad)) {
167                 return tarval_cmp(ta, tb) == pn_Cmp_Lt ? get_mode_one(m) : get_mode_null(m);
168         } else if (tarval_is_null(ta)) {
169                 return get_mode_null(m);
170         }
171         return tarval_bad;
172 }  /* computed_value_Borrow */
173
174 /**
175  * Return the value of an unary Minus.
176  */
177 static tarval *computed_value_Minus(ir_node *n) {
178         ir_node *a = get_Minus_op(n);
179         tarval *ta = value_of(a);
180
181         if (ta != tarval_bad)
182                 return tarval_neg(ta);
183
184         return tarval_bad;
185 }  /* computed_value_Minus */
186
187 /**
188  * Return the value of a Mul.
189  */
190 static tarval *computed_value_Mul(ir_node *n) {
191         ir_node *a = get_Mul_left(n);
192         ir_node *b = get_Mul_right(n);
193         ir_mode *mode;
194
195         tarval *ta = value_of(a);
196         tarval *tb = value_of(b);
197
198         mode = get_irn_mode(n);
199         if (mode != get_irn_mode(a)) {
200                 /* n * n = 2n bit multiplication */
201                 ta = tarval_convert_to(ta, mode);
202                 tb = tarval_convert_to(tb, mode);
203         }
204
205         if (ta != tarval_bad && tb != tarval_bad) {
206                 return tarval_mul(ta, tb);
207         } else {
208                 /* a*0 = 0 or 0*b = 0 */
209                 if (ta == get_mode_null(mode))
210                         return ta;
211                 if (tb == get_mode_null(mode))
212                         return tb;
213         }
214         return tarval_bad;
215 }  /* computed_value_Mul */
216
217 /**
218  * Return the value of a floating point Quot.
219  */
220 static tarval *computed_value_Quot(ir_node *n) {
221         ir_node *a = get_Quot_left(n);
222         ir_node *b = get_Quot_right(n);
223
224         tarval *ta = value_of(a);
225         tarval *tb = value_of(b);
226
227         /* This was missing in original implementation. Why? */
228         if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
229                 if (tb != get_mode_null(get_tarval_mode(tb)))   /* div by zero: return tarval_bad */
230                         return tarval_quo(ta, tb);
231         }
232         return tarval_bad;
233 }  /* computed_value_Quot */
234
235 /**
236  * Calculate the value of an integer Div of two nodes.
237  * Special case: 0 / b
238  */
239 static tarval *do_computed_value_Div(ir_node *a, ir_node *b) {
240         tarval *ta = value_of(a);
241         tarval *tb = value_of(b);
242
243         /* Compute c1 / c2 or 0 / a, a != 0 */
244         if (ta != tarval_bad) {
245                 if ((tb != tarval_bad) && (tb != get_mode_null(get_irn_mode(b))))   /* div by zero: return tarval_bad */
246                         return tarval_div(ta, tb);
247                 else if (ta == get_mode_null(get_tarval_mode(ta)))  /* 0 / b == 0 */
248                         return ta;
249         }
250         return tarval_bad;
251 }  /* do_computed_value_Div */
252
253 /**
254  * Return the value of an integer Div.
255  */
256 static tarval *computed_value_Div(ir_node *n) {
257         return do_computed_value_Div(get_Div_left(n), get_Div_right(n));
258 }  /* computed_value_Div */
259
260 /**
261  * Calculate the value of an integer Mod of two nodes.
262  * Special case: a % 1
263  */
264 static tarval *do_computed_value_Mod(ir_node *a, ir_node *b) {
265         tarval *ta = value_of(a);
266         tarval *tb = value_of(b);
267
268         /* Compute c1 % c2 or a % 1 */
269         if (tb != tarval_bad) {
270                 if ((ta != tarval_bad) && (tb != get_mode_null(get_tarval_mode(tb))))   /* div by zero: return tarval_bad */
271                         return tarval_mod(ta, tb);
272                 else if (tb == get_mode_one(get_tarval_mode(tb)))    /* x mod 1 == 0 */
273                         return get_mode_null(get_irn_mode(a));
274         }
275         return tarval_bad;
276 }  /* do_computed_value_Mod */
277
278 /**
279  * Return the value of an integer Mod.
280  */
281 static tarval *computed_value_Mod(ir_node *n) {
282         return do_computed_value_Mod(get_Mod_left(n), get_Mod_right(n));
283 }  /* computed_value_Mod */
284
285 /**
286  * Return the value of an Abs.
287  */
288 static tarval *computed_value_Abs(ir_node *n) {
289         ir_node *a = get_Abs_op(n);
290         tarval *ta = value_of(a);
291
292         if (ta != tarval_bad)
293                 return tarval_abs(ta);
294
295         return tarval_bad;
296 }  /* computed_value_Abs */
297
298 /**
299  * Return the value of an And.
300  * Special case: a & 0, 0 & b
301  */
302 static tarval *computed_value_And(ir_node *n) {
303         ir_node *a = get_And_left(n);
304         ir_node *b = get_And_right(n);
305
306         tarval *ta = value_of(a);
307         tarval *tb = value_of(b);
308
309         if ((ta != tarval_bad) && (tb != tarval_bad)) {
310                 return tarval_and (ta, tb);
311         } else {
312                 if (tarval_is_null(ta)) return ta;
313                 if (tarval_is_null(tb)) return tb;
314         }
315         return tarval_bad;
316 }  /* computed_value_And */
317
318 /**
319  * Return the value of an Or.
320  * Special case: a | 1...1, 1...1 | b
321  */
322 static tarval *computed_value_Or(ir_node *n) {
323         ir_node *a = get_Or_left(n);
324         ir_node *b = get_Or_right(n);
325
326         tarval *ta = value_of(a);
327         tarval *tb = value_of(b);
328
329         if ((ta != tarval_bad) && (tb != tarval_bad)) {
330                 return tarval_or (ta, tb);
331         } else {
332                 if (tarval_is_all_one(ta)) return ta;
333                 if (tarval_is_all_one(tb)) return tb;
334         }
335         return tarval_bad;
336 }  /* computed_value_Or */
337
338 /**
339  * Return the value of an Eor.
340  */
341 static tarval *computed_value_Eor(ir_node *n) {
342         ir_node *a = get_Eor_left(n);
343         ir_node *b = get_Eor_right(n);
344
345         tarval *ta, *tb;
346
347         if (a == b)
348                 return get_mode_null(get_irn_mode(n));
349
350         ta = value_of(a);
351         tb = value_of(b);
352
353         if ((ta != tarval_bad) && (tb != tarval_bad)) {
354                 return tarval_eor (ta, tb);
355         }
356         return tarval_bad;
357 }  /* computed_value_Eor */
358
359 /**
360  * Return the value of a Not.
361  */
362 static tarval *computed_value_Not(ir_node *n) {
363         ir_node *a = get_Not_op(n);
364         tarval *ta = value_of(a);
365
366         if (ta != tarval_bad)
367                 return tarval_not(ta);
368
369         return tarval_bad;
370 }  /* computed_value_Not */
371
372 /**
373  * Return the value of a Shl.
374  */
375 static tarval *computed_value_Shl(ir_node *n) {
376         ir_node *a = get_Shl_left(n);
377         ir_node *b = get_Shl_right(n);
378
379         tarval *ta = value_of(a);
380         tarval *tb = value_of(b);
381
382         if ((ta != tarval_bad) && (tb != tarval_bad)) {
383                 return tarval_shl (ta, tb);
384         }
385         return tarval_bad;
386 }  /* computed_value_Shl */
387
388 /**
389  * Return the value of a Shr.
390  */
391 static tarval *computed_value_Shr(ir_node *n) {
392         ir_node *a = get_Shr_left(n);
393         ir_node *b = get_Shr_right(n);
394
395         tarval *ta = value_of(a);
396         tarval *tb = value_of(b);
397
398         if ((ta != tarval_bad) && (tb != tarval_bad)) {
399                 return tarval_shr (ta, tb);
400         }
401         return tarval_bad;
402 }  /* computed_value_Shr */
403
404 /**
405  * Return the value of a Shrs.
406  */
407 static tarval *computed_value_Shrs(ir_node *n) {
408         ir_node *a = get_Shrs_left(n);
409         ir_node *b = get_Shrs_right(n);
410
411         tarval *ta = value_of(a);
412         tarval *tb = value_of(b);
413
414         if ((ta != tarval_bad) && (tb != tarval_bad)) {
415                 return tarval_shrs (ta, tb);
416         }
417         return tarval_bad;
418 }  /* computed_value_Shrs */
419
420 /**
421  * Return the value of a Rot.
422  */
423 static tarval *computed_value_Rot(ir_node *n) {
424         ir_node *a = get_Rot_left(n);
425         ir_node *b = get_Rot_right(n);
426
427         tarval *ta = value_of(a);
428         tarval *tb = value_of(b);
429
430         if ((ta != tarval_bad) && (tb != tarval_bad)) {
431                 return tarval_rot (ta, tb);
432         }
433         return tarval_bad;
434 }  /* computed_value_Rot */
435
436 /**
437  * Return the value of a Conv.
438  */
439 static tarval *computed_value_Conv(ir_node *n) {
440         ir_node *a = get_Conv_op(n);
441         tarval *ta = value_of(a);
442
443         if (ta != tarval_bad)
444                 return tarval_convert_to(ta, get_irn_mode(n));
445
446         return tarval_bad;
447 }  /* computed_value_Conv */
448
449 /**
450  * Return the value of a Proj(Cmp).
451  *
452  * This performs a first step of unreachable code elimination.
453  * Proj can not be computed, but folding a Cmp above the Proj here is
454  * not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
455  * only 1 is used.
456  * There are several case where we can evaluate a Cmp node, see later.
457  */
458 static tarval *computed_value_Proj_Cmp(ir_node *n) {
459         ir_node *a   = get_Proj_pred(n);
460         ir_node *aa  = get_Cmp_left(a);
461         ir_node *ab  = get_Cmp_right(a);
462         long proj_nr = get_Proj_proj(n);
463
464         /*
465          * BEWARE: a == a is NOT always True for floating Point values, as
466          * NaN != NaN is defined, so we must check this here.
467          */
468         if (aa == ab && (
469                 !mode_is_float(get_irn_mode(aa)) || proj_nr == pn_Cmp_Lt ||  proj_nr == pn_Cmp_Gt)
470                 ) { /* 1.: */
471
472                 /* This is a trick with the bits used for encoding the Cmp
473                    Proj numbers, the following statement is not the same:
474                 return new_tarval_from_long (proj_nr == pn_Cmp_Eq, mode_b) */
475                 return new_tarval_from_long (proj_nr & pn_Cmp_Eq, mode_b);
476         }
477         else {
478                 tarval *taa = value_of(aa);
479                 tarval *tab = value_of(ab);
480                 ir_mode *mode = get_irn_mode(aa);
481
482                 /*
483                  * The predecessors of Cmp are target values.  We can evaluate
484                  * the Cmp.
485                  */
486                 if ((taa != tarval_bad) && (tab != tarval_bad)) {
487                         /* strange checks... */
488                         pn_Cmp flags = tarval_cmp(taa, tab);
489                         if (flags != pn_Cmp_False) {
490                                 return new_tarval_from_long (proj_nr & flags, mode_b);
491                         }
492                 }
493                 /* for integer values, we can check against MIN/MAX */
494                 else if (mode_is_int(mode)) {
495                         /* MIN <=/> x.  This results in true/false. */
496                         if (taa == get_mode_min(mode)) {
497                                 /* a compare with the MIN value */
498                                 if (proj_nr == pn_Cmp_Le)
499                                         return get_tarval_b_true();
500                                 else if (proj_nr == pn_Cmp_Gt)
501                                         return get_tarval_b_false();
502                         }
503                         /* x >=/< MIN.  This results in true/false. */
504                         else
505                                 if (tab == get_mode_min(mode)) {
506                                         /* a compare with the MIN value */
507                                         if (proj_nr == pn_Cmp_Ge)
508                                                 return get_tarval_b_true();
509                                         else if (proj_nr == pn_Cmp_Lt)
510                                                 return get_tarval_b_false();
511                                 }
512                                 /* MAX >=/< x.  This results in true/false. */
513                                 else if (taa == get_mode_max(mode)) {
514                                         if (proj_nr == pn_Cmp_Ge)
515                                                 return get_tarval_b_true();
516                                         else if (proj_nr == pn_Cmp_Lt)
517                                                 return get_tarval_b_false();
518                                 }
519                                 /* x <=/> MAX.  This results in true/false. */
520                                 else if (tab == get_mode_max(mode)) {
521                                         if (proj_nr == pn_Cmp_Le)
522                                                 return get_tarval_b_true();
523                                         else if (proj_nr == pn_Cmp_Gt)
524                                                 return get_tarval_b_false();
525                                 }
526                 }
527                 /*
528                  * The predecessors are Allocs or (void*)(0) constants.  Allocs never
529                  * return NULL, they raise an exception.   Therefore we can predict
530                  * the Cmp result.
531                  */
532                 else {
533                         ir_node *aaa = skip_Id(skip_Proj(aa));
534                         ir_node *aba = skip_Id(skip_Proj(ab));
535
536                         if (   (   (/* aa is ProjP and aaa is Alloc */
537                                        is_Proj(aa)
538                                     && mode_is_reference(get_irn_mode(aa))
539                                     && is_Alloc(aaa))
540                                 && (   (/* ab is NULL */
541                                            is_Const(ab)
542                                         && mode_is_reference(get_irn_mode(ab))
543                                         && is_Const_null(ab))
544                                     || (/* ab is other Alloc */
545                                            is_Proj(ab)
546                                         && mode_is_reference(get_irn_mode(ab))
547                                         && is_Alloc(aba)
548                                         && (aaa != aba))))
549                             || (/* aa is NULL and aba is Alloc */
550                                    is_Const(aa)
551                                 && mode_is_reference(get_irn_mode(aa))
552                                 && is_Const_null(aa)
553                                 && is_Proj(ab)
554                                 && mode_is_reference(get_irn_mode(ab))
555                                 && is_Alloc(aba)))
556                                 /* 3.: */
557                         return new_tarval_from_long(proj_nr & pn_Cmp_Ne, mode_b);
558                 }
559         }
560         return computed_value_Cmp_Confirm(a, aa, ab, proj_nr);
561 }  /* computed_value_Proj_Cmp */
562
563 /**
564  * Return the value of a Proj, handle Proj(Cmp), Proj(Div), Proj(Mod),
565  * Proj(DivMod) and Proj(Quot).
566  */
567 static tarval *computed_value_Proj(ir_node *n) {
568         ir_node *a = get_Proj_pred(n);
569         long proj_nr;
570
571         switch (get_irn_opcode(a)) {
572         case iro_Cmp:
573                 return computed_value_Proj_Cmp(n);
574
575         case iro_DivMod:
576                 /* compute either the Div or the Mod part */
577                 proj_nr = get_Proj_proj(n);
578                 if (proj_nr == pn_DivMod_res_div)
579                         return do_computed_value_Div(get_DivMod_left(a), get_DivMod_right(a));
580                 else if (proj_nr == pn_DivMod_res_mod)
581                         return do_computed_value_Mod(get_DivMod_left(a), get_DivMod_right(a));
582                 break;
583
584         case iro_Div:
585                 if (get_Proj_proj(n) == pn_Div_res)
586                         return computed_value(a);
587                 break;
588
589         case iro_Mod:
590                 if (get_Proj_proj(n) == pn_Mod_res)
591                         return computed_value(a);
592                 break;
593
594         case iro_Quot:
595                 if (get_Proj_proj(n) == pn_Quot_res)
596                         return computed_value(a);
597                 break;
598
599         default:
600                 return tarval_bad;
601         }
602         return tarval_bad;
603 }  /* computed_value_Proj */
604
605 /**
606  * Calculate the value of a Mux: can be evaluated, if the
607  * sel and the right input are known.
608  */
609 static tarval *computed_value_Mux(ir_node *n) {
610         ir_node *sel = get_Mux_sel(n);
611         tarval *ts = value_of(sel);
612
613         if (ts == get_tarval_b_true()) {
614                 ir_node *v = get_Mux_true(n);
615                 return value_of(v);
616         }
617         else if (ts == get_tarval_b_false()) {
618                 ir_node *v = get_Mux_false(n);
619                 return value_of(v);
620         }
621         return tarval_bad;
622 }  /* computed_value_Mux */
623
624 /**
625  * Calculate the value of a Psi: can be evaluated, if a condition is true
626  * and all previous conditions are false. If all conditions are false
627  * we evaluate to the default one.
628  */
629 static tarval *computed_value_Psi(ir_node *n) {
630         if (is_Mux(n))
631                 return computed_value_Mux(n);
632         return tarval_bad;
633 }  /* computed_value_Psi */
634
635 /**
636  * Calculate the value of a Confirm: can be evaluated,
637  * if it has the form Confirm(x, '=', Const).
638  */
639 static tarval *computed_value_Confirm(ir_node *n) {
640         /*
641          * Beware: we might produce Phi(Confirm(x == true), Confirm(x == false)).
642          * Do NOT optimize them away (CondEval wants them), so wait until
643          * remove_confirm is activated.
644          */
645         if (get_opt_remove_confirm()) {
646                 return get_Confirm_cmp(n) == pn_Cmp_Eq ?
647                         value_of(get_Confirm_bound(n)) : tarval_bad;
648         }
649         return tarval_bad;
650 }  /* computed_value_Confirm */
651
652 /**
653  * If the parameter n can be computed, return its value, else tarval_bad.
654  * Performs constant folding.
655  *
656  * @param n  The node this should be evaluated
657  */
658 tarval *computed_value(ir_node *n) {
659         if (n->op->ops.computed_value)
660                 return n->op->ops.computed_value(n);
661         return tarval_bad;
662 }  /* computed_value */
663
664 /**
665  * Set the default computed_value evaluator in an ir_op_ops.
666  *
667  * @param code   the opcode for the default operation
668  * @param ops    the operations initialized
669  *
670  * @return
671  *    The operations.
672  */
673 static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops)
674 {
675 #define CASE(a)                                    \
676         case iro_##a:                                  \
677                 ops->computed_value  = computed_value_##a; \
678                 break
679
680         switch (code) {
681         CASE(Const);
682         CASE(SymConst);
683         CASE(Add);
684         CASE(Sub);
685         CASE(Minus);
686         CASE(Mul);
687         CASE(Quot);
688         CASE(Div);
689         CASE(Mod);
690         CASE(Abs);
691         CASE(And);
692         CASE(Or);
693         CASE(Eor);
694         CASE(Not);
695         CASE(Shl);
696         CASE(Shr);
697         CASE(Shrs);
698         CASE(Rot);
699         CASE(Carry);
700         CASE(Borrow);
701         CASE(Conv);
702         CASE(Proj);
703         CASE(Mux);
704         CASE(Psi);
705         CASE(Confirm);
706         default:
707                 /* leave NULL */;
708         }
709
710         return ops;
711 #undef CASE
712 }  /* firm_set_default_computed_value */
713
714 /**
715  * Returns a equivalent block for another block.
716  * If the block has only one predecessor, this is
717  * the equivalent one. If the only predecessor of a block is
718  * the block itself, this is a dead block.
719  *
720  * If both predecessors of a block are the branches of a binary
721  * Cond, the equivalent block is Cond's block.
722  *
723  * If all predecessors of a block are bad or lies in a dead
724  * block, the current block is dead as well.
725  *
726  * Note, that blocks are NEVER turned into Bad's, instead
727  * the dead_block flag is set. So, never test for is_Bad(block),
728  * always use is_dead_Block(block).
729  */
730 static ir_node *equivalent_node_Block(ir_node *n)
731 {
732         ir_node *oldn = n;
733         int     n_preds;
734
735         /* don't optimize dead blocks */
736         if (is_Block_dead(n))
737                 return n;
738
739         n_preds = get_Block_n_cfgpreds(n);
740
741         /* The Block constructor does not call optimize, but mature_immBlock()
742            calls the optimization. */
743         assert(get_Block_matured(n));
744
745         /* Straightening: a single entry Block following a single exit Block
746            can be merged, if it is not the Start block. */
747         /* !!! Beware, all Phi-nodes of n must have been optimized away.
748            This should be true, as the block is matured before optimize is called.
749            But what about Phi-cycles with the Phi0/Id that could not be resolved?
750            Remaining Phi nodes are just Ids. */
751         if (n_preds == 1 && is_Jmp(get_Block_cfgpred(n, 0))) {
752                 ir_node *predblock = get_nodes_block(get_Block_cfgpred(n, 0));
753                 if (predblock == oldn) {
754                         /* Jmp jumps into the block it is in -- deal self cycle. */
755                         n = set_Block_dead(n);
756                         DBG_OPT_DEAD_BLOCK(oldn, n);
757                 } else if (get_opt_control_flow_straightening()) {
758                         n = predblock;
759                         DBG_OPT_STG(oldn, n);
760                 }
761         } else if (n_preds == 1 && is_Cond(skip_Proj(get_Block_cfgpred(n, 0)))) {
762                 ir_node *predblock = get_Block_cfgpred_block(n, 0);
763                 if (predblock == oldn) {
764                         /* Jmp jumps into the block it is in -- deal self cycle. */
765                         n = set_Block_dead(n);
766                         DBG_OPT_DEAD_BLOCK(oldn, n);
767                 }
768         } else if ((n_preds == 2) &&
769                    (get_opt_control_flow_weak_simplification())) {
770                 /* Test whether Cond jumps twice to this block
771                  * The more general case which more than 2 predecessors is handles
772                  * in optimize_cf(), we handle only this special case for speed here.
773                  */
774                 ir_node *a = get_Block_cfgpred(n, 0);
775                 ir_node *b = get_Block_cfgpred(n, 1);
776
777                 if (is_Proj(a) &&
778                     is_Proj(b) &&
779                     (get_Proj_pred(a) == get_Proj_pred(b)) &&
780                     is_Cond(get_Proj_pred(a)) &&
781                     (get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
782                         /* Also a single entry Block following a single exit Block.  Phis have
783                            twice the same operand and will be optimized away. */
784                         n = get_nodes_block(get_Proj_pred(a));
785                         DBG_OPT_IFSIM1(oldn, a, b, n);
786                 }
787         } else if (get_opt_unreachable_code() &&
788                    (n != get_irg_start_block(current_ir_graph)) &&
789                    (n != get_irg_end_block(current_ir_graph))    ) {
790                 int i;
791
792                 /* If all inputs are dead, this block is dead too, except if it is
793                    the start or end block.  This is one step of unreachable code
794                    elimination */
795                 for (i = get_Block_n_cfgpreds(n) - 1; i >= 0; --i) {
796                         ir_node *pred = get_Block_cfgpred(n, i);
797                         ir_node *pred_blk;
798
799                         if (is_Bad(pred)) continue;
800                         pred_blk = get_nodes_block(skip_Proj(pred));
801
802                         if (is_Block_dead(pred_blk)) continue;
803
804                         if (pred_blk != n) {
805                                 /* really found a living input */
806                                 break;
807                         }
808                 }
809                 if (i < 0) {
810                         n = set_Block_dead(n);
811                         DBG_OPT_DEAD_BLOCK(oldn, n);
812                 }
813         }
814
815         return n;
816 }  /* equivalent_node_Block */
817
818 /**
819  * Returns a equivalent node for a Jmp, a Bad :-)
820  * Of course this only happens if the Block of the Jmp is dead.
821  */
822 static ir_node *equivalent_node_Jmp(ir_node *n) {
823         /* unreachable code elimination */
824         if (is_Block_dead(get_nodes_block(n)))
825                 n = new_Bad();
826
827         return n;
828 }  /* equivalent_node_Jmp */
829
830 /** Raise is handled in the same way as Jmp. */
831 #define equivalent_node_Raise   equivalent_node_Jmp
832
833
834 /* We do not evaluate Cond here as we replace it by a new node, a Jmp.
835    See transform_node_Proj_Cond(). */
836
837 /**
838  * Optimize operations that are commutative and have neutral 0,
839  * so a op 0 = 0 op a = a.
840  */
841 static ir_node *equivalent_node_neutral_zero(ir_node *n)
842 {
843         ir_node *oldn = n;
844
845         ir_node *a = get_binop_left(n);
846         ir_node *b = get_binop_right(n);
847
848         tarval *tv;
849         ir_node *on;
850
851         /* After running compute_node there is only one constant predecessor.
852            Find this predecessors value and remember the other node: */
853         if ((tv = value_of(a)) != tarval_bad) {
854                 on = b;
855         } else if ((tv = value_of(b)) != tarval_bad) {
856                 on = a;
857         } else
858                 return n;
859
860         /* If this predecessors constant value is zero, the operation is
861          * unnecessary. Remove it.
862          *
863          * Beware: If n is a Add, the mode of on and n might be different
864          * which happens in this rare construction: NULL + 3.
865          * Then, a Conv would be needed which we cannot include here.
866          */
867         if (tarval_is_null(tv) && get_irn_mode(on) == get_irn_mode(n)) {
868                 n = on;
869
870                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
871         }
872
873         return n;
874 }  /* equivalent_node_neutral_zero */
875
876 /**
877  * Eor is commutative and has neutral 0.
878  */
879 static ir_node *equivalent_node_Eor(ir_node *n)
880 {
881         ir_node *oldn = n;
882         ir_node *a;
883         ir_node *b;
884
885         n = equivalent_node_neutral_zero(n);
886         if (n != oldn) return n;
887
888         a = get_Eor_left(n);
889         b = get_Eor_right(n);
890
891         if (is_Eor(a)) {
892                 ir_node *aa = get_Eor_left(a);
893                 ir_node *ab = get_Eor_right(a);
894
895                 if (aa == b) {
896                         /* (a ^ b) ^ a -> b */
897                         n = ab;
898                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
899                         return n;
900                 } else if (ab == b) {
901                         /* (a ^ b) ^ b -> a */
902                         n = aa;
903                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
904                         return n;
905                 }
906         }
907         if (is_Eor(b)) {
908                 ir_node *ba = get_Eor_left(b);
909                 ir_node *bb = get_Eor_right(b);
910
911                 if (ba == a) {
912                         /* a ^ (a ^ b) -> b */
913                         n = bb;
914                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
915                         return n;
916                 } else if (bb == a) {
917                         /* a ^ (b ^ a) -> b */
918                         n = ba;
919                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_EOR_A_B_A);
920                         return n;
921                 }
922         }
923
924         return n;
925 }
926
927 /*
928  * Optimize a - 0 and (a - x) + x (for modes with wrap-around).
929  *
930  * The second one looks strange, but this construct
931  * is used heavily in the LCC sources :-).
932  *
933  * Beware: The Mode of an Add may be different than the mode of its
934  * predecessors, so we could not return a predecessors in all cases.
935  */
936 static ir_node *equivalent_node_Add(ir_node *n) {
937         ir_node *oldn = n;
938         ir_node *left, *right;
939         ir_mode *mode = get_irn_mode(n);
940
941         n = equivalent_node_neutral_zero(n);
942         if (n != oldn)
943                 return n;
944
945         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
946         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
947                 return n;
948
949         left  = get_Add_left(n);
950         right = get_Add_right(n);
951
952         if (is_Sub(left)) {
953                 if (get_Sub_right(left) == right) {
954                         /* (a - x) + x */
955
956                         n = get_Sub_left(left);
957                         if (mode == get_irn_mode(n)) {
958                                 DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB);
959                                 return n;
960                         }
961                 }
962         }
963         if (is_Sub(right)) {
964                 if (get_Sub_right(right) == left) {
965                         /* x + (a - x) */
966
967                         n = get_Sub_left(right);
968                         if (mode == get_irn_mode(n)) {
969                                 DBG_OPT_ALGSIM1(oldn, left, right, n, FS_OPT_ADD_SUB);
970                                 return n;
971                         }
972                 }
973         }
974         return n;
975 }  /* equivalent_node_Add */
976
977 /**
978  * optimize operations that are not commutative but have neutral 0 on left,
979  * so a op 0 = a.
980  */
981 static ir_node *equivalent_node_left_zero(ir_node *n) {
982         ir_node *oldn = n;
983
984         ir_node *a = get_binop_left(n);
985         ir_node *b = get_binop_right(n);
986
987         if (is_Const(b) && is_Const_null(b)) {
988                 n = a;
989
990                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
991         }
992         return n;
993 }  /* equivalent_node_left_zero */
994
995 #define equivalent_node_Shl   equivalent_node_left_zero
996 #define equivalent_node_Shr   equivalent_node_left_zero
997 #define equivalent_node_Shrs  equivalent_node_left_zero
998 #define equivalent_node_Rot   equivalent_node_left_zero
999
1000 /**
1001  * Optimize a - 0 and (a + x) - x (for modes with wrap-around).
1002  *
1003  * The second one looks strange, but this construct
1004  * is used heavily in the LCC sources :-).
1005  *
1006  * Beware: The Mode of a Sub may be different than the mode of its
1007  * predecessors, so we could not return a predecessors in all cases.
1008  */
1009 static ir_node *equivalent_node_Sub(ir_node *n) {
1010         ir_node *oldn = n;
1011         ir_node *b;
1012         ir_mode *mode = get_irn_mode(n);
1013
1014         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
1015         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
1016                 return n;
1017
1018         b = get_Sub_right(n);
1019
1020         /* Beware: modes might be different */
1021         if (is_Const(b) && is_Const_null(b)) {
1022                 ir_node *a = get_Sub_left(n);
1023                 if (mode == get_irn_mode(a)) {
1024                         n = a;
1025
1026                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_0);
1027                 }
1028         }
1029         return n;
1030 }  /* equivalent_node_Sub */
1031
1032
1033 /**
1034  * Optimize an "self-inverse unary op", ie op(op(n)) = n.
1035  *
1036  * @todo
1037  *   -(-a) == a, but might overflow two times.
1038  *   We handle it anyway here but the better way would be a
1039  *   flag. This would be needed for Pascal for instance.
1040  */
1041 static ir_node *equivalent_node_idempotent_unop(ir_node *n) {
1042         ir_node *oldn = n;
1043         ir_node *pred = get_unop_op(n);
1044
1045         /* optimize symmetric unop */
1046         if (get_irn_op(pred) == get_irn_op(n)) {
1047                 n = get_unop_op(pred);
1048                 DBG_OPT_ALGSIM2(oldn, pred, n, FS_OPT_IDEM_UNARY);
1049         }
1050         return n;
1051 }  /* equivalent_node_idempotent_unop */
1052
1053 /** Optimize Not(Not(x)) == x. */
1054 #define equivalent_node_Not    equivalent_node_idempotent_unop
1055
1056 /** -(-x) == x       ??? Is this possible or can --x raise an
1057                        out of bounds exception if min =! max? */
1058 #define equivalent_node_Minus  equivalent_node_idempotent_unop
1059
1060 /**
1061  * Optimize a * 1 = 1 * a = a.
1062  */
1063 static ir_node *equivalent_node_Mul(ir_node *n) {
1064         ir_node *oldn = n;
1065         ir_node *a = get_Mul_left(n);
1066
1067         /* we can handle here only the n * n = n bit cases */
1068         if (get_irn_mode(n) == get_irn_mode(a)) {
1069                 ir_node *b = get_Mul_right(n);
1070
1071                 /* Mul is commutative and has again an other neutral element. */
1072                 if (is_Const(a) && is_Const_one(a)) {
1073                         n = b;
1074                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
1075                 } else if (is_Const(b) && is_Const_one(b)) {
1076                         n = a;
1077                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
1078                 }
1079         }
1080         return n;
1081 }  /* equivalent_node_Mul */
1082
1083 /**
1084  * Optimize a / 1 = a.
1085  */
1086 static ir_node *equivalent_node_Div(ir_node *n) {
1087         ir_node *a = get_Div_left(n);
1088         ir_node *b = get_Div_right(n);
1089
1090         /* Div is not commutative. */
1091         if (is_Const(b) && is_Const_one(b)) { /* div(x, 1) == x */
1092                 /* Turn Div into a tuple (mem, bad, a) */
1093                 ir_node *mem = get_Div_mem(n);
1094                 ir_node *blk = get_irn_n(n, -1);
1095                 turn_into_tuple(n, pn_Div_max);
1096                 set_Tuple_pred(n, pn_Div_M,         mem);
1097                 set_Tuple_pred(n, pn_Div_X_regular, new_r_Jmp(current_ir_graph, blk));
1098                 set_Tuple_pred(n, pn_Div_X_except,  new_Bad());        /* no exception */
1099                 set_Tuple_pred(n, pn_Div_res,       a);
1100         }
1101         return n;
1102 }  /* equivalent_node_Div */
1103
1104 /**
1105  * Optimize a / 1.0 = a.
1106  */
1107 static ir_node *equivalent_node_Quot(ir_node *n) {
1108         ir_node *a = get_Quot_left(n);
1109         ir_node *b = get_Quot_right(n);
1110
1111         /* Div is not commutative. */
1112         if (is_Const(b) && is_Const_one(b)) { /* Quot(x, 1) == x */
1113                 /* Turn Quot into a tuple (mem, jmp, bad, a) */
1114                 ir_node *mem = get_Quot_mem(n);
1115                 ir_node *blk = get_irn_n(n, -1);
1116                 turn_into_tuple(n, pn_Quot_max);
1117                 set_Tuple_pred(n, pn_Quot_M,         mem);
1118                 set_Tuple_pred(n, pn_Quot_X_regular, new_r_Jmp(current_ir_graph, blk));
1119                 set_Tuple_pred(n, pn_Quot_X_except,  new_Bad());        /* no exception */
1120                 set_Tuple_pred(n, pn_Quot_res,       a);
1121         }
1122         return n;
1123 }  /* equivalent_node_Quot */
1124
1125 /**
1126  * Optimize a / 1 = a.
1127  */
1128 static ir_node *equivalent_node_DivMod(ir_node *n) {
1129         ir_node *b = get_DivMod_right(n);
1130
1131         /* Div is not commutative. */
1132         if (is_Const(b) && is_Const_one(b)) { /* div(x, 1) == x */
1133                 /* Turn DivMod into a tuple (mem, jmp, bad, a, 0) */
1134                 ir_node *a = get_DivMod_left(n);
1135                 ir_node *mem = get_Div_mem(n);
1136                 ir_node *blk = get_irn_n(n, -1);
1137                 ir_mode *mode = get_DivMod_resmode(n);
1138
1139                 turn_into_tuple(n, pn_DivMod_max);
1140                 set_Tuple_pred(n, pn_DivMod_M,         mem);
1141                 set_Tuple_pred(n, pn_DivMod_X_regular, new_r_Jmp(current_ir_graph, blk));
1142                 set_Tuple_pred(n, pn_DivMod_X_except,  new_Bad());        /* no exception */
1143                 set_Tuple_pred(n, pn_DivMod_res_div,   a);
1144                 set_Tuple_pred(n, pn_DivMod_res_mod,   new_Const(mode, get_mode_null(mode)));
1145         }
1146         return n;
1147 }  /* equivalent_node_DivMod */
1148
1149 /**
1150  * Use algebraic simplification a | a = a | 0 = 0 | a = a.
1151  */
1152 static ir_node *equivalent_node_Or(ir_node *n) {
1153         ir_node *oldn = n;
1154
1155         ir_node *a = get_Or_left(n);
1156         ir_node *b = get_Or_right(n);
1157
1158         if (a == b) {
1159                 n = a;    /* Or has it's own neutral element */
1160                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_OR);
1161         } else if (is_Const(a) && is_Const_null(a)) {
1162                 n = b;
1163                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_OR);
1164         } else if (is_Const(b) && is_Const_null(b)) {
1165                 n = a;
1166                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_OR);
1167         }
1168
1169         return n;
1170 }  /* equivalent_node_Or */
1171
1172 /**
1173  * Optimize a & 0b1...1 = 0b1...1 & a = a & a = (a|X) & a = a.
1174  */
1175 static ir_node *equivalent_node_And(ir_node *n) {
1176         ir_node *oldn = n;
1177
1178         ir_node *a = get_And_left(n);
1179         ir_node *b = get_And_right(n);
1180
1181         if (a == b) {
1182                 n = a;    /* And has it's own neutral element */
1183                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_AND);
1184                 return n;
1185         }
1186         if (is_Const(a) && is_Const_all_one(a)) {
1187                 n = b;
1188                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1189                 return n;
1190         }
1191         if (is_Const(b) && is_Const_all_one(b)) {
1192                 n = a;
1193                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1194                 return n;
1195         }
1196         if (is_Or(a)) {
1197                 if (b == get_Or_left(a) || b == get_Or_right(a)) {
1198                         /* (a|X) & a */
1199                         n = b;
1200                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1201                         return n;
1202                 }
1203         }
1204         if (is_Or(b)) {
1205                 if (a == get_Or_left(b) || a == get_Or_right(b)) {
1206                         /* a & (a|X) */
1207                         n = a;
1208                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_AND);
1209                         return n;
1210                 }
1211         }
1212
1213         return n;
1214 }  /* equivalent_node_And */
1215
1216 /**
1217  * Try to remove useless Conv's:
1218  */
1219 static ir_node *equivalent_node_Conv(ir_node *n) {
1220         ir_node *oldn = n;
1221         ir_node *a = get_Conv_op(n);
1222
1223         ir_mode *n_mode = get_irn_mode(n);
1224         ir_mode *a_mode = get_irn_mode(a);
1225
1226         if (n_mode == a_mode) { /* No Conv necessary */
1227                 if (get_Conv_strict(n)) {
1228                         /* special case: the predecessor might be a also a Conv */
1229                         if (is_Conv(a)) {
1230                                 if (! get_Conv_strict(a)) {
1231                                         /* first one is not strict, kick it */
1232                                         set_Conv_op(n, get_Conv_op(a));
1233                                         return n;
1234                                 }
1235                                 /* else both are strict conv, second is superfluous */
1236                         } else if(is_Proj(a)) {
1237                                 ir_node *pred = get_Proj_pred(a);
1238                                 if(is_Load(pred)) {
1239                                         /* loads always return with the exact precision of n_mode */
1240                                         assert(get_Load_mode(pred) == n_mode);
1241                                         return a;
1242                                 }
1243                         }
1244
1245                         /* leave strict floating point Conv's */
1246                         return n;
1247                 }
1248                 n = a;
1249                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CONV);
1250         } else if (is_Conv(a)) { /* Conv(Conv(b)) */
1251                 ir_node *b      = get_Conv_op(a);
1252                 ir_mode *b_mode = get_irn_mode(b);
1253
1254                 if (n_mode == b_mode) {
1255                         if (n_mode == mode_b) {
1256                                 n = b; /* Convb(Conv*(xxxb(...))) == xxxb(...) */
1257                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
1258                         } else if (mode_is_int(n_mode)) {
1259                                 if (get_mode_size_bits(b_mode) <= get_mode_size_bits(a_mode)) {
1260                                         n = b;        /* ConvS(ConvL(xxxS(...))) == xxxS(...) */
1261                                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_CONV);
1262                                 }
1263                         }
1264                 }
1265         }
1266         return n;
1267 }  /* equivalent_node_Conv */
1268
1269 /**
1270  * A Cast may be removed if the type of the previous node
1271  * is already the type of the Cast.
1272  */
1273 static ir_node *equivalent_node_Cast(ir_node *n) {
1274         ir_node *oldn = n;
1275         ir_node *pred = get_Cast_op(n);
1276
1277         if (get_irn_type(pred) == get_Cast_type(n)) {
1278                 n = pred;
1279                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_CAST);
1280         }
1281         return n;
1282 }  /* equivalent_node_Cast */
1283
1284 /**
1285  * Several optimizations:
1286  * - no Phi in start block.
1287  * - remove Id operators that are inputs to Phi
1288  * - fold Phi-nodes, iff they have only one predecessor except
1289  *   themselves.
1290  */
1291 static ir_node *equivalent_node_Phi(ir_node *n) {
1292         int i, n_preds;
1293
1294         ir_node *oldn = n;
1295         ir_node *block;
1296         ir_node *first_val = NULL; /* to shutup gcc */
1297
1298         if (!get_opt_normalize()) return n;
1299
1300         n_preds = get_Phi_n_preds(n);
1301
1302         block = get_nodes_block(n);
1303         if ((is_Block_dead(block)) ||                  /* Control dead */
1304                 (block == get_irg_start_block(current_ir_graph)))  /* There should be no Phi nodes */
1305                 return new_Bad();                                    /* in the Start Block. */
1306
1307         if (n_preds == 0) return n;           /* Phi of dead Region without predecessors. */
1308
1309         /* If the Block has a Bad pred, we also have one. */
1310         for (i = 0;  i < n_preds;  ++i)
1311                 if (is_Bad(get_Block_cfgpred(block, i)))
1312                         set_Phi_pred(n, i, new_Bad());
1313
1314         /* Find first non-self-referencing input */
1315         for (i = 0; i < n_preds; ++i) {
1316                 first_val = get_Phi_pred(n, i);
1317                 if (   (first_val != n)                            /* not self pointer */
1318 #if 0
1319                     /* BEWARE: when the if is changed to 1, Phi's will ignore it's Bad
1320                      * predecessors. Then, Phi nodes in dead code might be removed, causing
1321                      * nodes pointing to themself (Add's for instance).
1322                      * This is really bad and causes endless recursions in several
1323                      * code pathes, so we do NOT optimize such a code.
1324                      * This is not that bad as it sounds, optimize_cf() removes bad control flow
1325                      * (and bad Phi predecessors), so live code is optimized later.
1326                      */
1327                     && (! is_Bad(first_val))
1328 #endif
1329                    ) {        /* value not dead */
1330                         break;          /* then found first value. */
1331                 }
1332         }
1333
1334         if (i >= n_preds) {
1335                 /* A totally Bad or self-referencing Phi (we didn't break the above loop) */
1336                 return new_Bad();
1337         }
1338
1339         /* search for rest of inputs, determine if any of these
1340         are non-self-referencing */
1341         while (++i < n_preds) {
1342                 ir_node *scnd_val = get_Phi_pred(n, i);
1343                 if (   (scnd_val != n)
1344                     && (scnd_val != first_val)
1345 #if 0
1346                     /* see above */
1347                     && (! is_Bad(scnd_val))
1348 #endif
1349                         ) {
1350                         break;
1351                 }
1352         }
1353
1354         if (i >= n_preds) {
1355                 /* Fold, if no multiple distinct non-self-referencing inputs */
1356                 n = first_val;
1357                 DBG_OPT_PHI(oldn, n);
1358         }
1359         return n;
1360 }  /* equivalent_node_Phi */
1361
1362 /**
1363  * Several optimizations:
1364  * - no Sync in start block.
1365  * - fold Sync-nodes, iff they have only one predecessor except
1366  *   themselves.
1367  */
1368 static ir_node *equivalent_node_Sync(ir_node *n) {
1369         int arity = get_Sync_n_preds(n);
1370         int i;
1371
1372         for (i = 0; i < arity;) {
1373                 ir_node *pred = get_Sync_pred(n, i);
1374                 int      j;
1375
1376                 /* Remove Bad predecessors */
1377                 if (is_Bad(pred)) {
1378                         del_Sync_n(n, i);
1379                         --arity;
1380                         continue;
1381                 }
1382
1383                 /* Remove duplicate predecessors */
1384                 for (j = 0;; ++j) {
1385                         if (j >= i) {
1386                                 ++i;
1387                                 break;
1388                         }
1389                         if (get_Sync_pred(n, j) == pred) {
1390                                 del_Sync_n(n, i);
1391                                 --arity;
1392                                 break;
1393                         }
1394                 }
1395         }
1396
1397         if (arity == 0) return new_Bad();
1398         if (arity == 1) return get_Sync_pred(n, 0);
1399         return n;
1400 }  /* equivalent_node_Sync */
1401
1402 /**
1403  * Optimize Proj(Tuple) and gigo() for ProjX in Bad block,
1404  * ProjX(Load) and ProjX(Store).
1405  */
1406 static ir_node *equivalent_node_Proj(ir_node *proj) {
1407         ir_node *oldn = proj;
1408         ir_node *a = get_Proj_pred(proj);
1409
1410         if (is_Tuple(a)) {
1411                 /* Remove the Tuple/Proj combination. */
1412                 if ( get_Proj_proj(proj) <= get_Tuple_n_preds(a) ) {
1413                         proj = get_Tuple_pred(a, get_Proj_proj(proj));
1414                         DBG_OPT_TUPLE(oldn, a, proj);
1415                 } else {
1416                          /* This should not happen! */
1417                         assert(! "found a Proj with higher number than Tuple predecessors");
1418                         proj = new_Bad();
1419                 }
1420         } else if (get_irn_mode(proj) == mode_X) {
1421                 if (is_Block_dead(get_nodes_block(skip_Proj(proj)))) {
1422                         /* Remove dead control flow -- early gigo(). */
1423                         proj = new_Bad();
1424                 } else if (get_opt_ldst_only_null_ptr_exceptions()) {
1425                         if (is_Load(a)) {
1426                                 /* get the Load address */
1427                                 ir_node *addr = get_Load_ptr(a);
1428                                 ir_node *blk  = get_irn_n(a, -1);
1429                                 ir_node *confirm;
1430
1431                                 if (value_not_null(addr, &confirm)) {
1432                                         if (confirm == NULL) {
1433                                                 /* this node may float if it did not depend on a Confirm */
1434                                                 set_irn_pinned(a, op_pin_state_floats);
1435                                         }
1436                                         if (get_Proj_proj(proj) == pn_Load_X_except) {
1437                                                 DBG_OPT_EXC_REM(proj);
1438                                                 return new_Bad();
1439                                         } else
1440                                                 return new_r_Jmp(current_ir_graph, blk);
1441                                 }
1442                         } else if (is_Store(a)) {
1443                                 /* get the load/store address */
1444                                 ir_node *addr = get_Store_ptr(a);
1445                                 ir_node *blk  = get_irn_n(a, -1);
1446                                 ir_node *confirm;
1447
1448                                 if (value_not_null(addr, &confirm)) {
1449                                         if (confirm == NULL) {
1450                                                 /* this node may float if it did not depend on a Confirm */
1451                                                 set_irn_pinned(a, op_pin_state_floats);
1452                                         }
1453                                         if (get_Proj_proj(proj) == pn_Store_X_except) {
1454                                                 DBG_OPT_EXC_REM(proj);
1455                                                 return new_Bad();
1456                                         } else
1457                                                 return new_r_Jmp(current_ir_graph, blk);
1458                                 }
1459                         }
1460                 }
1461         }
1462
1463         return proj;
1464 }  /* equivalent_node_Proj */
1465
1466 /**
1467  * Remove Id's.
1468  */
1469 static ir_node *equivalent_node_Id(ir_node *n) {
1470         ir_node *oldn = n;
1471
1472         do {
1473                 n = get_Id_pred(n);
1474         } while (get_irn_op(n) == op_Id);
1475
1476         DBG_OPT_ID(oldn, n);
1477         return n;
1478 }  /* equivalent_node_Id */
1479
1480 /**
1481  * Optimize a Mux.
1482  */
1483 static ir_node *equivalent_node_Mux(ir_node *n)
1484 {
1485         ir_node *oldn = n, *sel = get_Mux_sel(n);
1486         tarval *ts = value_of(sel);
1487
1488         /* Mux(true, f, t) == t */
1489         if (ts == tarval_b_true) {
1490                 n = get_Mux_true(n);
1491                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_C);
1492         }
1493         /* Mux(false, f, t) == f */
1494         else if (ts == tarval_b_false) {
1495                 n = get_Mux_false(n);
1496                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_C);
1497         }
1498         /* Mux(v, x, x) == x */
1499         else if (get_Mux_false(n) == get_Mux_true(n)) {
1500                 n = get_Mux_true(n);
1501                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_EQ);
1502         }
1503         else if (is_Proj(sel) && !mode_honor_signed_zeros(get_irn_mode(n))) {
1504                 ir_node *cmp = get_Proj_pred(sel);
1505                 long proj_nr = get_Proj_proj(sel);
1506                 ir_node *f   = get_Mux_false(n);
1507                 ir_node *t   = get_Mux_true(n);
1508
1509                 /*
1510                  * Note further that these optimization work even for floating point
1511                  * with NaN's because -NaN == NaN.
1512                  * However, if +0 and -0 is handled differently, we cannot use the first one.
1513                  */
1514                 if (is_Cmp(cmp)) {
1515                         ir_node *const cmp_l = get_Cmp_left(cmp);
1516                         ir_node *const cmp_r = get_Cmp_right(cmp);
1517
1518                         switch (proj_nr) {
1519                                 case pn_Cmp_Eq:
1520                                         if ((cmp_l == t && cmp_r == f) || /* Psi(t == f, t, f) -> f */
1521                                                         (cmp_l == f && cmp_r == t)) { /* Psi(f == t, t, f) -> f */
1522                                                 n = f;
1523                                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1524                                                 return n;
1525                                         }
1526                                         break;
1527
1528                                 case pn_Cmp_Lg:
1529                                 case pn_Cmp_Ne:
1530                                         if ((cmp_l == t && cmp_r == f) || /* Psi(t != f, t, f) -> t */
1531                                                         (cmp_l == f && cmp_r == t)) { /* Psi(f != t, t, f) -> t */
1532                                                 n = t;
1533                                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1534                                                 return n;
1535                                         }
1536                                         break;
1537                         }
1538
1539                         /*
1540                          * Note: normalization puts the constant on the right side,
1541                          * so we check only one case.
1542                          */
1543                         if (cmp_l == t && is_Const(cmp_r) && is_Const_null(cmp_r)) {
1544                                 /* Mux(t CMP 0, X, t) */
1545                                 if (is_Minus(f) && get_Minus_op(f) == t) {
1546                                         /* Mux(t CMP 0, -t, t) */
1547                                         if (proj_nr == pn_Cmp_Eq) {
1548                                                 /* Mux(t == 0, -t, t)  ==>  -t */
1549                                                 n = f;
1550                                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1551                                         } else if (proj_nr == pn_Cmp_Lg || proj_nr == pn_Cmp_Ne) {
1552                                                 /* Mux(t != 0, -t, t)  ==> t */
1553                                                 n = t;
1554                                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_TRANSFORM);
1555                                         }
1556                                 }
1557                         }
1558                 }
1559         }
1560         return n;
1561 }  /* equivalent_node_Mux */
1562
1563 /**
1564  * Returns a equivalent node of a Psi: if a condition is true
1565  * and all previous conditions are false we know its value.
1566  * If all conditions are false its value is the default one.
1567  */
1568 static ir_node *equivalent_node_Psi(ir_node *n) {
1569         if (is_Mux(n))
1570                 return equivalent_node_Mux(n);
1571         return n;
1572 }  /* equivalent_node_Psi */
1573
1574 /**
1575  * Optimize -a CMP -b into b CMP a.
1576  * This works only for for modes where unary Minus
1577  * cannot Overflow.
1578  * Note that two-complement integers can Overflow
1579  * so it will NOT work.
1580  *
1581  * For == and != can be handled in Proj(Cmp)
1582  */
1583 static ir_node *equivalent_node_Cmp(ir_node *n) {
1584         ir_node *left  = get_Cmp_left(n);
1585         ir_node *right = get_Cmp_right(n);
1586
1587         if (is_Minus(left) && is_Minus(right) &&
1588                 !mode_overflow_on_unary_Minus(get_irn_mode(left))) {
1589                 left  = get_Minus_op(left);
1590                 right = get_Minus_op(right);
1591                 set_Cmp_left(n, right);
1592                 set_Cmp_right(n, left);
1593         }
1594         return n;
1595 }  /* equivalent_node_Cmp */
1596
1597 /**
1598  * Remove Confirm nodes if setting is on.
1599  * Replace Confirms(x, '=', Constlike) by Constlike.
1600  */
1601 static ir_node *equivalent_node_Confirm(ir_node *n) {
1602         ir_node *pred = get_Confirm_value(n);
1603         pn_Cmp  pnc   = get_Confirm_cmp(n);
1604
1605         if (is_Confirm(pred) && pnc == get_Confirm_cmp(pred)) {
1606                 /*
1607                  * rare case: two identical Confirms one after another,
1608                  * replace the second one with the first.
1609                  */
1610                 n = pred;
1611         }
1612         if (get_opt_remove_confirm())
1613                 return get_Confirm_value(n);
1614         return n;
1615 }
1616
1617 /**
1618  * Optimize CopyB(mem, x, x) into a Nop.
1619  */
1620 static ir_node *equivalent_node_CopyB(ir_node *n) {
1621         ir_node *a = get_CopyB_dst(n);
1622         ir_node *b = get_CopyB_src(n);
1623
1624         if (a == b) {
1625                 /* Turn CopyB into a tuple (mem, jmp, bad, bad) */
1626                 ir_node *mem = get_CopyB_mem(n);
1627                 ir_node *blk = get_nodes_block(n);
1628                 turn_into_tuple(n, pn_CopyB_max);
1629                 set_Tuple_pred(n, pn_CopyB_M,         mem);
1630                 set_Tuple_pred(n, pn_CopyB_X_regular, new_r_Jmp(current_ir_graph, blk));
1631                 set_Tuple_pred(n, pn_CopyB_X_except,  new_Bad());        /* no exception */
1632                 set_Tuple_pred(n, pn_CopyB_M_except,  new_Bad());
1633         }
1634         return n;
1635 }  /* equivalent_node_CopyB */
1636
1637 /**
1638  * Optimize Bounds(idx, idx, upper) into idx.
1639  */
1640 static ir_node *equivalent_node_Bound(ir_node *n) {
1641         ir_node *idx  = get_Bound_index(n);
1642         ir_node *pred = skip_Proj(idx);
1643         int ret_tuple = 0;
1644
1645         if (is_Bound(pred)) {
1646                 /*
1647                  * idx was Bounds checked in the same MacroBlock previously,
1648                  * it is still valid if lower <= pred_lower && pred_upper <= upper.
1649                  */
1650                 ir_node *lower = get_Bound_lower(n);
1651                 ir_node *upper = get_Bound_upper(n);
1652                 if (get_Bound_lower(pred) == lower &&
1653                         get_Bound_upper(pred) == upper &&
1654                         get_irn_MacroBlock(n) == get_irn_MacroBlock(pred)) {
1655                         /*
1656                          * One could expect that we simply return the previous
1657                          * Bound here. However, this would be wrong, as we could
1658                          * add an exception Proj to a new location then.
1659                          * So, we must turn in into a tuple.
1660                          */
1661                         ret_tuple = 1;
1662                 }
1663         }
1664         if (ret_tuple) {
1665                 /* Turn Bound into a tuple (mem, jmp, bad, idx) */
1666                 ir_node *mem = get_Bound_mem(n);
1667                 ir_node *blk = get_nodes_block(n);
1668                 turn_into_tuple(n, pn_Bound_max);
1669                 set_Tuple_pred(n, pn_Bound_M,         mem);
1670                 set_Tuple_pred(n, pn_Bound_X_regular, new_r_Jmp(current_ir_graph, blk));       /* no exception */
1671                 set_Tuple_pred(n, pn_Bound_X_except,  new_Bad());       /* no exception */
1672                 set_Tuple_pred(n, pn_Bound_res,       idx);
1673         }
1674         return n;
1675 }  /* equivalent_node_Bound */
1676
1677 /**
1678  * equivalent_node() returns a node equivalent to input n. It skips all nodes that
1679  * perform no actual computation, as, e.g., the Id nodes.  It does not create
1680  * new nodes.  It is therefore safe to free n if the node returned is not n.
1681  * If a node returns a Tuple we can not just skip it.  If the size of the
1682  * in array fits, we transform n into a tuple (e.g., Div).
1683  */
1684 ir_node *equivalent_node(ir_node *n) {
1685         if (n->op->ops.equivalent_node)
1686                 return n->op->ops.equivalent_node(n);
1687         return n;
1688 }  /* equivalent_node */
1689
1690 /**
1691  * Sets the default equivalent node operation for an ir_op_ops.
1692  *
1693  * @param code   the opcode for the default operation
1694  * @param ops    the operations initialized
1695  *
1696  * @return
1697  *    The operations.
1698  */
1699 static ir_op_ops *firm_set_default_equivalent_node(ir_opcode code, ir_op_ops *ops)
1700 {
1701 #define CASE(a)                                      \
1702         case iro_##a:                                    \
1703                 ops->equivalent_node  = equivalent_node_##a; \
1704                 break
1705
1706         switch (code) {
1707         CASE(Block);
1708         CASE(Jmp);
1709         CASE(Raise);
1710         CASE(Or);
1711         CASE(Add);
1712         CASE(Eor);
1713         CASE(Sub);
1714         CASE(Shl);
1715         CASE(Shr);
1716         CASE(Shrs);
1717         CASE(Rot);
1718         CASE(Not);
1719         CASE(Minus);
1720         CASE(Mul);
1721         CASE(Div);
1722         CASE(Quot);
1723         CASE(DivMod);
1724         CASE(And);
1725         CASE(Conv);
1726         CASE(Cast);
1727         CASE(Phi);
1728         CASE(Sync);
1729         CASE(Proj);
1730         CASE(Id);
1731         CASE(Mux);
1732         CASE(Psi);
1733         CASE(Cmp);
1734         CASE(Confirm);
1735         CASE(CopyB);
1736         CASE(Bound);
1737         default:
1738                 /* leave NULL */;
1739         }
1740
1741         return ops;
1742 #undef CASE
1743 }  /* firm_set_default_equivalent_node */
1744
1745 /**
1746  * Returns non-zero if a node is a Phi node
1747  * with all predecessors constant.
1748  */
1749 static int is_const_Phi(ir_node *n) {
1750         int i;
1751
1752         if (! is_Phi(n) || get_irn_arity(n) == 0)
1753                 return 0;
1754         for (i = get_irn_arity(n) - 1; i >= 0; --i)
1755                 if (! is_Const(get_irn_n(n, i)))
1756                         return 0;
1757                 return 1;
1758 }  /* is_const_Phi */
1759
1760 /**
1761  * Apply an evaluator on a binop with a constant operators (and one Phi).
1762  *
1763  * @param phi    the Phi node
1764  * @param other  the other operand
1765  * @param eval   an evaluator function
1766  * @param mode   the mode of the result, may be different from the mode of the Phi!
1767  * @param left   if non-zero, other is the left operand, else the right
1768  *
1769  * @return a new Phi node if the conversion was successful, NULL else
1770  */
1771 static ir_node *apply_binop_on_phi(ir_node *phi, tarval *other, tarval *(*eval)(tarval *, tarval *), ir_mode *mode, int left) {
1772         tarval   *tv;
1773         void     **res;
1774         ir_node  *pred;
1775         ir_graph *irg;
1776         int      i, n = get_irn_arity(phi);
1777
1778         NEW_ARR_A(void *, res, n);
1779         if (left) {
1780                 for (i = 0; i < n; ++i) {
1781                         pred = get_irn_n(phi, i);
1782                         tv   = get_Const_tarval(pred);
1783                         tv   = eval(other, tv);
1784
1785                         if (tv == tarval_bad) {
1786                                 /* folding failed, bad */
1787                                 return NULL;
1788                         }
1789                         res[i] = tv;
1790                 }
1791         } else {
1792                 for (i = 0; i < n; ++i) {
1793                         pred = get_irn_n(phi, i);
1794                         tv   = get_Const_tarval(pred);
1795                         tv   = eval(tv, other);
1796
1797                         if (tv == tarval_bad) {
1798                                 /* folding failed, bad */
1799                                 return 0;
1800                         }
1801                         res[i] = tv;
1802                 }
1803         }
1804         irg  = current_ir_graph;
1805         for (i = 0; i < n; ++i) {
1806                 pred = get_irn_n(phi, i);
1807                 res[i] = new_r_Const_type(irg, get_irg_start_block(irg),
1808                         mode, res[i], get_Const_type(pred));
1809         }
1810         return new_r_Phi(irg, get_nodes_block(phi), n, (ir_node **)res, mode);
1811 }  /* apply_binop_on_phi */
1812
1813 /**
1814  * Apply an evaluator on a binop with two constant Phi.
1815  *
1816  * @param a      the left Phi node
1817  * @param b      the right Phi node
1818  * @param eval   an evaluator function
1819  * @param mode   the mode of the result, may be different from the mode of the Phi!
1820  *
1821  * @return a new Phi node if the conversion was successful, NULL else
1822  */
1823 static ir_node *apply_binop_on_2_phis(ir_node *a, ir_node *b, tarval *(*eval)(tarval *, tarval *), ir_mode *mode) {
1824         tarval   *tv_l, *tv_r, *tv;
1825         void     **res;
1826         ir_node  *pred;
1827         ir_graph *irg;
1828         int      i, n;
1829
1830         if (get_nodes_block(a) != get_nodes_block(b))
1831                 return NULL;
1832
1833         n = get_irn_arity(a);
1834         NEW_ARR_A(void *, res, n);
1835
1836         for (i = 0; i < n; ++i) {
1837                 pred = get_irn_n(a, i);
1838                 tv_l = get_Const_tarval(pred);
1839                 pred = get_irn_n(b, i);
1840                 tv_r = get_Const_tarval(pred);
1841                 tv   = eval(tv_l, tv_r);
1842
1843                 if (tv == tarval_bad) {
1844                         /* folding failed, bad */
1845                         return NULL;
1846                 }
1847                 res[i] = tv;
1848         }
1849         irg  = current_ir_graph;
1850         for (i = 0; i < n; ++i) {
1851                 pred = get_irn_n(a, i);
1852                 res[i] = new_r_Const_type(irg, get_irg_start_block(irg), mode, res[i], get_Const_type(pred));
1853         }
1854         return new_r_Phi(irg, get_nodes_block(a), n, (ir_node **)res, mode);
1855 }  /* apply_binop_on_2_phis */
1856
1857 /**
1858  * Apply an evaluator on a unop with a constant operator (a Phi).
1859  *
1860  * @param phi    the Phi node
1861  * @param eval   an evaluator function
1862  *
1863  * @return a new Phi node if the conversion was successful, NULL else
1864  */
1865 static ir_node *apply_unop_on_phi(ir_node *phi, tarval *(*eval)(tarval *)) {
1866         tarval   *tv;
1867         void     **res;
1868         ir_node  *pred;
1869         ir_mode  *mode;
1870         ir_graph *irg;
1871         int      i, n = get_irn_arity(phi);
1872
1873         NEW_ARR_A(void *, res, n);
1874         for (i = 0; i < n; ++i) {
1875                 pred = get_irn_n(phi, i);
1876                 tv   = get_Const_tarval(pred);
1877                 tv   = eval(tv);
1878
1879                 if (tv == tarval_bad) {
1880                         /* folding failed, bad */
1881                         return 0;
1882                 }
1883                 res[i] = tv;
1884         }
1885         mode = get_irn_mode(phi);
1886         irg  = current_ir_graph;
1887         for (i = 0; i < n; ++i) {
1888                 pred = get_irn_n(phi, i);
1889                 res[i] = new_r_Const_type(irg, get_irg_start_block(irg),
1890                         mode, res[i], get_Const_type(pred));
1891         }
1892         return new_r_Phi(irg, get_nodes_block(phi), n, (ir_node **)res, mode);
1893 }  /* apply_unop_on_phi */
1894
1895 /**
1896  * Apply a conversion on a constant operator (a Phi).
1897  *
1898  * @param phi    the Phi node
1899  *
1900  * @return a new Phi node if the conversion was successful, NULL else
1901  */
1902 static ir_node *apply_conv_on_phi(ir_node *phi, ir_mode *mode) {
1903         tarval   *tv;
1904         void     **res;
1905         ir_node  *pred;
1906         ir_graph *irg;
1907         int      i, n = get_irn_arity(phi);
1908
1909         NEW_ARR_A(void *, res, n);
1910         for (i = 0; i < n; ++i) {
1911                 pred = get_irn_n(phi, i);
1912                 tv   = get_Const_tarval(pred);
1913                 tv   = tarval_convert_to(tv, mode);
1914
1915                 if (tv == tarval_bad) {
1916                         /* folding failed, bad */
1917                         return 0;
1918                 }
1919                 res[i] = tv;
1920         }
1921         irg  = current_ir_graph;
1922         for (i = 0; i < n; ++i) {
1923                 pred = get_irn_n(phi, i);
1924                 res[i] = new_r_Const_type(irg, get_irg_start_block(irg),
1925                         mode, res[i], get_Const_type(pred));
1926         }
1927         return new_r_Phi(irg, get_nodes_block(phi), n, (ir_node **)res, mode);
1928 }  /* apply_conv_on_phi */
1929
1930 /**
1931  * Transform AddP(P, ConvIs(Iu)), AddP(P, ConvIu(Is)) and
1932  * SubP(P, ConvIs(Iu)), SubP(P, ConvIu(Is)).
1933  * If possible, remove the Conv's.
1934  */
1935 static ir_node *transform_node_AddSub(ir_node *n) {
1936         ir_mode *mode = get_irn_mode(n);
1937
1938         if (mode_is_reference(mode)) {
1939                 ir_node *left     = get_binop_left(n);
1940                 ir_node *right    = get_binop_right(n);
1941                 unsigned ref_bits = get_mode_size_bits(mode);
1942
1943                 if (is_Conv(left)) {
1944                         ir_mode *lmode = get_irn_mode(left);
1945                         unsigned bits = get_mode_size_bits(lmode);
1946
1947                         if (ref_bits == bits &&
1948                             mode_is_int(lmode) &&
1949                             get_mode_arithmetic(lmode) == irma_twos_complement) {
1950                                 ir_node *pre      = get_Conv_op(left);
1951                                 ir_mode *pre_mode = get_irn_mode(pre);
1952
1953                                 if (mode_is_int(pre_mode) &&
1954                                     get_mode_size_bits(pre_mode) == bits &&
1955                                     get_mode_arithmetic(pre_mode) == irma_twos_complement) {
1956                                         /* ok, this conv just changes to sign, moreover the calculation
1957                                          * is done with same number of bits as our address mode, so
1958                                          * we can ignore the conv as address calculation can be viewed
1959                                          * as either signed or unsigned
1960                                          */
1961                                         set_binop_left(n, pre);
1962                                 }
1963                         }
1964                 }
1965
1966                 if (is_Conv(right)) {
1967                         ir_mode *rmode = get_irn_mode(right);
1968                         unsigned bits = get_mode_size_bits(rmode);
1969
1970                         if (ref_bits == bits &&
1971                             mode_is_int(rmode) &&
1972                             get_mode_arithmetic(rmode) == irma_twos_complement) {
1973                                 ir_node *pre      = get_Conv_op(right);
1974                                 ir_mode *pre_mode = get_irn_mode(pre);
1975
1976                                 if (mode_is_int(pre_mode) &&
1977                                     get_mode_size_bits(pre_mode) == bits &&
1978                                     get_mode_arithmetic(pre_mode) == irma_twos_complement) {
1979                                         /* ok, this conv just changes to sign, moreover the calculation
1980                                          * is done with same number of bits as our address mode, so
1981                                          * we can ignore the conv as address calculation can be viewed
1982                                          * as either signed or unsigned
1983                                          */
1984                                         set_binop_right(n, pre);
1985                                 }
1986                         }
1987                 }
1988
1989                 /* let address arithmetic use unsigned modes */
1990                 if (is_Const(right)) {
1991                         ir_mode *rmode = get_irn_mode(right);
1992
1993                         if (mode_is_signed(rmode) && get_mode_arithmetic(rmode) == irma_twos_complement) {
1994                                 /* convert a AddP(P, *s) into AddP(P, *u) */
1995                                 ir_mode *nm = get_reference_mode_unsigned_eq(mode);
1996
1997                                 ir_node *pre = new_r_Conv(current_ir_graph, get_nodes_block(n), right, nm);
1998                                 set_binop_right(n, pre);
1999                         }
2000                 }
2001         }
2002
2003         return n;
2004 }  /* transform_node_AddSub */
2005
2006 #define HANDLE_BINOP_PHI(eval, a, b, c, mode)                     \
2007   c = NULL;                                                       \
2008   if (is_Const(b) && is_const_Phi(a)) {                           \
2009     /* check for Op(Phi, Const) */                                \
2010     c = apply_binop_on_phi(a, get_Const_tarval(b), eval, mode, 0);\
2011   }                                                               \
2012   else if (is_Const(a) && is_const_Phi(b)) {                      \
2013     /* check for Op(Const, Phi) */                                \
2014     c = apply_binop_on_phi(b, get_Const_tarval(a), eval, mode, 1);\
2015   }                                                               \
2016   else if (is_const_Phi(a) && is_const_Phi(b)) {                  \
2017     /* check for Op(Phi, Phi) */                                  \
2018     c = apply_binop_on_2_phis(a, b, eval, mode);                  \
2019   }                                                               \
2020   if (c) {                                                        \
2021     DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI);                   \
2022     return c;                                                     \
2023   }
2024
2025 #define HANDLE_UNOP_PHI(eval, a, c)               \
2026   c = NULL;                                       \
2027   if (is_const_Phi(a)) {                          \
2028     /* check for Op(Phi) */                       \
2029     c = apply_unop_on_phi(a, eval);               \
2030     if (c) {                                      \
2031       DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI); \
2032       return c;                                   \
2033     }                                             \
2034   }
2035
2036 /**
2037  * Do the AddSub optimization, then Transform
2038  *   Constant folding on Phi
2039  *   Add(a,a)          -> Mul(a, 2)
2040  *   Add(Mul(a, x), a) -> Mul(a, x+1)
2041  * if the mode is integer or float.
2042  * Transform Add(a,-b) into Sub(a,b).
2043  * Reassociation might fold this further.
2044  */
2045 static ir_node *transform_node_Add(ir_node *n) {
2046         ir_mode *mode;
2047         ir_node *a, *b, *c, *oldn = n;
2048
2049         n = transform_node_AddSub(n);
2050
2051         a = get_Add_left(n);
2052         b = get_Add_right(n);
2053
2054         mode = get_irn_mode(n);
2055
2056         if (mode_is_reference(mode)) {
2057                 ir_mode *lmode = get_irn_mode(a);
2058
2059                 if (is_Const(b) && is_Const_null(b) && mode_is_int(lmode)) {
2060                         /* an Add(a, NULL) is a hidden Conv */
2061                         dbg_info *dbg = get_irn_dbg_info(n);
2062                         return new_rd_Conv(dbg, current_ir_graph, get_nodes_block(n), a, mode);
2063                 }
2064         }
2065
2066         HANDLE_BINOP_PHI(tarval_add, a, b, c, mode);
2067
2068         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2069         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
2070                 return n;
2071
2072         if (mode_is_num(mode)) {
2073                 /* the following code leads to endless recursion when Mul are replaced by a simple instruction chain */
2074                 if (!is_arch_dep_running() && a == b && mode_is_int(mode)) {
2075                         ir_node *block = get_nodes_block(n);
2076
2077                         n = new_rd_Mul(
2078                                 get_irn_dbg_info(n),
2079                                 current_ir_graph,
2080                                 block,
2081                                 a,
2082                                 new_r_Const_long(current_ir_graph, block, mode, 2),
2083                                 mode);
2084                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_A);
2085                         return n;
2086                 }
2087                 if (is_Minus(a)) {
2088                         n = new_rd_Sub(
2089                                         get_irn_dbg_info(n),
2090                                         current_ir_graph,
2091                                         get_irn_n(n, -1),
2092                                         b,
2093                                         get_Minus_op(a),
2094                                         mode);
2095                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B);
2096                         return n;
2097                 }
2098                 if (is_Minus(b)) {
2099                         n = new_rd_Sub(
2100                                         get_irn_dbg_info(n),
2101                                         current_ir_graph,
2102                                         get_irn_n(n, -1),
2103                                         a,
2104                                         get_Minus_op(b),
2105                                         mode);
2106                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B);
2107                         return n;
2108                 }
2109                 if (get_mode_arithmetic(mode) == irma_twos_complement) {
2110                         /* Here we rely on constants be on the RIGHT side */
2111                         if (is_Not(a)) {
2112                                 ir_node *op = get_Not_op(a);
2113
2114                                 if (is_Const(b) && is_Const_one(b)) {
2115                                         /* ~x + 1 = -x */
2116                                         ir_node *blk = get_irn_n(n, -1);
2117                                         n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, op, mode);
2118                                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_PLUS_1);
2119                                         return n;
2120                                 }
2121                                 if (op == b) {
2122                                         /* ~x + x = -1 */
2123                                         ir_node *blk = get_irn_n(n, -1);
2124                                         n = new_r_Const(current_ir_graph, blk, mode, get_mode_minus_one(mode));
2125                                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_X_NOT_X);
2126                                         return n;
2127                                 }
2128                         }
2129                         if (is_Not(b)) {
2130                                 ir_node *op = get_Not_op(b);
2131
2132                                 if (op == a) {
2133                                         /* x + ~x = -1 */
2134                                         ir_node *blk = get_irn_n(n, -1);
2135                                         n = new_r_Const(current_ir_graph, blk, mode, get_mode_minus_one(mode));
2136                                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_X_NOT_X);
2137                                         return n;
2138                                 }
2139                         }
2140                 }
2141         }
2142         return n;
2143 }  /* transform_node_Add */
2144
2145 /**
2146  * returns -cnst or NULL if impossible
2147  */
2148 static ir_node *const_negate(ir_node *cnst) {
2149         tarval   *tv    = tarval_neg(get_Const_tarval(cnst));
2150         dbg_info *dbgi  = get_irn_dbg_info(cnst);
2151         ir_graph *irg   = get_irn_irg(cnst);
2152         ir_node  *block = get_nodes_block(cnst);
2153         ir_mode  *mode  = get_irn_mode(cnst);
2154         if (tv == tarval_bad) return NULL;
2155         return new_rd_Const(dbgi, irg, block, mode, tv);
2156 }
2157
2158 /**
2159  * Do the AddSub optimization, then Transform
2160  *   Constant folding on Phi
2161  *   Sub(0,a)          -> Minus(a)
2162  *   Sub(Mul(a, x), a) -> Mul(a, x-1)
2163  *   Sub(Sub(x, y), b) -> Sub(x, Add(y,b))
2164  *   Sub(Add(a, x), x) -> a
2165  *   Sub(x, Add(x, a)) -> -a
2166  *   Sub(x, Const)     -> Add(x, -Const)
2167  */
2168 static ir_node *transform_node_Sub(ir_node *n) {
2169         ir_mode *mode;
2170         ir_node *oldn = n;
2171         ir_node *a, *b, *c;
2172
2173         n = transform_node_AddSub(n);
2174
2175         a = get_Sub_left(n);
2176         b = get_Sub_right(n);
2177
2178         mode = get_irn_mode(n);
2179
2180         if (mode_is_int(mode)) {
2181                 ir_mode *lmode = get_irn_mode(a);
2182
2183                 if (is_Const(b) && is_Const_null(b) && mode_is_reference(lmode)) {
2184                         /* a Sub(a, NULL) is a hidden Conv */
2185                         dbg_info *dbg = get_irn_dbg_info(n);
2186                         return new_rd_Conv(dbg, current_ir_graph, get_nodes_block(n), a, mode);
2187                 }
2188         }
2189
2190 restart:
2191         HANDLE_BINOP_PHI(tarval_sub, a, b, c, mode);
2192
2193         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2194         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
2195                 return n;
2196
2197         if (is_Const(b) && get_irn_mode(b) != mode_P) {
2198                 /* a - C -> a + (-C) */
2199                 ir_node *cnst = const_negate(b);
2200                 if (cnst != NULL) {
2201                         ir_node  *block = get_nodes_block(n);
2202                         dbg_info *dbgi  = get_irn_dbg_info(n);
2203                         ir_graph *irg   = get_irn_irg(n);
2204
2205                         n = new_rd_Add(dbgi, irg, block, a, cnst, mode);
2206                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2207                         return n;
2208                 }
2209         }
2210
2211         if (is_Minus(a)) { /* (-a) - b -> -(a + b) */
2212                 ir_graph *irg   = current_ir_graph;
2213                 dbg_info *dbg   = get_irn_dbg_info(n);
2214                 ir_node  *block = get_nodes_block(n);
2215                 ir_node  *left  = get_Minus_op(a);
2216                 ir_node  *add   = new_rd_Add(dbg, irg, block, left, b, mode);
2217
2218                 n = new_rd_Minus(dbg, irg, block, add, mode);
2219                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2220                 return n;
2221         } else if (is_Minus(b)) { /* a - (-b) -> a + b */
2222                 ir_graph *irg   = current_ir_graph;
2223                 dbg_info *dbg   = get_irn_dbg_info(n);
2224                 ir_node  *block = get_nodes_block(n);
2225                 ir_node  *right = get_Minus_op(b);
2226
2227                 n = new_rd_Add(dbg, irg, block, a, right, mode);
2228                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MINUS);
2229                 return n;
2230         } else if (is_Sub(b)) { /* a - (b - c) -> a + (c - b) */
2231                 ir_graph *irg     = current_ir_graph;
2232                 dbg_info *s_dbg   = get_irn_dbg_info(b);
2233                 ir_node  *s_block = get_nodes_block(b);
2234                 ir_node  *s_left  = get_Sub_right(b);
2235                 ir_node  *s_right = get_Sub_left(b);
2236                 ir_mode  *s_mode  = get_irn_mode(b);
2237                 ir_node  *sub     = new_rd_Sub(s_dbg, irg, s_block, s_left, s_right, s_mode);
2238                 dbg_info *a_dbg   = get_irn_dbg_info(n);
2239                 ir_node  *a_block = get_nodes_block(n);
2240
2241                 n = new_rd_Add(a_dbg, irg, a_block, a, sub, mode);
2242                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2243                 return n;
2244         } else if (is_Mul(b)) { /* a - (b * C) -> a + (b * -C) */
2245                 ir_node *m_right = get_Mul_right(b);
2246                 if (is_Const(m_right)) {
2247                         ir_node *cnst2 = const_negate(m_right);
2248                         if (cnst2 != NULL) {
2249                                 ir_graph *irg     = current_ir_graph;
2250                                 dbg_info *m_dbg   = get_irn_dbg_info(b);
2251                                 ir_node  *m_block = get_nodes_block(b);
2252                                 ir_node  *m_left  = get_Mul_left(b);
2253                                 ir_mode  *m_mode  = get_irn_mode(b);
2254                                 ir_node  *mul     = new_rd_Mul(m_dbg, irg, m_block, m_left, cnst2, m_mode);
2255                                 dbg_info *a_dbg   = get_irn_dbg_info(n);
2256                                 ir_node  *a_block = get_nodes_block(n);
2257
2258                                 n = new_rd_Add(a_dbg, irg, a_block, a, mul, mode);
2259                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_TO_ADD);
2260                                 return n;
2261                         }
2262                 }
2263         }
2264
2265         /* Beware of Sub(P, P) which cannot be optimized into a simple Minus ... */
2266         if (mode_is_num(mode) && mode == get_irn_mode(a) && is_Const(a) && is_Const_null(a)) {
2267                 n = new_rd_Minus(
2268                                 get_irn_dbg_info(n),
2269                                 current_ir_graph,
2270                                 get_irn_n(n, -1),
2271                                 b,
2272                                 mode);
2273                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_0_A);
2274                 return n;
2275         }
2276         if (is_Add(a)) {
2277                 if (mode_wrap_around(mode)) {
2278                         ir_node *left  = get_Add_left(a);
2279                         ir_node *right = get_Add_right(a);
2280
2281                         /* FIXME: Does the Conv's work only for two complement or generally? */
2282                         if (left == b) {
2283                                 if (mode != get_irn_mode(right)) {
2284                                         /* This Sub is an effective Cast */
2285                                         right = new_r_Conv(get_irn_irg(n), get_irn_n(n, -1), right, mode);
2286                                 }
2287                                 n = right;
2288                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2289                                 return n;
2290                         } else if (right == b) {
2291                                 if (mode != get_irn_mode(left)) {
2292                                         /* This Sub is an effective Cast */
2293                                         left = new_r_Conv(get_irn_irg(n), get_irn_n(n, -1), left, mode);
2294                                 }
2295                                 n = left;
2296                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2297                                 return n;
2298                         }
2299                 }
2300         }
2301         if (is_Add(b)) {
2302                 if (mode_wrap_around(mode)) {
2303                         ir_node *left  = get_Add_left(b);
2304                         ir_node *right = get_Add_right(b);
2305
2306                         /* FIXME: Does the Conv's work only for two complement or generally? */
2307                         if (left == a) {
2308                                 ir_mode *r_mode = get_irn_mode(right);
2309
2310                                 n = new_r_Minus(get_irn_irg(n), get_irn_n(n, -1), right, r_mode);
2311                                 if (mode != r_mode) {
2312                                         /* This Sub is an effective Cast */
2313                                         n = new_r_Conv(get_irn_irg(n), get_irn_n(n, -1), n, mode);
2314                                 }
2315                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2316                                 return n;
2317                         } else if (right == a) {
2318                                 ir_mode *l_mode = get_irn_mode(left);
2319
2320                                 n = new_r_Minus(get_irn_irg(n), get_irn_n(n, -1), left, l_mode);
2321                                 if (mode != l_mode) {
2322                                         /* This Sub is an effective Cast */
2323                                         n = new_r_Conv(get_irn_irg(n), get_irn_n(n, -1), n, mode);
2324                                 }
2325                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_SUB);
2326                                 return n;
2327                         }
2328                 }
2329         }
2330         if (mode_is_int(mode) && is_Conv(a) && is_Conv(b)) {
2331                 ir_mode *mode = get_irn_mode(a);
2332
2333                 if (mode == get_irn_mode(b)) {
2334                         ir_mode *ma, *mb;
2335                         ir_node *op_a = get_Conv_op(a);
2336                         ir_node *op_b = get_Conv_op(b);
2337
2338                         /* check if it's allowed to skip the conv */
2339                         ma = get_irn_mode(op_a);
2340                         mb = get_irn_mode(op_b);
2341
2342                         if (mode_is_reference(ma) && mode_is_reference(mb)) {
2343                                 /* SubInt(ConvInt(aP), ConvInt(bP)) -> SubInt(aP,bP) */
2344                                 a = op_a; b = op_b;
2345                                 set_Sub_left(n, a);
2346                                 set_Sub_right(n, b);
2347
2348                                 goto restart;
2349                         }
2350                 }
2351         }
2352         /* do NOT execute this code if reassociation is enabled, it does the inverse! */
2353         if (!is_reassoc_running() && is_Mul(a)) {
2354                 ir_node *ma = get_Mul_left(a);
2355                 ir_node *mb = get_Mul_right(a);
2356
2357                 if (ma == b) {
2358                         ir_node *blk = get_irn_n(n, -1);
2359                         n = new_rd_Mul(
2360                                         get_irn_dbg_info(n),
2361                                         current_ir_graph, blk,
2362                                         ma,
2363                                         new_rd_Sub(
2364                                                 get_irn_dbg_info(n),
2365                                                 current_ir_graph, blk,
2366                                                 mb,
2367                                                 new_r_Const_long(current_ir_graph, blk, mode, 1),
2368                                                 mode),
2369                                         mode);
2370                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MUL_A_X_A);
2371                         return n;
2372                 } else if (mb == b) {
2373                         ir_node *blk = get_irn_n(n, -1);
2374                         n = new_rd_Mul(
2375                                         get_irn_dbg_info(n),
2376                                         current_ir_graph, blk,
2377                                         mb,
2378                                         new_rd_Sub(
2379                                                 get_irn_dbg_info(n),
2380                                                 current_ir_graph, blk,
2381                                                 ma,
2382                                                 new_r_Const_long(current_ir_graph, blk, mode, 1),
2383                                                 mode),
2384                                         mode);
2385                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_MUL_A_X_A);
2386                         return n;
2387                 }
2388         }
2389         if (is_Sub(a)) { /* (x - y) - b -> x - (y + b) */
2390                 ir_node *x   =      get_Sub_left(a);
2391                 ir_node *y        = get_Sub_right(a);
2392                 ir_node *blk      = get_irn_n(n, -1);
2393                 ir_mode *m_b      = get_irn_mode(b);
2394                 ir_mode *m_y      = get_irn_mode(y);
2395                 ir_mode *add_mode;
2396                 ir_node *add;
2397
2398                 /* Determine the right mode for the Add. */
2399                 if (m_b == m_y)
2400                         add_mode = m_b;
2401                 else if (mode_is_reference(m_b))
2402                         add_mode = m_b;
2403                 else if (mode_is_reference(m_y))
2404                         add_mode = m_y;
2405                 else {
2406                         /*
2407                          * Both modes are different but none is reference,
2408                          * happens for instance in SubP(SubP(P, Iu), Is).
2409                          * We have two possibilities here: Cast or ignore.
2410                          * Currently we ignore this case.
2411                          */
2412                         return n;
2413                 }
2414
2415                 add = new_r_Add(current_ir_graph, blk, y, b, add_mode);
2416
2417                 n = new_rd_Sub(get_irn_dbg_info(n), current_ir_graph, blk, x, add, mode);
2418                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_SUB_X_Y_Z);
2419                 return n;
2420         }
2421
2422         if (get_mode_arithmetic(mode) == irma_twos_complement) {
2423                 if (is_Const(a) && is_Not(b)) {
2424                         /* c - ~X = X + (c+1) */
2425                         tarval *tv = get_Const_tarval(a);
2426
2427                         tv = tarval_add(tv, get_mode_one(mode));
2428                         if (tv != tarval_bad) {
2429                                 ir_node *blk = get_irn_n(n, -1);
2430                                 ir_node *c = new_r_Const(current_ir_graph, blk, mode, tv);
2431                                 n = new_rd_Add(get_irn_dbg_info(n), current_ir_graph, blk, get_Not_op(b), c, mode);
2432                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_SUB_C_NOT_X);
2433                                 return n;
2434                         }
2435                 }
2436         }
2437         return n;
2438 }  /* transform_node_Sub */
2439
2440 /**
2441  * Several transformation done on n*n=2n bits mul.
2442  * These transformations must be done here because new nodes may be produced.
2443  */
2444 static ir_node *transform_node_Mul2n(ir_node *n, ir_mode *mode) {
2445         ir_node *oldn = n;
2446         ir_node *a = get_Mul_left(n);
2447         ir_node *b = get_Mul_right(n);
2448         tarval *ta = value_of(a);
2449         tarval *tb = value_of(b);
2450         ir_mode *smode = get_irn_mode(a);
2451
2452         if (ta == get_mode_one(smode)) {
2453                 /* (L)1 * (L)b = (L)b */
2454                 ir_node *blk = get_irn_n(n, -1);
2455                 n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, b, mode);
2456                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
2457                 return n;
2458         }
2459         else if (ta == get_mode_minus_one(smode)) {
2460                 /* (L)-1 * (L)b = (L)b */
2461                 ir_node *blk = get_irn_n(n, -1);
2462                 n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, b, smode);
2463                 n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, n, mode);
2464                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2465                 return n;
2466         }
2467         if (tb == get_mode_one(smode)) {
2468                 /* (L)a * (L)1 = (L)a */
2469                 ir_node *blk = get_irn_n(a, -1);
2470                 n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, a, mode);
2471                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_NEUTRAL_1);
2472                 return n;
2473         }
2474         else if (tb == get_mode_minus_one(smode)) {
2475                 /* (L)a * (L)-1 = (L)-a */
2476                 ir_node *blk = get_irn_n(n, -1);
2477                 n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, a, smode);
2478                 n = new_rd_Conv(get_irn_dbg_info(n), current_ir_graph, blk, n, mode);
2479                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2480                 return n;
2481         }
2482         return n;
2483 }
2484
2485 /**
2486  * Transform Mul(a,-1) into -a.
2487  * Do constant evaluation of Phi nodes.
2488  * Do architecture dependent optimizations on Mul nodes
2489  */
2490 static ir_node *transform_node_Mul(ir_node *n) {
2491         ir_node *c, *oldn = n;
2492         ir_mode *mode = get_irn_mode(n);
2493         ir_node *a = get_Mul_left(n);
2494         ir_node *b = get_Mul_right(n);
2495
2496         if (is_Bad(a) || is_Bad(b))
2497                 return n;
2498
2499         if (mode != get_irn_mode(a))
2500                 return transform_node_Mul2n(n, mode);
2501
2502         HANDLE_BINOP_PHI(tarval_mul, a, b, c, mode);
2503
2504         if (mode_is_signed(mode)) {
2505                 ir_node *r = NULL;
2506
2507                 if (value_of(a) == get_mode_minus_one(mode))
2508                         r = b;
2509                 else if (value_of(b) == get_mode_minus_one(mode))
2510                         r = a;
2511                 if (r) {
2512                         n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1), r, mode);
2513                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2514                         return n;
2515                 }
2516         }
2517         if (is_Minus(a)) {
2518                 if (is_Const(b)) { /* (-a) * const -> a * -const */
2519                         ir_node *cnst = const_negate(b);
2520                         if (cnst != NULL) {
2521                                 dbg_info *dbgi  = get_irn_dbg_info(n);
2522                                 ir_node  *block = get_nodes_block(n);
2523                                 n = new_rd_Mul(dbgi, current_ir_graph, block, get_Minus_op(a), cnst, mode);
2524                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_1);
2525                                 return n;
2526                         }
2527                 } else if (is_Minus(b)) { /* (-a) * (-b) -> a * b */
2528                         dbg_info *dbgi  = get_irn_dbg_info(n);
2529                         ir_node  *block = get_nodes_block(n);
2530                         n = new_rd_Mul(dbgi, current_ir_graph, block, get_Minus_op(a), get_Minus_op(b), mode);
2531                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS_MINUS);
2532                         return n;
2533                 } else if (is_Sub(b)) { /* (-a) * (b - c) -> a * (c - b) */
2534                         ir_node  *sub_l = get_Sub_left(b);
2535                         ir_node  *sub_r = get_Sub_right(b);
2536                         dbg_info *dbgi  = get_irn_dbg_info(n);
2537                         ir_graph *irg   = current_ir_graph;
2538                         ir_node  *block = get_nodes_block(n);
2539                         ir_node  *new_b = new_rd_Sub(dbgi, irg, block, sub_r, sub_l, mode);
2540                         n = new_rd_Mul(dbgi, irg, block, get_Minus_op(a), new_b, mode);
2541                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS);
2542                         return n;
2543                 }
2544         } else if (is_Minus(b)) {
2545                 if (is_Sub(a)) { /* (a - b) * (-c) -> (b - a) * c */
2546                         ir_node  *sub_l = get_Sub_left(a);
2547                         ir_node  *sub_r = get_Sub_right(a);
2548                         dbg_info *dbgi  = get_irn_dbg_info(n);
2549                         ir_graph *irg   = current_ir_graph;
2550                         ir_node  *block = get_nodes_block(n);
2551                         ir_node  *new_a = new_rd_Sub(dbgi, irg, block, sub_r, sub_l, mode);
2552                         n = new_rd_Mul(dbgi, irg, block, new_a, get_Minus_op(b), mode);
2553                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_MUL_MINUS);
2554                         return n;
2555                 }
2556         }
2557         if (get_mode_arithmetic(mode) == irma_ieee754) {
2558                 if (is_Const(a)) {
2559                         tarval *tv = get_Const_tarval(a);
2560                         if (tarval_ieee754_get_exponent(tv) == 1 && tarval_ieee754_zero_mantissa(tv)) {
2561                                 /* 2.0 * b = b + b */
2562                                 n = new_rd_Add(get_irn_dbg_info(n), current_ir_graph, get_nodes_block(n), b, b, mode);
2563                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_A_A);
2564                                 return n;
2565                         }
2566                 }
2567                 else if (is_Const(b)) {
2568                         tarval *tv = get_Const_tarval(b);
2569                         if (tarval_ieee754_get_exponent(tv) == 1 && tarval_ieee754_zero_mantissa(tv)) {
2570                                 /* a * 2.0 = a + a */
2571                                 n = new_rd_Add(get_irn_dbg_info(n), current_ir_graph, get_nodes_block(n), a, a, mode);
2572                                 DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_ADD_A_A);
2573                                 return n;
2574                         }
2575                 }
2576         }
2577         return arch_dep_replace_mul_with_shifts(n);
2578 }  /* transform_node_Mul */
2579
2580 /**
2581  * Transform a Div Node.
2582  */
2583 static ir_node *transform_node_Div(ir_node *n) {
2584         ir_mode *mode = get_Div_resmode(n);
2585         ir_node *a = get_Div_left(n);
2586         ir_node *b = get_Div_right(n);
2587         ir_node *value;
2588         tarval  *tv;
2589
2590         if (is_Const(b) && is_const_Phi(a)) {
2591                 /* check for Div(Phi, Const) */
2592                 value = apply_binop_on_phi(a, get_Const_tarval(b), tarval_div, mode, 0);
2593                 if (value) {
2594                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2595                         goto make_tuple;
2596                 }
2597         }
2598         else if (is_Const(a) && is_const_Phi(b)) {
2599                 /* check for Div(Const, Phi) */
2600                 value = apply_binop_on_phi(b, get_Const_tarval(a), tarval_div, mode, 1);
2601                 if (value) {
2602                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2603                         goto make_tuple;
2604                 }
2605         }
2606         else if (is_const_Phi(a) && is_const_Phi(b)) {
2607                 /* check for Div(Phi, Phi) */
2608                 value = apply_binop_on_2_phis(a, b, tarval_div, mode);
2609                 if (value) {
2610                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2611                         goto make_tuple;
2612                 }
2613         }
2614
2615         value = n;
2616         tv = value_of(n);
2617         if (tv != tarval_bad) {
2618                 value = new_Const(get_tarval_mode(tv), tv);
2619
2620                 DBG_OPT_CSTEVAL(n, value);
2621                 goto make_tuple;
2622         } else {
2623                 ir_node *a = get_Div_left(n);
2624                 ir_node *b = get_Div_right(n);
2625                 ir_node *dummy;
2626
2627                 if (a == b && value_not_zero(a, &dummy)) {
2628                         /* BEWARE: we can optimize a/a to 1 only if this cannot cause a exception */
2629                         value = new_Const(mode, get_mode_one(mode));
2630                         DBG_OPT_CSTEVAL(n, value);
2631                         goto make_tuple;
2632                 } else {
2633                         if (mode_is_signed(mode) && is_Const(b)) {
2634                                 tarval *tv = get_Const_tarval(b);
2635
2636                                 if (tv == get_mode_minus_one(mode)) {
2637                                         /* a / -1 */
2638                                         value = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1), a, mode);
2639                                         DBG_OPT_CSTEVAL(n, value);
2640                                         goto make_tuple;
2641                                 }
2642                         }
2643                         /* Try architecture dependent optimization */
2644                         value = arch_dep_replace_div_by_const(n);
2645                 }
2646         }
2647
2648         if (value != n) {
2649                 ir_node *mem, *blk;
2650
2651 make_tuple:
2652                 /* Turn Div into a tuple (mem, jmp, bad, value) */
2653                 mem = get_Div_mem(n);
2654                 blk = get_irn_n(n, -1);
2655
2656                 /* skip a potential Pin */
2657                 if (is_Pin(mem))
2658                         mem = get_Pin_op(mem);
2659                 turn_into_tuple(n, pn_Div_max);
2660                 set_Tuple_pred(n, pn_Div_M,         mem);
2661                 set_Tuple_pred(n, pn_Div_X_regular, new_r_Jmp(current_ir_graph, blk));
2662                 set_Tuple_pred(n, pn_Div_X_except,  new_Bad());
2663                 set_Tuple_pred(n, pn_Div_res,       value);
2664         }
2665         return n;
2666 }  /* transform_node_Div */
2667
2668 /**
2669  * Transform a Mod node.
2670  */
2671 static ir_node *transform_node_Mod(ir_node *n) {
2672         ir_mode *mode = get_Mod_resmode(n);
2673         ir_node *a = get_Mod_left(n);
2674         ir_node *b = get_Mod_right(n);
2675         ir_node *value;
2676         tarval  *tv;
2677
2678         if (is_Const(b) && is_const_Phi(a)) {
2679                 /* check for Div(Phi, Const) */
2680                 value = apply_binop_on_phi(a, get_Const_tarval(b), tarval_mod, mode, 0);
2681                 if (value) {
2682                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2683                         goto make_tuple;
2684                 }
2685         }
2686         else if (is_Const(a) && is_const_Phi(b)) {
2687                 /* check for Div(Const, Phi) */
2688                 value = apply_binop_on_phi(b, get_Const_tarval(a), tarval_mod, mode, 1);
2689                 if (value) {
2690                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2691                         goto make_tuple;
2692                 }
2693         }
2694         else if (is_const_Phi(a) && is_const_Phi(b)) {
2695                 /* check for Div(Phi, Phi) */
2696                 value = apply_binop_on_2_phis(a, b, tarval_mod, mode);
2697                 if (value) {
2698                         DBG_OPT_ALGSIM0(n, value, FS_OPT_CONST_PHI);
2699                         goto make_tuple;
2700                 }
2701         }
2702
2703         value = n;
2704         tv = value_of(n);
2705         if (tv != tarval_bad) {
2706                 value = new_Const(get_tarval_mode(tv), tv);
2707
2708                 DBG_OPT_CSTEVAL(n, value);
2709                 goto make_tuple;
2710         } else {
2711                 ir_node *a = get_Mod_left(n);
2712                 ir_node *b = get_Mod_right(n);
2713                 ir_node *dummy;
2714
2715                 if (a == b && value_not_zero(a, &dummy)) {
2716                         /* BEWARE: we can optimize a%a to 0 only if this cannot cause a exception */
2717                         value = new_Const(mode, get_mode_null(mode));
2718                         DBG_OPT_CSTEVAL(n, value);
2719                         goto make_tuple;
2720                 } else {
2721                         if (mode_is_signed(mode) && is_Const(b)) {
2722                                 tarval *tv = get_Const_tarval(b);
2723
2724                                 if (tv == get_mode_minus_one(mode)) {
2725                                         /* a % -1 = 0 */
2726                                         value = new_Const(mode, get_mode_null(mode));
2727                                         DBG_OPT_CSTEVAL(n, value);
2728                                         goto make_tuple;
2729                                 }
2730                         }
2731                         /* Try architecture dependent optimization */
2732                         value = arch_dep_replace_mod_by_const(n);
2733                 }
2734         }
2735
2736         if (value != n) {
2737                 ir_node *mem, *blk;
2738
2739 make_tuple:
2740                 /* Turn Mod into a tuple (mem, jmp, bad, value) */
2741                 mem = get_Mod_mem(n);
2742                 blk = get_irn_n(n, -1);
2743
2744                 /* skip a potential Pin */
2745                 if (is_Pin(mem))
2746                         mem = get_Pin_op(mem);
2747                 turn_into_tuple(n, pn_Mod_max);
2748                 set_Tuple_pred(n, pn_Mod_M,         mem);
2749                 set_Tuple_pred(n, pn_Mod_X_regular, new_r_Jmp(current_ir_graph, blk));
2750                 set_Tuple_pred(n, pn_Mod_X_except,  new_Bad());
2751                 set_Tuple_pred(n, pn_Mod_res,       value);
2752         }
2753         return n;
2754 }  /* transform_node_Mod */
2755
2756 /**
2757  * Transform a DivMod node.
2758  */
2759 static ir_node *transform_node_DivMod(ir_node *n) {
2760         ir_node *dummy;
2761         ir_node *a = get_DivMod_left(n);
2762         ir_node *b = get_DivMod_right(n);
2763         ir_mode *mode = get_DivMod_resmode(n);
2764         tarval *ta, *tb;
2765         int evaluated = 0;
2766         ir_node *va, *vb;
2767
2768         if (is_Const(b) && is_const_Phi(a)) {
2769                 /* check for Div(Phi, Const) */
2770                 va = apply_binop_on_phi(a, get_Const_tarval(b), tarval_div, mode, 0);
2771                 vb = apply_binop_on_phi(a, get_Const_tarval(b), tarval_mod, mode, 0);
2772                 if (va && vb) {
2773                         DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
2774                         DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
2775                         goto make_tuple;
2776                 }
2777         }
2778         else if (is_Const(a) && is_const_Phi(b)) {
2779                 /* check for Div(Const, Phi) */
2780                 va = apply_binop_on_phi(b, get_Const_tarval(a), tarval_div, mode, 1);
2781                 vb = apply_binop_on_phi(b, get_Const_tarval(a), tarval_mod, mode, 1);
2782                 if (va && vb) {
2783                         DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
2784                         DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
2785                         goto make_tuple;
2786                 }
2787         }
2788         else if (is_const_Phi(a) && is_const_Phi(b)) {
2789                 /* check for Div(Phi, Phi) */
2790                 va = apply_binop_on_2_phis(a, b, tarval_div, mode);
2791                 vb = apply_binop_on_2_phis(a, b, tarval_mod, mode);
2792                 if (va && vb) {
2793                         DBG_OPT_ALGSIM0(n, va, FS_OPT_CONST_PHI);
2794                         DBG_OPT_ALGSIM0(n, vb, FS_OPT_CONST_PHI);
2795                         goto make_tuple;
2796                 }
2797         }
2798
2799         ta = value_of(a);
2800         tb = value_of(b);
2801         if (tb != tarval_bad) {
2802                 if (tb == get_mode_one(get_tarval_mode(tb))) {
2803                         va = a;
2804                         vb = new_Const(mode, get_mode_null(mode));
2805                         DBG_OPT_CSTEVAL(n, vb);
2806                         goto make_tuple;
2807                 } else if (ta != tarval_bad) {
2808                         tarval *resa, *resb;
2809                         resa = tarval_div(ta, tb);
2810                         if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
2811                                                              Jmp for X result!? */
2812                         resb = tarval_mod(ta, tb);
2813                         if (resb == tarval_bad) return n; /* Causes exception! */
2814                         va = new_Const(mode, resa);
2815                         vb = new_Const(mode, resb);
2816                         DBG_OPT_CSTEVAL(n, va);
2817                         DBG_OPT_CSTEVAL(n, vb);
2818                         goto make_tuple;
2819                 } else if (mode_is_signed(mode) && tb == get_mode_minus_one(mode)) {
2820                         va = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1), a, mode);
2821                         vb = new_Const(mode, get_mode_null(mode));
2822                         DBG_OPT_CSTEVAL(n, va);
2823                         DBG_OPT_CSTEVAL(n, vb);
2824                         goto make_tuple;
2825                 } else { /* Try architecture dependent optimization */
2826                         va = a;
2827                         vb = b;
2828                         arch_dep_replace_divmod_by_const(&va, &vb, n);
2829                         evaluated = va != NULL;
2830                 }
2831         } else if (a == b) {
2832                 if (value_not_zero(a, &dummy)) {
2833                         /* a/a && a != 0 */
2834                         va = new_Const(mode, get_mode_one(mode));
2835                         vb = new_Const(mode, get_mode_null(mode));
2836                         DBG_OPT_CSTEVAL(n, va);
2837                         DBG_OPT_CSTEVAL(n, vb);
2838                         goto make_tuple;
2839                 } else {
2840                         /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
2841                         return n;
2842                 }
2843         } else if (ta == get_mode_null(mode) && value_not_zero(b, &dummy)) {
2844                 /* 0 / non-Const = 0 */
2845                 vb = va = a;
2846                 goto make_tuple;
2847         }
2848
2849         if (evaluated) { /* replace by tuple */
2850                 ir_node *mem, *blk;
2851
2852 make_tuple:
2853                 mem = get_DivMod_mem(n);
2854                 /* skip a potential Pin */
2855                 if (is_Pin(mem))
2856                         mem = get_Pin_op(mem);
2857
2858                 blk = get_irn_n(n, -1);
2859                 turn_into_tuple(n, pn_DivMod_max);
2860                 set_Tuple_pred(n, pn_DivMod_M,         mem);
2861                 set_Tuple_pred(n, pn_DivMod_X_regular, new_r_Jmp(current_ir_graph, blk));
2862                 set_Tuple_pred(n, pn_DivMod_X_except,  new_Bad());  /* no exception */
2863                 set_Tuple_pred(n, pn_DivMod_res_div,   va);
2864                 set_Tuple_pred(n, pn_DivMod_res_mod,   vb);
2865         }
2866
2867         return n;
2868 }  /* transform_node_DivMod */
2869
2870 /**
2871  * Optimize x / c to x * (1/c)
2872  */
2873 static ir_node *transform_node_Quot(ir_node *n) {
2874         ir_mode *mode = get_Quot_resmode(n);
2875         ir_node *oldn = n;
2876
2877         if (get_mode_arithmetic(mode) == irma_ieee754) {
2878                 ir_node *b = get_Quot_right(n);
2879
2880                 if (is_Const(b)) {
2881                         tarval *tv = get_Const_tarval(b);
2882                         int rem;
2883
2884                         /*
2885                          * Floating point constant folding might be disabled here to
2886                          * prevent rounding.
2887                          * However, as we check for exact result, doing it is safe.
2888                          * Switch it on.
2889                          */
2890                         rem = tarval_enable_fp_ops(1);
2891                         tv = tarval_quo(get_mode_one(mode), tv);
2892                         (void)tarval_enable_fp_ops(rem);
2893
2894                         /* Do the transformation if the result is either exact or we are not
2895                            using strict rules. */
2896                         if (tv != tarval_bad &&
2897                             (tarval_ieee754_get_exact() || (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic) == 0)) {
2898                                 ir_node *blk = get_irn_n(n, -1);
2899                                 ir_node *c = new_r_Const(current_ir_graph, blk, mode, tv);
2900                                 ir_node *a = get_Quot_left(n);
2901                                 ir_node *m = new_rd_Mul(get_irn_dbg_info(n), current_ir_graph, blk, a, c, mode);
2902                                 ir_node *mem = get_Quot_mem(n);
2903
2904                                 /* skip a potential Pin */
2905                                 if (is_Pin(mem))
2906                                         mem = get_Pin_op(mem);
2907                                 turn_into_tuple(n, pn_Quot_max);
2908                                 set_Tuple_pred(n, pn_Quot_M, mem);
2909                                 set_Tuple_pred(n, pn_Quot_X_regular, new_r_Jmp(current_ir_graph, blk));
2910                                 set_Tuple_pred(n, pn_Quot_X_except,  new_r_Bad(current_ir_graph));
2911                                 set_Tuple_pred(n, pn_Quot_res, m);
2912                                 DBG_OPT_ALGSIM1(oldn, a, b, m, FS_OPT_FP_INV_MUL);
2913                         }
2914                 }
2915         }
2916         return n;
2917 }  /* transform_node_Quot */
2918
2919 /**
2920  * Optimize Abs(x) into  x if x is Confirmed >= 0
2921  * Optimize Abs(x) into -x if x is Confirmed <= 0
2922  * Optimize Abs(-x) int Abs(x)
2923  */
2924 static ir_node *transform_node_Abs(ir_node *n) {
2925         ir_node *c, *oldn = n;
2926         ir_node *a = get_Abs_op(n);
2927         ir_mode *mode;
2928
2929         HANDLE_UNOP_PHI(tarval_abs, a, c);
2930
2931         switch (classify_value_sign(a)) {
2932         case value_classified_negative:
2933                 mode = get_irn_mode(n);
2934
2935                 /*
2936                  * We can replace the Abs by -x here.
2937                  * We even could add a new Confirm here
2938                  * (if not twos complement)
2939                  *
2940                  * Note that -x would create a new node, so we could
2941                  * not run it in the equivalent_node() context.
2942                  */
2943                 n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph,
2944                                 get_nodes_block(n), a, mode);
2945
2946                 DBG_OPT_CONFIRM(oldn, n);
2947                 return n;
2948         case value_classified_positive:
2949                 /* n is positive, Abs is not needed */
2950                 n = a;
2951
2952                 DBG_OPT_CONFIRM(oldn, n);
2953                 return n;
2954         default:
2955                 break;
2956         }
2957         if (is_Minus(a)) {
2958                 /* Abs(-x) = Abs(x) */
2959                 mode = get_irn_mode(n);
2960                 n = new_rd_Abs(get_irn_dbg_info(n), current_ir_graph,
2961                                 get_nodes_block(n), get_Minus_op(a), mode);
2962                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ABS_MINUS_X);
2963                 return n;
2964         }
2965         return n;
2966 }  /* transform_node_Abs */
2967
2968 /**
2969  * Transform a Cond node.
2970  *
2971  * Replace the Cond by a Jmp if it branches on a constant
2972  * condition.
2973  */
2974 static ir_node *transform_node_Cond(ir_node *n) {
2975
2976         ir_node *jmp;
2977         ir_node *a = get_Cond_selector(n);
2978         tarval *ta = value_of(a);
2979
2980         /* we need block info which is not available in floating irgs */
2981         if (get_irg_pinned(current_ir_graph) == op_pin_state_floats)
2982                 return n;
2983
2984         if ((ta != tarval_bad) &&
2985             (get_irn_mode(a) == mode_b) &&
2986             (get_opt_unreachable_code())) {
2987                 /* It's a boolean Cond, branching on a boolean constant.
2988                    Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
2989                 ir_node *blk = get_nodes_block(n);
2990                 jmp = new_r_Jmp(current_ir_graph, blk);
2991                 turn_into_tuple(n, pn_Cond_max);
2992                 if (ta == tarval_b_true) {
2993                         set_Tuple_pred(n, pn_Cond_false, new_Bad());
2994                         set_Tuple_pred(n, pn_Cond_true, jmp);
2995                 } else {
2996                         set_Tuple_pred(n, pn_Cond_false, jmp);
2997                         set_Tuple_pred(n, pn_Cond_true, new_Bad());
2998                 }
2999                 /* We might generate an endless loop, so keep it alive. */
3000                 add_End_keepalive(get_irg_end(current_ir_graph), blk);
3001         }
3002         return n;
3003 }  /* transform_node_Cond */
3004
3005 /**
3006  * Prototype of a recursive transform function
3007  * for bitwise distributive transformations.
3008  */
3009 typedef ir_node* (*recursive_transform)(ir_node *n);
3010
3011 /**
3012  * makes use of distributive laws for and, or, eor
3013  *     and(a OP c, b OP c) -> and(a, b) OP c
3014  * note, might return a different op than n
3015  */
3016 static ir_node *transform_bitwise_distributive(ir_node *n,
3017                                                recursive_transform trans_func)
3018 {
3019         ir_node *oldn    = n;
3020         ir_node *a       = get_binop_left(n);
3021         ir_node *b       = get_binop_right(n);
3022         ir_op   *op      = get_irn_op(a);
3023         ir_op   *op_root = get_irn_op(n);
3024
3025         if(op != get_irn_op(b))
3026                 return n;
3027
3028         if (op == op_Conv) {
3029                 ir_node *a_op   = get_Conv_op(a);
3030                 ir_node *b_op   = get_Conv_op(b);
3031                 ir_mode *a_mode = get_irn_mode(a_op);
3032                 ir_mode *b_mode = get_irn_mode(b_op);
3033                 if(a_mode == b_mode && (mode_is_int(a_mode) || a_mode == mode_b)) {
3034                         ir_node *blk = get_irn_n(n, -1);
3035
3036                         n = exact_copy(n);
3037                         set_binop_left(n, a_op);
3038                         set_binop_right(n, b_op);
3039                         set_irn_mode(n, a_mode);
3040                         n = trans_func(n);
3041                         n = new_r_Conv(current_ir_graph, blk, n, get_irn_mode(oldn));
3042
3043                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_AND);
3044                         return n;
3045                 }
3046         }
3047
3048         if (op == op_Eor) {
3049                 /* nothing to gain here */
3050                 return n;
3051         }
3052
3053         if (op == op_Shrs || op == op_Shr || op == op_Shl
3054                         || op == op_And || op == op_Or || op == op_Eor) {
3055                 ir_node *a_left  = get_binop_left(a);
3056                 ir_node *a_right = get_binop_right(a);
3057                 ir_node *b_left  = get_binop_left(b);
3058                 ir_node *b_right = get_binop_right(b);
3059                 ir_node *c       = NULL;
3060                 ir_node *op1     = NULL;
3061                 ir_node *op2     = NULL;
3062
3063                 if (is_op_commutative(op)) {
3064                         if (a_left == b_left) {
3065                                 c   = a_left;
3066                                 op1 = a_right;
3067                                 op2 = b_right;
3068                         } else if(a_left == b_right) {
3069                                 c   = a_left;
3070                                 op1 = a_right;
3071                                 op2 = b_left;
3072                         } else if(a_right == b_left) {
3073                                 c   = a_right;
3074                                 op1 = a_left;
3075                                 op2 = b_right;
3076                         }
3077                 }
3078                 if(a_right == b_right) {
3079                         c   = a_right;
3080                         op1 = a_left;
3081                         op2 = b_left;
3082                 }
3083
3084                 if (c != NULL) {
3085                         /* (a sop c) & (b sop c) => (a & b) sop c */
3086                         ir_node *blk = get_irn_n(n, -1);
3087
3088                         ir_node *new_n = exact_copy(n);
3089                         set_binop_left(new_n, op1);
3090                         set_binop_right(new_n, op2);
3091                         new_n = trans_func(new_n);
3092
3093                         if(op_root == op_Eor && op == op_Or) {
3094                                 dbg_info  *dbgi = get_irn_dbg_info(n);
3095                                 ir_graph  *irg  = current_ir_graph;
3096                                 ir_mode   *mode = get_irn_mode(c);
3097
3098                                 c = new_rd_Not(dbgi, irg, blk, c, mode);
3099                                 n = new_rd_And(dbgi, irg, blk, new_n, c, mode);
3100                         } else {
3101                                 n = exact_copy(a);
3102                                 set_nodes_block(n, blk);
3103                                 set_binop_left(n, new_n);
3104                                 set_binop_right(n, c);
3105                                 add_identities(current_ir_graph->value_table, n);
3106                         }
3107
3108                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_SHIFT_AND);
3109                         return n;
3110                 }
3111         }
3112
3113         return n;
3114 }
3115
3116 /**
3117  * Transform an And.
3118  */
3119 static ir_node *transform_node_And(ir_node *n) {
3120         ir_node *c, *oldn = n;
3121         ir_node *a = get_And_left(n);
3122         ir_node *b = get_And_right(n);
3123         ir_mode *mode;
3124
3125         mode = get_irn_mode(n);
3126         HANDLE_BINOP_PHI(tarval_and, a, b, c, mode);
3127
3128         /* we can evaluate 2 Projs of the same Cmp */
3129         if (mode == mode_b && is_Proj(a) && is_Proj(b)) {
3130                 ir_node *pred_a = get_Proj_pred(a);
3131                 ir_node *pred_b = get_Proj_pred(b);
3132                 if (pred_a == pred_b) {
3133                         dbg_info *dbgi  = get_irn_dbg_info(n);
3134                         ir_node  *block = get_nodes_block(pred_a);
3135                         pn_Cmp pn_a     = get_Proj_proj(a);
3136                         pn_Cmp pn_b     = get_Proj_proj(b);
3137                         /* yes, we can simply calculate with pncs */
3138                         pn_Cmp new_pnc  = pn_a & pn_b;
3139
3140                         return new_rd_Proj(dbgi, current_ir_graph, block, pred_a, mode_b, new_pnc);
3141                 }
3142         }
3143         if (is_Or(a)) {
3144                 if (is_Not(b)) {
3145                         ir_node *op = get_Not_op(b);
3146                         if (is_And(op)) {
3147                                 ir_node *ba = get_And_left(op);
3148                                 ir_node *bb = get_And_right(op);
3149
3150                                 /* it's enough to test the following cases due to normalization! */
3151                                 if (get_Or_left(a) == ba && get_Or_right(a) == bb) {
3152                                         /* (a|b) & ~(a&b) = a^b */
3153                                         ir_node *block = get_nodes_block(n);
3154
3155                                         n = new_rd_Eor(get_irn_dbg_info(n), current_ir_graph, block, ba, bb, mode);
3156                                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_TO_EOR);
3157                                         return n;
3158                                 }
3159                         }
3160                 }
3161         }
3162         if (is_Or(b)) {
3163                 if (is_Not(a)) {
3164                         ir_node *op = get_Not_op(a);
3165                         if (is_And(op)) {
3166                                 ir_node *aa = get_And_left(op);
3167                                 ir_node *ab = get_And_right(op);
3168
3169                                 /* it's enough to test the following cases due to normalization! */
3170                                 if (get_Or_left(b) == aa && get_Or_right(b) == ab) {
3171                                         /* (a|b) & ~(a&b) = a^b */
3172                                         ir_node *block = get_nodes_block(n);
3173
3174                                         n = new_rd_Eor(get_irn_dbg_info(n), current_ir_graph, block, aa, ab, mode);
3175                                         DBG_OPT_ALGSIM1(oldn, a, b, n, FS_OPT_TO_EOR);
3176                                         return n;
3177                                 }
3178                         }
3179                 }
3180         }
3181         if (is_Eor(a)) {
3182                 ir_node *al = get_Eor_left(a);
3183                 ir_node *ar = get_Eor_right(a);
3184
3185                 if (al == b) {
3186                         /* (b ^ a) & b -> ~a & b */
3187                         dbg_info *dbg  = get_irn_dbg_info(n);
3188                         ir_node *block = get_nodes_block(n);
3189
3190                         ar = new_rd_Not(dbg, current_ir_graph, block, ar, mode);
3191                         n  = new_rd_And(dbg, current_ir_graph, block, ar, b, mode);
3192                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3193                         return n;
3194                 }
3195                 if (ar == b) {
3196                         /* (a ^ b) & b -> ~a & b */
3197                         dbg_info *dbg  = get_irn_dbg_info(n);
3198                         ir_node *block = get_nodes_block(n);
3199
3200                         al = new_rd_Not(dbg, current_ir_graph, block, al, mode);
3201                         n  = new_rd_And(dbg, current_ir_graph, block, al, b, mode);
3202                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3203                         return n;
3204                 }
3205         }
3206         if (is_Eor(b)) {
3207                 ir_node *bl = get_Eor_left(b);
3208                 ir_node *br = get_Eor_right(b);
3209
3210                 if (bl == a) {
3211                         /* a & (a ^ b) -> a & ~b */
3212                         dbg_info *dbg  = get_irn_dbg_info(n);
3213                         ir_node *block = get_nodes_block(n);
3214
3215                         br = new_rd_Not(dbg, current_ir_graph, block, br, mode);
3216                         n  = new_rd_And(dbg, current_ir_graph, block, br, a, mode);
3217                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3218                         return n;
3219                 }
3220                 if (br == a) {
3221                         /* a & (b ^ a) -> a & ~b */
3222                         dbg_info *dbg  = get_irn_dbg_info(n);
3223                         ir_node *block = get_nodes_block(n);
3224
3225                         bl = new_rd_Not(dbg, current_ir_graph, block, bl, mode);
3226                         n  = new_rd_And(dbg, current_ir_graph, block, bl, a, mode);
3227                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3228                         return n;
3229                 }
3230         }
3231         if (is_Not(a) && is_Not(b)) {
3232                 /* ~a & ~b = ~(a|b) */
3233                 ir_node *block = get_nodes_block(n);
3234                 ir_mode *mode = get_irn_mode(n);
3235
3236                 a = get_Not_op(a);
3237                 b = get_Not_op(b);
3238                 n = new_rd_Or(get_irn_dbg_info(n), current_ir_graph, block, a, b, mode);
3239                 n = new_rd_Not(get_irn_dbg_info(n), current_ir_graph, block, n, mode);
3240                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
3241                 return n;
3242         }
3243
3244         n = transform_bitwise_distributive(n, transform_node_And);
3245
3246         return n;
3247 }  /* transform_node_And */
3248
3249 /**
3250  * Transform an Eor.
3251  */
3252 static ir_node *transform_node_Eor(ir_node *n) {
3253         ir_node *c, *oldn = n;
3254         ir_node *a = get_Eor_left(n);
3255         ir_node *b = get_Eor_right(n);
3256         ir_mode *mode = get_irn_mode(n);
3257
3258         HANDLE_BINOP_PHI(tarval_eor, a, b, c, mode);
3259
3260         /* we can evaluate 2 Projs of the same Cmp */
3261         if (mode == mode_b && is_Proj(a) && is_Proj(b)) {
3262                 ir_node *pred_a = get_Proj_pred(a);
3263                 ir_node *pred_b = get_Proj_pred(b);
3264                 if(pred_a == pred_b) {
3265                         dbg_info *dbgi  = get_irn_dbg_info(n);
3266                         ir_node  *block = get_nodes_block(pred_a);
3267                         pn_Cmp pn_a     = get_Proj_proj(a);
3268                         pn_Cmp pn_b     = get_Proj_proj(b);
3269                         /* yes, we can simply calculate with pncs */
3270                         pn_Cmp new_pnc  = pn_a ^ pn_b;
3271
3272                         return new_rd_Proj(dbgi, current_ir_graph, block, pred_a, mode_b,
3273                                            new_pnc);
3274                 }
3275         }
3276
3277         if (a == b) {
3278                 /* a ^ a = 0 */
3279                 n = new_rd_Const(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1),
3280                                  mode, get_mode_null(mode));
3281                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_A_A);
3282         } else if (mode == mode_b &&
3283                         is_Proj(a) &&
3284                         is_Const(b) && is_Const_one(b) &&
3285                         is_Cmp(get_Proj_pred(a))) {
3286                 /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
3287                 n = new_r_Proj(current_ir_graph, get_irn_n(n, -1), get_Proj_pred(a),
3288                                 mode_b, get_negated_pnc(get_Proj_proj(a), mode));
3289
3290                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT_BOOL);
3291         } else if (is_Const(b)) {
3292                 if (is_Not(a)) { /* ~x ^ const -> x ^ ~const */
3293                         ir_node  *cnst   = new_Const(mode, tarval_not(get_Const_tarval(b)));
3294                         ir_node  *not_op = get_Not_op(a);
3295                         dbg_info *dbg    = get_irn_dbg_info(n);
3296                         ir_graph *irg    = current_ir_graph;
3297                         ir_node  *block  = get_nodes_block(n);
3298                         ir_mode  *mode   = get_irn_mode(n);
3299                         n = new_rd_Eor(dbg, irg, block, not_op, cnst, mode);
3300                         return n;
3301                 } else if (is_Const_all_one(b)) { /* x ^ 1...1 -> ~1 */
3302                         n = new_r_Not(current_ir_graph, get_nodes_block(n), a, mode);
3303                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
3304                 }
3305         } else {
3306                 n = transform_bitwise_distributive(n, transform_node_Eor);
3307         }
3308
3309         return n;
3310 }  /* transform_node_Eor */
3311
3312 /**
3313  * Transform a Not.
3314  */
3315 static ir_node *transform_node_Not(ir_node *n) {
3316         ir_node *c, *oldn = n;
3317         ir_node *a    = get_Not_op(n);
3318         ir_mode *mode = get_irn_mode(n);
3319
3320         HANDLE_UNOP_PHI(tarval_not,a,c);
3321
3322         /* check for a boolean Not */
3323         if (mode == mode_b &&
3324                         is_Proj(a) &&
3325                         is_Cmp(get_Proj_pred(a))) {
3326                 /* We negate a Cmp. The Cmp has the negated result anyways! */
3327                 n = new_r_Proj(current_ir_graph, get_irn_n(n, -1), get_Proj_pred(a),
3328                                 mode_b, get_negated_pnc(get_Proj_proj(a), mode_b));
3329                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_CMP);
3330                 return n;
3331         }
3332         if  (is_Eor(a)) {
3333                 ir_node *eor_b = get_Eor_right(a);
3334                 if (is_Const(eor_b)) { /* ~(x ^ const) -> x ^ ~const */
3335                         ir_node  *cnst  = new_Const(mode, tarval_not(get_Const_tarval(eor_b)));
3336                         ir_node  *eor_a = get_Eor_left(a);
3337                         dbg_info *dbg   = get_irn_dbg_info(n);
3338                         ir_graph *irg   = current_ir_graph;
3339                         ir_node  *block = get_nodes_block(n);
3340                         ir_mode  *mode  = get_irn_mode(n);
3341                         n = new_rd_Eor(dbg, irg, block, eor_a, cnst, mode);
3342                         return n;
3343                 }
3344         }
3345         if (get_mode_arithmetic(mode) == irma_twos_complement) {
3346                 if (is_Minus(a)) { /* ~-x -> x + -1 */
3347                         dbg_info *dbg   = get_irn_dbg_info(n);
3348                         ir_graph *irg   = current_ir_graph;
3349                         ir_node  *block = get_nodes_block(n);
3350                         ir_node  *add_l = get_Minus_op(a);
3351                         ir_node  *add_r = new_rd_Const(dbg, irg, block, mode, get_mode_minus_one(mode));
3352                         n = new_rd_Add(dbg, irg, block, add_l, add_r, mode);
3353                 } else if (is_Add(a)) {
3354                         ir_node *add_r = get_Add_right(a);
3355                         if (is_Const(add_r) && is_Const_all_one(add_r)) {
3356                                 /* ~(x + -1) = -x */
3357                                 ir_node *op = get_Add_left(a);
3358                                 ir_node *blk = get_irn_n(n, -1);
3359                                 n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, op, get_irn_mode(n));
3360                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_MINUS_1);
3361                         }
3362                 }
3363         }
3364         return n;
3365 }  /* transform_node_Not */
3366
3367 /**
3368  * Transform a Minus.
3369  * Optimize:
3370  *   -(~x) = x + 1
3371  *   -(a-b) = b - a
3372  *   -(a >>u (size-1)) = a >>s (size-1)
3373  *   -(a >>s (size-1)) = a >>u (size-1)
3374  *   -(a * const) -> a * -const
3375  */
3376 static ir_node *transform_node_Minus(ir_node *n) {
3377         ir_node *c, *oldn = n;
3378         ir_node *a = get_Minus_op(n);
3379         ir_mode *mode;
3380
3381         HANDLE_UNOP_PHI(tarval_neg,a,c);
3382
3383         mode = get_irn_mode(a);
3384         if (get_mode_arithmetic(mode) == irma_twos_complement) {
3385                 /* the following rules are only to twos-complement */
3386                 if (is_Not(a)) {
3387                         /* -(~x) = x + 1 */
3388                         ir_node *op   = get_Not_op(a);
3389                         tarval *tv    = get_mode_one(mode);
3390                         ir_node *blk  = get_irn_n(n, -1);
3391                         ir_node *c    = new_r_Const(current_ir_graph, blk, mode, tv);
3392                         n = new_rd_Add(get_irn_dbg_info(n), current_ir_graph, blk, op, c, mode);
3393                         DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_NOT);
3394                         return n;
3395                 }
3396                 if (is_Shr(a)) {
3397                         ir_node *c = get_Shr_right(a);
3398
3399                         if (is_Const(c)) {
3400                                 tarval *tv = get_Const_tarval(c);
3401
3402                                 if (tarval_is_long(tv) && get_tarval_long(tv) == (int) get_mode_size_bits(mode) - 1) {
3403                                         /* -(a >>u (size-1)) = a >>s (size-1) */
3404                                         ir_node *v = get_Shr_left(a);
3405
3406                                         n = new_rd_Shrs(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1), v, c, mode);
3407                                         DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_PREDICATE);
3408                                         return n;
3409                                 }
3410                         }
3411                 }
3412                 if (is_Shrs(a)) {
3413                         ir_node *c = get_Shrs_right(a);
3414
3415                         if (is_Const(c)) {
3416                                 tarval *tv = get_Const_tarval(c);
3417
3418                                 if (tarval_is_long(tv) && get_tarval_long(tv) == (int) get_mode_size_bits(mode) - 1) {
3419                                         /* -(a >>s (size-1)) = a >>u (size-1) */
3420                                         ir_node *v = get_Shrs_left(a);
3421
3422                                         n = new_rd_Shr(get_irn_dbg_info(n), current_ir_graph, get_irn_n(n, -1), v, c, mode);
3423                                         DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_PREDICATE);
3424                                         return n;
3425                                 }
3426                         }
3427                 }
3428         }
3429         if (is_Sub(a)) {
3430                 /* - (a-b) = b - a */
3431                 ir_node *la  = get_Sub_left(a);
3432                 ir_node *ra  = get_Sub_right(a);
3433                 ir_node *blk = get_irn_n(n, -1);
3434
3435                 n = new_rd_Sub(get_irn_dbg_info(n), current_ir_graph, blk, ra, la, mode);
3436                 DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_SUB);
3437                 return n;
3438         }
3439
3440         if (is_Mul(a)) { /* -(a * const) -> a * -const */
3441                 ir_node *mul_l = get_Mul_left(a);
3442                 ir_node *mul_r = get_Mul_right(a);
3443                 if (is_Const(mul_r)) {
3444                         tarval   *tv    = tarval_neg(get_Const_tarval(mul_r));
3445                         if(tv != tarval_bad) {
3446                                 ir_node  *cnst  = new_Const(mode, tv);
3447                                 dbg_info *dbg   = get_irn_dbg_info(a);
3448                                 ir_graph *irg   = current_ir_graph;
3449                                 ir_node  *block = get_nodes_block(a);
3450                                 n = new_rd_Mul(dbg, irg, block, mul_l, cnst, mode);
3451                                 DBG_OPT_ALGSIM2(oldn, a, n, FS_OPT_MINUS_MUL_C);
3452                                 return n;
3453                         }
3454                 }
3455         }
3456
3457         return n;
3458 }  /* transform_node_Minus */
3459
3460 /**
3461  * Transform a Cast_type(Const) into a new Const_type
3462  */
3463 static ir_node *transform_node_Cast(ir_node *n) {
3464         ir_node *oldn = n;
3465         ir_node *pred = get_Cast_op(n);
3466         ir_type *tp = get_irn_type(n);
3467
3468         if (is_Const(pred) && get_Const_type(pred) != tp) {
3469                 n = new_rd_Const_type(NULL, current_ir_graph, get_irn_n(pred, -1), get_irn_mode(pred),
3470                         get_Const_tarval(pred), tp);
3471                 DBG_OPT_CSTEVAL(oldn, n);
3472         } else if (is_SymConst(pred) && get_SymConst_value_type(pred) != tp) {
3473                 n = new_rd_SymConst_type(NULL, current_ir_graph, get_irn_n(pred, -1), get_irn_mode(pred),
3474                         get_SymConst_symbol(pred), get_SymConst_kind(pred), tp);
3475                 DBG_OPT_CSTEVAL(oldn, n);
3476         }
3477
3478         return n;
3479 }  /* transform_node_Cast */
3480
3481 /**
3482  * Transform a Proj(Div) with a non-zero value.
3483  * Removes the exceptions and routes the memory to the NoMem node.
3484  */
3485 static ir_node *transform_node_Proj_Div(ir_node *proj) {
3486         ir_node *div = get_Proj_pred(proj);
3487         ir_node *b   = get_Div_right(div);
3488         ir_node *confirm, *res, *new_mem;
3489         long proj_nr;
3490
3491         if (value_not_zero(b, &confirm)) {
3492                 /* div(x, y) && y != 0 */
3493                 if (confirm == NULL) {
3494                         /* we are sure we have a Const != 0 */
3495                         new_mem = get_Div_mem(div);
3496                         if (is_Pin(new_mem))
3497                                 new_mem = get_Pin_op(new_mem);
3498                         set_Div_mem(div, new_mem);
3499                         set_irn_pinned(div, op_pin_state_floats);
3500                 }
3501
3502                 proj_nr = get_Proj_proj(proj);
3503                 switch (proj_nr) {
3504                 case pn_Div_X_regular:
3505                         return new_r_Jmp(current_ir_graph, get_irn_n(div, -1));
3506
3507                 case pn_Div_X_except:
3508                         /* we found an exception handler, remove it */
3509                         DBG_OPT_EXC_REM(proj);
3510                         return new_Bad();
3511
3512                 case pn_Div_M:
3513                         res = get_Div_mem(div);
3514                         new_mem = get_irg_no_mem(current_ir_graph);
3515
3516                         if (confirm) {
3517                                 /* This node can only float up to the Confirm block */
3518                                 new_mem = new_r_Pin(current_ir_graph, get_nodes_block(confirm), new_mem);
3519                         }
3520                         set_irn_pinned(div, op_pin_state_floats);
3521                         /* this is a Div without exception, we can remove the memory edge */
3522                         set_Div_mem(div, new_mem);
3523                         return res;
3524                 }
3525         }
3526         return proj;
3527 }  /* transform_node_Proj_Div */
3528
3529 /**
3530  * Transform a Proj(Mod) with a non-zero value.
3531  * Removes the exceptions and routes the memory to the NoMem node.
3532  */
3533 static ir_node *transform_node_Proj_Mod(ir_node *proj) {
3534         ir_node *mod = get_Proj_pred(proj);
3535         ir_node *b   = get_Mod_right(mod);
3536         ir_node *confirm, *res, *new_mem;
3537         long proj_nr;
3538
3539         if (value_not_zero(b, &confirm)) {
3540                 /* mod(x, y) && y != 0 */
3541                 proj_nr = get_Proj_proj(proj);
3542
3543                 if (confirm == NULL) {
3544                         /* we are sure we have a Const != 0 */
3545                         new_mem = get_Mod_mem(mod);
3546                         if (is_Pin(new_mem))
3547                                 new_mem = get_Pin_op(new_mem);
3548                         set_Mod_mem(mod, new_mem);
3549                         set_irn_pinned(mod, op_pin_state_floats);
3550                 }
3551
3552                 switch (proj_nr) {
3553
3554                 case pn_Mod_X_regular:
3555                         return new_r_Jmp(current_ir_graph, get_irn_n(mod, -1));
3556
3557                 case pn_Mod_X_except:
3558                         /* we found an exception handler, remove it */
3559                         DBG_OPT_EXC_REM(proj);
3560                         return new_Bad();
3561
3562                 case pn_Mod_M:
3563                         res = get_Mod_mem(mod);
3564                         new_mem = get_irg_no_mem(current_ir_graph);
3565
3566                         if (confirm) {
3567                                 /* This node can only float up to the Confirm block */
3568                                 new_mem = new_r_Pin(current_ir_graph, get_nodes_block(confirm), new_mem);
3569                         }
3570                         /* this is a Mod without exception, we can remove the memory edge */
3571                         set_Mod_mem(mod, new_mem);
3572                         return res;
3573                 case pn_Mod_res:
3574                         if (get_Mod_left(mod) == b) {
3575                                 /* a % a = 0 if a != 0 */
3576                                 ir_mode *mode = get_irn_mode(proj);
3577                                 ir_node *res  = new_Const(mode, get_mode_null(mode));
3578
3579                                 DBG_OPT_CSTEVAL(mod, res);
3580                                 return res;
3581                         }
3582                 }
3583         }
3584         return proj;
3585 }  /* transform_node_Proj_Mod */
3586
3587 /**
3588  * Transform a Proj(DivMod) with a non-zero value.
3589  * Removes the exceptions and routes the memory to the NoMem node.
3590  */
3591 static ir_node *transform_node_Proj_DivMod(ir_node *proj) {
3592         ir_node *divmod = get_Proj_pred(proj);
3593         ir_node *b      = get_DivMod_right(divmod);
3594         ir_node *confirm, *res, *new_mem;
3595         long proj_nr;
3596
3597         if (value_not_zero(b, &confirm)) {
3598                 /* DivMod(x, y) && y != 0 */
3599                 proj_nr = get_Proj_proj(proj);
3600
3601                 if (confirm == NULL) {
3602                         /* we are sure we have a Const != 0 */
3603                         new_mem = get_DivMod_mem(divmod);
3604                         if (is_Pin(new_mem))
3605                                 new_mem = get_Pin_op(new_mem);
3606                         set_DivMod_mem(divmod, new_mem);
3607                         set_irn_pinned(divmod, op_pin_state_floats);
3608                 }
3609
3610                 switch (proj_nr) {
3611
3612                 case pn_DivMod_X_regular:
3613                         return new_r_Jmp(current_ir_graph, get_irn_n(divmod, -1));
3614
3615                 case pn_DivMod_X_except:
3616                         /* we found an exception handler, remove it */
3617                         DBG_OPT_EXC_REM(proj);
3618                         return new_Bad();
3619
3620                 case pn_DivMod_M:
3621                         res = get_DivMod_mem(divmod);
3622                         new_mem = get_irg_no_mem(current_ir_graph);
3623
3624                         if (confirm) {
3625                                 /* This node can only float up to the Confirm block */
3626                                 new_mem = new_r_Pin(current_ir_graph, get_nodes_block(confirm), new_mem);
3627                         }
3628                         /* this is a DivMod without exception, we can remove the memory edge */
3629                         set_DivMod_mem(divmod, new_mem);
3630                         return res;
3631
3632                 case pn_DivMod_res_mod:
3633                         if (get_DivMod_left(divmod) == b) {
3634                                 /* a % a = 0 if a != 0 */
3635                                 ir_mode *mode = get_irn_mode(proj);
3636                                 ir_node *res  = new_Const(mode, get_mode_null(mode));
3637
3638                                 DBG_OPT_CSTEVAL(divmod, res);
3639                                 return res;
3640                         }
3641                 }
3642         }
3643         return proj;
3644 }  /* transform_node_Proj_DivMod */
3645
3646 /**
3647  * Optimizes jump tables (CondIs or CondIu) by removing all impossible cases.
3648  */
3649 static ir_node *transform_node_Proj_Cond(ir_node *proj) {
3650         if (get_opt_unreachable_code()) {
3651                 ir_node *n = get_Proj_pred(proj);
3652                 ir_node *b = get_Cond_selector(n);
3653
3654                 if (mode_is_int(get_irn_mode(b))) {
3655                         tarval *tb = value_of(b);
3656
3657                         if (tb != tarval_bad) {
3658                                 /* we have a constant switch */
3659                                 long num = get_Proj_proj(proj);
3660
3661                                 if (num != get_Cond_defaultProj(n)) { /* we cannot optimize default Proj's yet */
3662                                         if (get_tarval_long(tb) == num) {
3663                                                 /* Do NOT create a jump here, or we will have 2 control flow ops
3664                                                  * in a block. This case is optimized away in optimize_cf(). */
3665                                                 return proj;
3666                                         } else {
3667                                                 /* this case will NEVER be taken, kill it */
3668                                                 return new_Bad();
3669                                         }
3670                                 }
3671                         }
3672                 }
3673         }
3674         return proj;
3675 }  /* transform_node_Proj_Cond */
3676
3677 /**
3678  * Create a 0 constant of given mode.
3679  */
3680 static ir_node *create_zero_const(ir_mode *mode) {
3681         tarval   *tv    = get_mode_null(mode);
3682         ir_node  *cnst  = new_Const(mode, tv);
3683
3684         return cnst;
3685 }
3686
3687 /* the order of the values is important! */
3688 typedef enum const_class {
3689         const_const = 0,
3690         const_like  = 1,
3691         const_other = 2
3692 } const_class;
3693
3694 static const_class classify_const(const ir_node* n)
3695 {
3696         if (is_Const(n))         return const_const;
3697         if (is_irn_constlike(n)) return const_like;
3698         return const_other;
3699 }
3700
3701 /**
3702  * Determines whether r is more constlike or has a larger index (in that order)
3703  * than l.
3704  */
3705 static int operands_are_normalized(const ir_node *l, const ir_node *r)
3706 {
3707         const const_class l_order = classify_const(l);
3708         const const_class r_order = classify_const(r);
3709         return
3710                 l_order > r_order ||
3711                 (l_order == r_order && get_irn_idx(l) <= get_irn_idx(r));
3712 }
3713
3714 /**
3715  * Normalizes and optimizes Cmp nodes.
3716  */
3717 static ir_node *transform_node_Proj_Cmp(ir_node *proj) {
3718         ir_node      *n      = get_Proj_pred(proj);
3719         ir_node      *left   = get_Cmp_left(n);
3720         ir_node      *right  = get_Cmp_right(n);
3721         tarval      *tv      = NULL;
3722         int          changed = 0;
3723         ir_mode     *mode    = NULL;
3724         long         proj_nr = get_Proj_proj(proj);
3725
3726         /* we can evaluate some cases directly */
3727         switch (proj_nr) {
3728         case pn_Cmp_False:
3729                 return new_Const(mode_b, get_tarval_b_false());
3730         case pn_Cmp_True:
3731                 return new_Const(mode_b, get_tarval_b_true());
3732         case pn_Cmp_Leg:
3733                 if (!mode_is_float(get_irn_mode(left)))
3734                         return new_Const(mode_b, get_tarval_b_true());
3735                 break;
3736         default:
3737                 break;
3738         }
3739
3740         /* remove Casts of both sides */
3741         left  = skip_Cast(left);
3742         right = skip_Cast(right);
3743
3744         /* Remove unnecessary conversions */
3745         /* TODO handle constants */
3746         if (is_Conv(left) && is_Conv(right)) {
3747                 ir_mode *mode        = get_irn_mode(left);
3748                 ir_node *op_left     = get_Conv_op(left);
3749                 ir_node *op_right    = get_Conv_op(right);
3750                 ir_mode *mode_left   = get_irn_mode(op_left);
3751                 ir_mode *mode_right  = get_irn_mode(op_right);
3752
3753                 if (smaller_mode(mode_left, mode) && smaller_mode(mode_right, mode)
3754                                 && mode_left != mode_b && mode_right != mode_b) {
3755                         ir_graph *irg   = current_ir_graph;
3756                         ir_node  *block = get_nodes_block(n);
3757
3758                         if (mode_left == mode_right) {
3759                                 left  = op_left;
3760                                 right = op_right;
3761                                 changed |= 1;
3762                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV_CONV);
3763                         } else if (smaller_mode(mode_left, mode_right)) {
3764                                 left  = new_r_Conv(irg, block, op_left, mode_right);
3765                                 right = op_right;
3766                                 changed |= 1;
3767                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
3768                         } else if (smaller_mode(mode_right, mode_left)) {
3769                                 left  = op_left;
3770                                 right = new_r_Conv(irg, block, op_right, mode_left);
3771                                 changed |= 1;
3772                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
3773                         }
3774                 }
3775         }
3776
3777         /* remove operation on both sides if possible */
3778         if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
3779                 /*
3780                  * The following operations are NOT safe for floating point operations, for instance
3781                  * 1.0 + inf == 2.0 + inf, =/=> x == y
3782                  */
3783                 if (mode_is_int(get_irn_mode(left))) {
3784                         unsigned lop = get_irn_opcode(left);
3785
3786                         if (lop == get_irn_opcode(right)) {
3787                                 ir_node *ll, *lr, *rl, *rr;
3788
3789                                 /* same operation on both sides, try to remove */
3790                                 switch (lop) {
3791                                 case iro_Not:
3792                                 case iro_Minus:
3793                                         /* ~a CMP ~b => a CMP b, -a CMP -b ==> a CMP b */
3794                                         left  = get_unop_op(left);
3795                                         right = get_unop_op(right);
3796                                         changed |= 1;
3797                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3798                                         break;
3799                                 case iro_Add:
3800                                         ll = get_Add_left(left);
3801                                         lr = get_Add_right(left);
3802                                         rl = get_Add_left(right);
3803                                         rr = get_Add_right(right);
3804
3805                                         if (ll == rl) {
3806                                                 /* X + a CMP X + b ==> a CMP b */
3807                                                 left  = lr;
3808                                                 right = rr;
3809                                                 changed |= 1;
3810                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3811                                         } else if (ll == rr) {
3812                                                 /* X + a CMP b + X ==> a CMP b */
3813                                                 left  = lr;
3814                                                 right = rl;
3815                                                 changed |= 1;
3816                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3817                                         } else if (lr == rl) {
3818                                                 /* a + X CMP X + b ==> a CMP b */
3819                                                 left  = ll;
3820                                                 right = rr;
3821                                                 changed |= 1;
3822                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3823                                         } else if (lr == rr) {
3824                                                 /* a + X CMP b + X ==> a CMP b */
3825                                                 left  = ll;
3826                                                 right = rl;
3827                                                 changed |= 1;
3828                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3829                                         }
3830                                         break;
3831                                 case iro_Sub:
3832                                         ll = get_Sub_left(left);
3833                                         lr = get_Sub_right(left);
3834                                         rl = get_Sub_left(right);
3835                                         rr = get_Sub_right(right);
3836
3837                                         if (ll == rl) {
3838                                                 /* X - a CMP X - b ==> a CMP b */
3839                                                 left  = lr;
3840                                                 right = rr;
3841                                                 changed |= 1;
3842                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3843                                         } else if (lr == rr) {
3844                                                 /* a - X CMP b - X ==> a CMP b */
3845                                                 left  = ll;
3846                                                 right = rl;
3847                                                 changed |= 1;
3848                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3849                                         }
3850                                         break;
3851                                 case iro_Rot:
3852                                         if (get_Rot_right(left) == get_Rot_right(right)) {
3853                                                 /* a ROT X CMP b ROT X ==> a CMP b */
3854                                                 left  = get_Rot_left(left);
3855                                                 right = get_Rot_left(right);
3856                                                 changed |= 1;
3857                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3858                                         }
3859                                         break;
3860                                 default:
3861                                         break;
3862                                 }
3863                         }
3864
3865                         /* X+A == A, A+X == A, A-X == A -> X == 0 */
3866                         if (is_Add(left) || is_Sub(left)) {
3867                                 ir_node *ll = get_binop_left(left);
3868                                 ir_node *lr = get_binop_right(left);
3869
3870                                 if (lr == right && is_Add(left)) {
3871                                         ir_node *tmp = ll;
3872                                         ll = lr;
3873                                         lr = tmp;
3874                                 }
3875                                 if (ll == right) {
3876                                         left     = lr;
3877                                         right    = create_zero_const(get_irn_mode(left));
3878                                         changed |= 1;
3879                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3880                                 }
3881                         }
3882                         if (is_Add(right) || is_Sub(right)) {
3883                                 ir_node *rl = get_binop_left(right);
3884                                 ir_node *rr = get_binop_right(right);
3885
3886                                 if (rr == left && is_Add(right)) {
3887                                         ir_node *tmp = rl;
3888                                         rl = rr;
3889                                         rr = tmp;
3890                                 }
3891                                 if (rl == left) {
3892                                         left     = rr;
3893                                         right    = create_zero_const(get_irn_mode(left));
3894                                         changed |= 1;
3895                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_OP);
3896                                 }
3897                         }
3898                 }  /* mode_is_int(...) */
3899         }  /* proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg */
3900
3901         /* replace mode_b compares with ands/ors */
3902         if (get_irn_mode(left) == mode_b) {
3903                 ir_graph *irg   = current_ir_graph;
3904                 ir_node  *block = get_nodes_block(n);
3905                 ir_node  *bres;
3906
3907                 switch (proj_nr) {
3908                         case pn_Cmp_Le: bres = new_r_Or( irg, block, new_r_Not(irg, block, left, mode_b), right, mode_b); break;
3909                         case pn_Cmp_Lt: bres = new_r_And(irg, block, new_r_Not(irg, block, left, mode_b), right, mode_b); break;
3910                         case pn_Cmp_Ge: bres = new_r_Or( irg, block, left, new_r_Not(irg, block, right, mode_b), mode_b); break;
3911                         case pn_Cmp_Gt: bres = new_r_And(irg, block, left, new_r_Not(irg, block, right, mode_b), mode_b); break;
3912                         case pn_Cmp_Lg: bres = new_r_Eor(irg, block, left, right, mode_b); break;
3913                         case pn_Cmp_Eq: bres = new_r_Not(irg, block, new_r_Eor(irg, block, left, right, mode_b), mode_b); break;
3914                         default: bres = NULL;
3915                 }
3916                 if (bres) {
3917                         DBG_OPT_ALGSIM0(n, bres, FS_OPT_CMP_TO_BOOL);
3918                         return bres;
3919                 }
3920         }
3921
3922         /*
3923          * First step: normalize the compare op
3924          * by placing the constant on the right side
3925          * or moving the lower address node to the left.
3926          */
3927         if (!operands_are_normalized(left, right)) {
3928                 ir_node *t = left;
3929
3930                 left  = right;
3931                 right = t;
3932
3933                 proj_nr = get_inversed_pnc(proj_nr);
3934                 changed |= 1;
3935         }
3936
3937         /*
3938          * Second step: Try to reduce the magnitude
3939          * of a constant. This may help to generate better code
3940          * later and may help to normalize more compares.
3941          * Of course this is only possible for integer values.
3942          */
3943         if (is_Const(right)) {
3944                 mode = get_irn_mode(right);
3945                 tv = get_Const_tarval(right);
3946
3947                 /* TODO extend to arbitrary constants */
3948                 if (is_Conv(left) && tarval_is_null(tv)) {
3949                         ir_node *op      = get_Conv_op(left);
3950                         ir_mode *op_mode = get_irn_mode(op);
3951
3952                         /*
3953                          * UpConv(x) REL 0  ==> x REL 0
3954                          */
3955                         if (get_mode_size_bits(mode) > get_mode_size_bits(op_mode) &&
3956                             ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) ||
3957                                  mode_is_signed(mode) || !mode_is_signed(op_mode))) {
3958                                 tv   = get_mode_null(op_mode);
3959                                 left = op;
3960                                 mode = op_mode;
3961                                 changed |= 2;
3962                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CONV);
3963                         }
3964                 }
3965
3966                 if (tv != tarval_bad) {
3967                         /* the following optimization is possible on modes without Overflow
3968                          * on Unary Minus or on == and !=:
3969                          * -a CMP c  ==>  a swap(CMP) -c
3970                          *
3971                          * Beware: for two-complement Overflow may occur, so only == and != can
3972                          * be optimized, see this:
3973                          * -MININT < 0 =/=> MININT > 0 !!!
3974                          */
3975                         if (is_Minus(left) &&
3976                                 (!mode_overflow_on_unary_Minus(mode) ||
3977                                 (mode_is_int(mode) && (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg)))) {
3978                                 tv = tarval_neg(tv);
3979
3980                                 if (tv != tarval_bad) {
3981                                         left = get_Minus_op(left);
3982                                         proj_nr = get_inversed_pnc(proj_nr);
3983                                         changed |= 2;
3984                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
3985                                 }
3986                         } else if (is_Not(left) && (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg)) {
3987                                 /* Not(a) ==/!= c  ==>  a ==/!= Not(c) */
3988                                 tv = tarval_not(tv);
3989
3990                                 if (tv != tarval_bad) {
3991                                         left = get_Not_op(left);
3992                                         changed |= 2;
3993                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
3994                                 }
3995                         }
3996
3997                         /* for integer modes, we have more */
3998                         if (mode_is_int(mode)) {
3999                                 /* Ne includes Unordered which is not possible on integers.
4000                                  * However, frontends often use this wrong, so fix it here */
4001                                 if (proj_nr & pn_Cmp_Uo) {
4002                                         proj_nr &= ~pn_Cmp_Uo;
4003                                         set_Proj_proj(proj, proj_nr);
4004                                 }
4005
4006                                 /* c > 0 : a < c  ==>  a <= (c-1)    a >= c  ==>  a > (c-1) */
4007                                 if ((proj_nr == pn_Cmp_Lt || proj_nr == pn_Cmp_Ge) &&
4008                                         tarval_cmp(tv, get_mode_null(mode)) == pn_Cmp_Gt) {
4009                                         tv = tarval_sub(tv, get_mode_one(mode));
4010
4011                                         if (tv != tarval_bad) {
4012                                                 proj_nr ^= pn_Cmp_Eq;
4013                                                 changed |= 2;
4014                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4015                                         }
4016                                 }
4017                                 /* c < 0 : a > c  ==>  a >= (c+1)    a <= c  ==>  a < (c+1) */
4018                                 else if ((proj_nr == pn_Cmp_Gt || proj_nr == pn_Cmp_Le) &&
4019                                         tarval_cmp(tv, get_mode_null(mode)) == pn_Cmp_Lt) {
4020                                         tv = tarval_add(tv, get_mode_one(mode));
4021
4022                                         if (tv != tarval_bad) {
4023                                                 proj_nr ^= pn_Cmp_Eq;
4024                                                 changed |= 2;
4025                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4026                                         }
4027                                 }
4028
4029                                 /* the following reassociations work only for == and != */
4030                                 if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
4031
4032 #if 0 /* Might be not that good in general */
4033                                         /* a-b == 0  ==>  a == b,  a-b != 0  ==>  a != b */
4034                                         if (tarval_is_null(tv) && is_Sub(left)) {
4035                                                 right = get_Sub_right(left);
4036                                                 left  = get_Sub_left(left);
4037
4038                                                 tv = value_of(right);
4039                                                 changed = 1;
4040                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4041                                         }
4042 #endif
4043
4044                                         if (tv != tarval_bad) {
4045                                                 /* a-c1 == c2  ==>  a == c2+c1,  a-c1 != c2  ==>  a != c2+c1 */
4046                                                 if (is_Sub(left)) {
4047                                                         ir_node *c1 = get_Sub_right(left);
4048                                                         tarval *tv2 = value_of(c1);
4049
4050                                                         if (tv2 != tarval_bad) {
4051                                                                 tv2 = tarval_add(tv, value_of(c1));
4052
4053                                                                 if (tv2 != tarval_bad) {
4054                                                                         left    = get_Sub_left(left);
4055                                                                         tv      = tv2;
4056                                                                         changed |= 2;
4057                                                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4058                                                                 }
4059                                                         }
4060                                                 }
4061                                                 /* a+c1 == c2  ==>  a == c2-c1,  a+c1 != c2  ==>  a != c2-c1 */
4062                                                 else if (is_Add(left)) {
4063                                                         ir_node *a_l = get_Add_left(left);
4064                                                         ir_node *a_r = get_Add_right(left);
4065                                                         ir_node *a;
4066                                                         tarval *tv2;
4067
4068                                                         if (is_Const(a_l)) {
4069                                                                 a = a_r;
4070                                                                 tv2 = value_of(a_l);
4071                                                         } else {
4072                                                                 a = a_l;
4073                                                                 tv2 = value_of(a_r);
4074                                                         }
4075
4076                                                         if (tv2 != tarval_bad) {
4077                                                                 tv2 = tarval_sub(tv, tv2);
4078
4079                                                                 if (tv2 != tarval_bad) {
4080                                                                         left    = a;
4081                                                                         tv      = tv2;
4082                                                                         changed |= 2;
4083                                                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4084                                                                 }
4085                                                         }
4086                                                 }
4087                                                 /* -a == c ==> a == -c, -a != c ==> a != -c */
4088                                                 else if (is_Minus(left)) {
4089                                                         tarval *tv2 = tarval_sub(get_mode_null(mode), tv);
4090
4091                                                         if (tv2 != tarval_bad) {
4092                                                                 left    = get_Minus_op(left);
4093                                                                 tv      = tv2;
4094                                                                 changed |= 2;
4095                                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_OP_C);
4096                                                         }
4097                                                 }
4098                                         }
4099                                 } /* == or != */
4100                                 /* the following reassociations work only for <= */
4101                                 else if (proj_nr == pn_Cmp_Le || proj_nr == pn_Cmp_Lt) {
4102                                         if (tv != tarval_bad) {
4103                                                 /* c >= 0 : Abs(a) <= c  ==>  (unsigned)(a + c) <= 2*c */
4104                                                 if (get_irn_op(left) == op_Abs) { // TODO something is missing here
4105                                                 }
4106                                         }
4107                                 }
4108                         } /* mode_is_int */
4109
4110                         if (proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) {
4111                                 switch (get_irn_opcode(left)) {
4112                                         ir_node *c1;
4113
4114                                 case iro_And:
4115                                         c1 = get_And_right(left);
4116                                         if (is_Const(c1)) {
4117                                                 /*
4118                                                  * And(x, C1) == C2 ==> FALSE if C2 & C1 != C2
4119                                                  * And(x, C1) != C2 ==> TRUE if C2 & C1 != C2
4120                                                  */
4121                                                 tarval *mask = tarval_and(get_Const_tarval(c1), tv);
4122                                                 if (mask != tv) {
4123                                                         /* TODO: move to constant evaluation */
4124                                                         tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
4125                                                         c1 = new_Const(mode_b, tv);
4126                                                         DBG_OPT_CSTEVAL(proj, c1);
4127                                                         return c1;
4128                                                 }
4129
4130                                                 if (tarval_is_single_bit(tv)) {
4131                                                         /*
4132                                                          * optimization for AND:
4133                                                          * Optimize:
4134                                                          *   And(x, C) == C  ==>  And(x, C) != 0
4135                                                          *   And(x, C) != C  ==>  And(X, C) == 0
4136                                                          *
4137                                                          * if C is a single Bit constant.
4138                                                          */
4139
4140                                                         /* check for Constant's match. We have check hare the tarvals,
4141                                                            because our const might be changed */
4142                                                         if (get_Const_tarval(c1) == tv) {
4143                                                                 /* fine: do the transformation */
4144                                                                 tv = get_mode_null(get_tarval_mode(tv));
4145                                                                 proj_nr ^= pn_Cmp_Leg;
4146                                                                 changed |= 2;
4147                                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_CNST_MAGN);
4148                                                         }
4149                                                 }
4150                                         }
4151                                         break;
4152                                 case iro_Or:
4153                                         c1 = get_Or_right(left);
4154                                         if (is_Const(c1) && tarval_is_null(tv)) {
4155                                                 /*
4156                                                  * Or(x, C) == 0  && C != 0 ==> FALSE
4157                                                  * Or(x, C) != 0  && C != 0 ==> TRUE
4158                                                  */
4159                                                 if (! tarval_is_null(get_Const_tarval(c1))) {
4160                                                         /* TODO: move to constant evaluation */
4161                                                         tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
4162                                                         c1 = new_Const(mode_b, tv);
4163                                                         DBG_OPT_CSTEVAL(proj, c1);
4164                                                         return c1;
4165                                                 }
4166                                         }
4167                                         break;
4168                                 case iro_Shl:
4169                                         /*
4170                                          * optimize x << c1 == c into x & (-1 >>u c1) == c >> c1  if  c & (-1 << c1) == c
4171                                          *                             FALSE                       else
4172                                          * optimize x << c1 != c into x & (-1 >>u c1) != c >> c1  if  c & (-1 << c1) == c
4173                                          *                             TRUE                        else
4174                                          */
4175                                         c1 = get_Shl_right(left);
4176                                         if (is_Const(c1)) {
4177                                                 tarval  *tv1    = get_Const_tarval(c1);
4178                                                 ir_mode *mode   = get_irn_mode(left);
4179                                                 tarval  *minus1 = get_mode_all_one(mode);
4180                                                 tarval  *amask  = tarval_shr(minus1, tv1);
4181                                                 tarval  *cmask  = tarval_shl(minus1, tv1);
4182                                                 ir_node *sl, *blk;
4183
4184                                                 if (tarval_and(tv, cmask) != tv) {
4185                                                         /* condition not met */
4186                                                         tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
4187                                                         c1 = new_Const(mode_b, tv);
4188                                                         DBG_OPT_CSTEVAL(proj, c1);
4189                                                         return c1;
4190                                                 }
4191                                                 sl   = get_Shl_left(left);
4192                                                 blk  = get_nodes_block(n);
4193                                                 left = new_rd_And(get_irn_dbg_info(left), current_ir_graph, blk, sl, new_Const(mode, amask), mode);
4194                                                 tv   = tarval_shr(tv, tv1);
4195                                                 changed |= 2;
4196                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4197                                         }
4198                                         break;
4199                                 case iro_Shr:
4200                                         /*
4201                                          * optimize x >>u c1 == c into x & (-1 << c1) == c << c1  if  c & (-1 >>u c1) == c
4202                                          *                             FALSE                       else
4203                                          * optimize x >>u c1 != c into x & (-1 << c1) != c << c1  if  c & (-1 >>u c1) == c
4204                                          *                             TRUE                        else
4205                                          */
4206                                         c1 = get_Shr_right(left);
4207                                         if (is_Const(c1)) {
4208                                                 tarval  *tv1    = get_Const_tarval(c1);
4209                                                 ir_mode *mode   = get_irn_mode(left);
4210                                                 tarval  *minus1 = get_mode_all_one(mode);
4211                                                 tarval  *amask  = tarval_shl(minus1, tv1);
4212                                                 tarval  *cmask  = tarval_shr(minus1, tv1);
4213                                                 ir_node *sl, *blk;
4214
4215                                                 if (tarval_and(tv, cmask) != tv) {
4216                                                         /* condition not met */
4217                                                         tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
4218                                                         c1 = new_Const(mode_b, tv);
4219                                                         DBG_OPT_CSTEVAL(proj, c1);
4220                                                         return c1;
4221                                                 }
4222                                                 sl   = get_Shr_left(left);
4223                                                 blk  = get_nodes_block(n);
4224                                                 left = new_rd_And(get_irn_dbg_info(left), current_ir_graph, blk, sl, new_Const(mode, amask), mode);
4225                                                 tv   = tarval_shl(tv, tv1);
4226                                                 changed |= 2;
4227                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4228                                         }
4229                                         break;
4230                                 case iro_Shrs:
4231                                         /*
4232                                          * optimize x >>s c1 == c into x & (-1 << c1) == c << c1  if  (c >>s (BITS - c1)) \in {0,-1}
4233                                          *                             FALSE                       else
4234                                          * optimize x >>s c1 != c into x & (-1 << c1) != c << c1  if  (c >>s (BITS - c1)) \in {0,-1}
4235                                          *                             TRUE                        else
4236                                          */
4237                                         c1 = get_Shrs_right(left);
4238                                         if (is_Const(c1)) {
4239                                                 tarval  *tv1    = get_Const_tarval(c1);
4240                                                 ir_mode *mode   = get_irn_mode(left);
4241                                                 tarval  *minus1 = get_mode_all_one(mode);
4242                                                 tarval  *amask  = tarval_shl(minus1, tv1);
4243                                                 tarval  *cond   = new_tarval_from_long(get_mode_size_bits(mode), get_tarval_mode(tv1));
4244                                                 ir_node *sl, *blk;
4245
4246                                                 cond = tarval_sub(cond, tv1);
4247                                                 cond = tarval_shrs(tv, cond);
4248
4249                                                 if (!tarval_is_all_one(cond) && !tarval_is_null(cond)) {
4250                                                         /* condition not met */
4251                                                         tv = proj_nr == pn_Cmp_Eq ? get_tarval_b_false() : get_tarval_b_true();
4252                                                         c1 = new_Const(mode_b, tv);
4253                                                         DBG_OPT_CSTEVAL(proj, c1);
4254                                                         return c1;
4255                                                 }
4256                                                 sl   = get_Shrs_left(left);
4257                                                 blk  = get_nodes_block(n);
4258                                                 left = new_rd_And(get_irn_dbg_info(left), current_ir_graph, blk, sl, new_Const(mode, amask), mode);
4259                                                 tv   = tarval_shl(tv, tv1);
4260                                                 changed |= 2;
4261                                                 DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_SHF_TO_AND);
4262                                         }
4263                                         break;
4264                                 }  /* switch */
4265                         }
4266                 } /* tarval != bad */
4267         }
4268
4269         if (changed & 2)      /* need a new Const */
4270                 right = new_Const(mode, tv);
4271
4272         if ((proj_nr == pn_Cmp_Eq || proj_nr == pn_Cmp_Lg) && is_Const(right) && is_Const_null(right) && is_Proj(left)) {
4273                 ir_node *op = get_Proj_pred(left);
4274
4275                 if ((is_Mod(op) && get_Proj_proj(left) == pn_Mod_res) ||
4276                     (is_DivMod(op) && get_Proj_proj(left) == pn_DivMod_res_mod)) {
4277                         ir_node *c = get_binop_right(op);
4278
4279                         if (is_Const(c)) {
4280                                 tarval *tv = get_Const_tarval(c);
4281
4282                                 if (tarval_is_single_bit(tv)) {
4283                                         /* special case: (x % 2^n) CMP 0 ==> x & (2^n-1) CMP 0 */
4284                                         ir_node *v    = get_binop_left(op);
4285                                         ir_node *blk  = get_irn_n(op, -1);
4286                                         ir_mode *mode = get_irn_mode(v);
4287
4288                                         tv = tarval_sub(tv, get_mode_one(mode));
4289                                         left = new_rd_And(get_irn_dbg_info(op), current_ir_graph, blk, v, new_Const(mode, tv), mode);
4290                                         changed |= 1;
4291                                         DBG_OPT_ALGSIM0(n, n, FS_OPT_CMP_MOD_TO_AND);
4292                                 }
4293                         }
4294                 }
4295         }
4296
4297         if (changed) {
4298                 ir_node *block = get_irn_n(n, -1); /* Beware of get_nodes_Block() */
4299
4300                 /* create a new compare */
4301                 n = new_rd_Cmp(get_irn_dbg_info(n), current_ir_graph, block, left, right);
4302                 proj = new_rd_Proj(get_irn_dbg_info(proj), current_ir_graph, block, n, get_irn_mode(proj), proj_nr);
4303         }
4304
4305         return proj;
4306 }  /* transform_node_Proj_Cmp */
4307
4308 /**
4309  * Does all optimizations on nodes that must be done on it's Proj's
4310  * because of creating new nodes.
4311  */
4312 static ir_node *transform_node_Proj(ir_node *proj) {
4313         ir_node *n = get_Proj_pred(proj);
4314
4315         switch (get_irn_opcode(n)) {
4316         case iro_Div:
4317                 return transform_node_Proj_Div(proj);
4318
4319         case iro_Mod:
4320                 return transform_node_Proj_Mod(proj);
4321
4322         case iro_DivMod:
4323                 return transform_node_Proj_DivMod(proj);
4324
4325         case iro_Cond:
4326                 return transform_node_Proj_Cond(proj);
4327
4328         case iro_Cmp:
4329                 return transform_node_Proj_Cmp(proj);
4330
4331         case iro_Tuple:
4332                 /* should not happen, but if it does will be optimized away */
4333                 return equivalent_node_Proj(proj);
4334
4335         default:
4336                 /* do nothing */
4337                 return proj;
4338         }
4339 }  /* transform_node_Proj */
4340
4341 /**
4342  * Move Confirms down through Phi nodes.
4343  */
4344 static ir_node *transform_node_Phi(ir_node *phi) {
4345         int i, n;
4346         ir_mode *mode = get_irn_mode(phi);
4347
4348         if (mode_is_reference(mode)) {
4349                 n = get_irn_arity(phi);
4350
4351                 /* Beware of Phi0 */
4352                 if (n > 0) {
4353                         ir_node *pred = get_irn_n(phi, 0);
4354                         ir_node *bound, *new_Phi, *block, **in;
4355                         pn_Cmp  pnc;
4356
4357                         if (! is_Confirm(pred))
4358                                 return phi;
4359
4360                         bound = get_Confirm_bound(pred);
4361                         pnc   = get_Confirm_cmp(pred);
4362
4363                         NEW_ARR_A(ir_node *, in, n);
4364                         in[0] = get_Confirm_value(pred);
4365
4366                         for (i = 1; i < n; ++i) {
4367                                 pred = get_irn_n(phi, i);
4368
4369                                 if (! is_Confirm(pred) ||
4370                                         get_Confirm_bound(pred) != bound ||
4371                                         get_Confirm_cmp(pred) != pnc)
4372                                         return phi;
4373                                 in[i] = get_Confirm_value(pred);
4374                         }
4375                         /* move the Confirm nodes "behind" the Phi */
4376                         block = get_irn_n(phi, -1);
4377                         new_Phi = new_r_Phi(current_ir_graph, block, n, in, get_irn_mode(phi));
4378                         return new_r_Confirm(current_ir_graph, block, new_Phi, bound, pnc);
4379                 }
4380         }
4381         return phi;
4382 }  /* transform_node_Phi */
4383
4384 /**
4385  * Returns the operands of a commutative bin-op, if one operand is
4386  * a const, it is returned as the second one.
4387  */
4388 static void get_comm_Binop_Ops(ir_node *binop, ir_node **a, ir_node **c) {
4389         ir_node *op_a = get_binop_left(binop);
4390         ir_node *op_b = get_binop_right(binop);
4391
4392         assert(is_op_commutative(get_irn_op(binop)));
4393
4394         if (is_Const(op_a)) {
4395                 *a = op_b;
4396                 *c = op_a;
4397         } else {
4398                 *a = op_a;
4399                 *c = op_b;
4400         }
4401 }  /* get_comm_Binop_Ops */
4402
4403 /**
4404  * Optimize a Or(And(Or(And(v,c4),c3),c2),c1) pattern if possible.
4405  * Such pattern may arise in bitfield stores.
4406  *
4407  * value  c4                  value      c4 & c2
4408  *    AND     c3                    AND           c1 | c3
4409  *        OR     c2      ===>               OR
4410  *           AND    c1
4411  *               OR
4412  *
4413  *
4414  * value  c2                 value  c1
4415  *     AND   c1    ===>           OR     if (c1 | c2) == 0x111..11
4416  *        OR
4417  */
4418 static ir_node *transform_node_Or_bf_store(ir_node *or) {
4419         ir_node *and, *c1;
4420         ir_node *or_l, *c2;
4421         ir_node *and_l, *c3;
4422         ir_node *value, *c4;
4423         ir_node *new_and, *new_const, *block;
4424         ir_mode *mode = get_irn_mode(or);
4425
4426         tarval *tv1, *tv2, *tv3, *tv4, *tv, *n_tv4, *n_tv2;
4427
4428         while (1) {
4429                 get_comm_Binop_Ops(or, &and, &c1);
4430                 if (!is_Const(c1) || !is_And(and))
4431                         return or;
4432
4433                 get_comm_Binop_Ops(and, &or_l, &c2);
4434                 if (!is_Const(c2))
4435                         return or;
4436
4437                 tv1 = get_Const_tarval(c1);
4438                 tv2 = get_Const_tarval(c2);
4439
4440                 tv = tarval_or(tv1, tv2);
4441                 if (tarval_is_all_one(tv)) {
4442                         /* the AND does NOT clear a bit with isn't set by the OR */
4443                         set_Or_left(or, or_l);
4444                         set_Or_right(or, c1);
4445
4446                         /* check for more */
4447                         continue;
4448                 }
4449
4450                 if (!is_Or(or_l))
4451                         return or;
4452
4453                 get_comm_Binop_Ops(or_l, &and_l, &c3);
4454                 if (!is_Const(c3) || !is_And(and_l))
4455                         return or;
4456
4457                 get_comm_Binop_Ops(and_l, &value, &c4);
4458                 if (!is_Const(c4))
4459                         return or;
4460
4461                 /* ok, found the pattern, check for conditions */
4462                 assert(mode == get_irn_mode(and));
4463                 assert(mode == get_irn_mode(or_l));
4464                 assert(mode == get_irn_mode(and_l));
4465
4466                 tv3 = get_Const_tarval(c3);
4467                 tv4 = get_Const_tarval(c4);
4468
4469                 tv = tarval_or(tv4, tv2);
4470                 if (!tarval_is_all_one(tv)) {
4471                         /* have at least one 0 at the same bit position */
4472                         return or;
4473                 }
4474
4475                 n_tv4 = tarval_not(tv4);
4476                 if (tv3 != tarval_and(tv3, n_tv4)) {
4477                         /* bit in the or_mask is outside the and_mask */
4478                         return or;
4479                 }
4480
4481                 n_tv2 = tarval_not(tv2);
4482                 if (tv1 != tarval_and(tv1, n_tv2)) {
4483                         /* bit in the or_mask is outside the and_mask */
4484                         return or;
4485                 }
4486
4487                 /* ok, all conditions met */
4488                 block = get_irn_n(or, -1);
4489
4490                 new_and = new_r_And(current_ir_graph, block,
4491                         value, new_r_Const(current_ir_graph, block, mode, tarval_and(tv4, tv2)), mode);
4492
4493                 new_const = new_r_Const(current_ir_graph, block, mode, tarval_or(tv3, tv1));
4494
4495                 set_Or_left(or, new_and);
4496                 set_Or_right(or, new_const);
4497
4498                 /* check for more */
4499         }
4500 }  /* transform_node_Or_bf_store */
4501
4502 /**
4503  * Optimize an Or(shl(x, c), shr(x, bits - c)) into a Rot
4504  */
4505 static ir_node *transform_node_Or_Rot(ir_node *or) {
4506         ir_mode *mode = get_irn_mode(or);
4507         ir_node *shl, *shr, *block;
4508         ir_node *irn, *x, *c1, *c2, *v, *sub, *n;
4509         tarval *tv1, *tv2;
4510
4511         if (! mode_is_int(mode))
4512                 return or;
4513
4514         shl = get_binop_left(or);
4515         shr = get_binop_right(or);
4516
4517         if (is_Shr(shl)) {
4518                 if (!is_Shl(shr))
4519                         return or;
4520
4521                 irn = shl;
4522                 shl = shr;
4523                 shr = irn;
4524         } else if (!is_Shl(shl)) {
4525                 return or;
4526         } else if (!is_Shr(shr)) {
4527                 return or;
4528         }
4529         x = get_Shl_left(shl);
4530         if (x != get_Shr_left(shr))
4531                 return or;
4532
4533         c1 = get_Shl_right(shl);
4534         c2 = get_Shr_right(shr);
4535         if (is_Const(c1) && is_Const(c2)) {
4536                 tv1 = get_Const_tarval(c1);
4537                 if (! tarval_is_long(tv1))
4538                         return or;
4539
4540                 tv2 = get_Const_tarval(c2);
4541                 if (! tarval_is_long(tv2))
4542                         return or;
4543
4544                 if (get_tarval_long(tv1) + get_tarval_long(tv2)
4545                                 != (int) get_mode_size_bits(mode))
4546                         return or;
4547
4548                 /* yet, condition met */
4549                 block = get_irn_n(or, -1);
4550
4551                 n = new_r_Rot(current_ir_graph, block, x, c1, mode);
4552
4553                 DBG_OPT_ALGSIM1(or, shl, shr, n, FS_OPT_OR_SHFT_TO_ROT);
4554                 return n;
4555         } else if (is_Sub(c1)) {
4556                 v   = c2;
4557                 sub = c1;
4558
4559                 if (get_Sub_right(sub) != v)
4560                         return or;
4561
4562                 c1 = get_Sub_left(sub);
4563                 if (!is_Const(c1))
4564                         return or;
4565
4566                 tv1 = get_Const_tarval(c1);
4567                 if (! tarval_is_long(tv1))
4568                         return or;
4569
4570                 if (get_tarval_long(tv1) != (int) get_mode_size_bits(mode))
4571                         return or;
4572
4573                 /* yet, condition met */
4574                 block = get_nodes_block(or);
4575
4576                 /* a Rot right is not supported, so use a rot left */
4577                 n =  new_r_Rot(current_ir_graph, block, x, sub, mode);
4578
4579                 DBG_OPT_ALGSIM0(or, n, FS_OPT_OR_SHFT_TO_ROT);
4580                 return n;
4581         } else if (is_Sub(c2)) {
4582                 v   = c1;
4583                 sub = c2;
4584
4585                 c1 = get_Sub_left(sub);
4586                 if (!is_Const(c1))
4587                         return or;
4588
4589                 tv1 = get_Const_tarval(c1);
4590                 if (! tarval_is_long(tv1))
4591                         return or;
4592
4593                 if (get_tarval_long(tv1) != (int) get_mode_size_bits(mode))
4594                         return or;
4595
4596                 /* yet, condition met */
4597                 block = get_irn_n(or, -1);
4598
4599                 /* a Rot Left */
4600                 n = new_r_Rot(current_ir_graph, block, x, v, mode);
4601
4602                 DBG_OPT_ALGSIM0(or, n, FS_OPT_OR_SHFT_TO_ROT);
4603                 return n;
4604         }
4605
4606         return or;
4607 }  /* transform_node_Or_Rot */
4608
4609 /**
4610  * Transform an Or.
4611  */
4612 static ir_node *transform_node_Or(ir_node *n) {
4613         ir_node *c, *oldn = n;
4614         ir_node *a = get_Or_left(n);
4615         ir_node *b = get_Or_right(n);
4616         ir_mode *mode;
4617
4618         if (is_Not(a) && is_Not(b)) {
4619                 /* ~a | ~b = ~(a&b) */
4620                 ir_node *block = get_nodes_block(n);
4621
4622                 mode = get_irn_mode(n);
4623                 a = get_Not_op(a);
4624                 b = get_Not_op(b);
4625                 n = new_rd_And(get_irn_dbg_info(n), current_ir_graph, block, a, b, mode);
4626                 n = new_rd_Not(get_irn_dbg_info(n), current_ir_graph, block, n, mode);
4627                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
4628                 return n;
4629         }
4630
4631         /* we can evaluate 2 Projs of the same Cmp */
4632         if (get_irn_mode(n) == mode_b && is_Proj(a) && is_Proj(b)) {
4633                 ir_node *pred_a = get_Proj_pred(a);
4634                 ir_node *pred_b = get_Proj_pred(b);
4635                 if (pred_a == pred_b) {
4636                         dbg_info *dbgi  = get_irn_dbg_info(n);
4637                         ir_node  *block = get_nodes_block(pred_a);
4638                         pn_Cmp pn_a     = get_Proj_proj(a);
4639                         pn_Cmp pn_b     = get_Proj_proj(b);
4640                         /* yes, we can simply calculate with pncs */
4641                         pn_Cmp new_pnc  = pn_a | pn_b;
4642
4643                         return new_rd_Proj(dbgi, current_ir_graph, block, pred_a, mode_b,
4644                                            new_pnc);
4645                 }
4646         }
4647
4648         mode = get_irn_mode(n);
4649         HANDLE_BINOP_PHI(tarval_or, a, b, c, mode);
4650
4651         n = transform_node_Or_bf_store(n);
4652         n = transform_node_Or_Rot(n);
4653         if (n != oldn)
4654                 return n;
4655
4656         n = transform_bitwise_distributive(n, transform_node_Or);
4657
4658         return n;
4659 }  /* transform_node_Or */
4660
4661
4662 /* forward */
4663 static ir_node *transform_node(ir_node *n);
4664
4665 /**
4666  * Optimize (a >> c1) >> c2), works for Shr, Shrs, Shl, Rot.
4667  *
4668  * Should be moved to reassociation?
4669  */
4670 static ir_node *transform_node_shift(ir_node *n) {
4671         ir_node *left, *right;
4672         tarval *tv1, *tv2, *res;
4673         ir_mode *mode;
4674         int modulo_shf, flag;
4675
4676         left = get_binop_left(n);
4677
4678         /* different operations */
4679         if (get_irn_op(left) != get_irn_op(n))
4680                 return n;
4681
4682         right = get_binop_right(n);
4683         tv1 = value_of(right);
4684         if (tv1 == tarval_bad)
4685                 return n;
4686
4687         tv2 = value_of(get_binop_right(left));
4688         if (tv2 == tarval_bad)
4689                 return n;
4690
4691         res = tarval_add(tv1, tv2);
4692
4693         /* beware: a simple replacement works only, if res < modulo shift */
4694         mode = get_irn_mode(n);
4695
4696         flag = 0;
4697
4698         modulo_shf = get_mode_modulo_shift(mode);
4699         if (modulo_shf > 0) {
4700                 tarval *modulo = new_tarval_from_long(modulo_shf, get_tarval_mode(res));
4701
4702                 if (tarval_cmp(res, modulo) & pn_Cmp_Lt)
4703                         flag = 1;
4704         } else
4705                 flag = 1;
4706
4707         if (flag) {
4708                 /* ok, we can replace it */
4709                 ir_node *in[2], *irn, *block = get_irn_n(n, -1);
4710
4711                 in[0] = get_binop_left(left);
4712                 in[1] = new_r_Const(current_ir_graph, block, get_tarval_mode(res), res);
4713
4714                 irn = new_ir_node(NULL, current_ir_graph, block, get_irn_op(n), mode, 2, in);
4715
4716                 DBG_OPT_ALGSIM0(n, irn, FS_OPT_REASSOC_SHIFT);
4717
4718                 return transform_node(irn);
4719         }
4720         return n;
4721 }  /* transform_node_shift */
4722
4723 /**
4724  * Transform a Shr.
4725  */
4726 static ir_node *transform_node_Shr(ir_node *n) {
4727         ir_node *c, *oldn = n;
4728         ir_node *a    = get_Shr_left(n);
4729         ir_node *b    = get_Shr_right(n);
4730         ir_mode *mode = get_irn_mode(n);
4731
4732         HANDLE_BINOP_PHI(tarval_shr, a, b, c, mode);
4733         return transform_node_shift(n);
4734 }  /* transform_node_Shr */
4735
4736 /**
4737  * Transform a Shrs.
4738  */
4739 static ir_node *transform_node_Shrs(ir_node *n) {
4740         ir_node *c, *oldn = n;
4741         ir_node *a    = get_Shrs_left(n);
4742         ir_node *b    = get_Shrs_right(n);
4743         ir_mode *mode = get_irn_mode(n);
4744
4745         HANDLE_BINOP_PHI(tarval_shrs, a, b, c, mode);
4746         return transform_node_shift(n);
4747 }  /* transform_node_Shrs */
4748
4749 /**
4750  * Transform a Shl.
4751  */
4752 static ir_node *transform_node_Shl(ir_node *n) {
4753         ir_node *c, *oldn = n;
4754         ir_node *a    = get_Shl_left(n);
4755         ir_node *b    = get_Shl_right(n);
4756         ir_mode *mode = get_irn_mode(n);
4757
4758         HANDLE_BINOP_PHI(tarval_shl, a, b, c, mode);
4759         return transform_node_shift(n);
4760 }  /* transform_node_Shl */
4761
4762 /**
4763  * Transform a Rot.
4764  */
4765 static ir_node *transform_node_Rot(ir_node *n) {
4766         ir_node *c, *oldn = n;
4767         ir_node *a    = get_Rot_left(n);
4768         ir_node *b    = get_Rot_right(n);
4769         ir_mode *mode = get_irn_mode(n);
4770
4771         HANDLE_BINOP_PHI(tarval_rot, a, b, c, mode);
4772         return transform_node_shift(n);
4773 }  /* transform_node_Rot */
4774
4775 /**
4776  * Transform a Conv.
4777  */
4778 static ir_node *transform_node_Conv(ir_node *n) {
4779         ir_node *c, *oldn = n;
4780         ir_node *a = get_Conv_op(n);
4781
4782         if (is_const_Phi(a)) {
4783                 c = apply_conv_on_phi(a, get_irn_mode(n));
4784                 if (c) {
4785                         DBG_OPT_ALGSIM0(oldn, c, FS_OPT_CONST_PHI);
4786                         return c;
4787                 }
4788         }
4789
4790         if (is_Unknown(a)) { /* Conv_A(Unknown_B) -> Unknown_A */
4791                 ir_mode *mode = get_irn_mode(n);
4792                 return new_r_Unknown(current_ir_graph, mode);
4793         }
4794
4795         return n;
4796 }  /* transform_node_Conv */
4797
4798 /**
4799  * Remove dead blocks and nodes in dead blocks
4800  * in keep alive list.  We do not generate a new End node.
4801  */
4802 static ir_node *transform_node_End(ir_node *n) {
4803         int i, j, n_keepalives = get_End_n_keepalives(n);
4804         ir_node **in;
4805
4806         NEW_ARR_A(ir_node *, in, n_keepalives);
4807
4808         for (i = j = 0; i < n_keepalives; ++i) {
4809                 ir_node *ka = get_End_keepalive(n, i);
4810                 if (is_Block(ka)) {
4811                         if (! is_Block_dead(ka)) {
4812                                 in[j++] = ka;
4813                         }
4814                         continue;
4815                 } else if (is_irn_pinned_in_irg(ka) && is_Block_dead(get_nodes_block(ka))) {
4816                         continue;
4817                 }
4818                 /* FIXME: beabi need to keep a Proj(M) */
4819                 if (is_Phi(ka) || is_irn_keep(ka) || is_Proj(ka))
4820                         in[j++] = ka;
4821         }
4822         if (j != n_keepalives)
4823                 set_End_keepalives(n, j, in);
4824         return n;
4825 }  /* transform_node_End */
4826
4827 /** returns 1 if a == -b */
4828 static int is_negated_value(ir_node *a, ir_node *b) {
4829         if (is_Minus(a) && get_Minus_op(a) == b)
4830                 return 1;
4831         if (is_Minus(b) && get_Minus_op(b) == a)
4832                 return 1;
4833         if (is_Sub(a) && is_Sub(b)) {
4834                 ir_node *a_left  = get_Sub_left(a);
4835                 ir_node *a_right = get_Sub_right(a);
4836                 ir_node *b_left  = get_Sub_left(b);
4837                 ir_node *b_right = get_Sub_right(b);
4838
4839                 if (a_left == b_right && a_right == b_left)
4840                         return 1;
4841         }
4842
4843         return 0;
4844 }
4845
4846 /**
4847  * Optimize a Mux into some simpler cases.
4848  */
4849 static ir_node *transform_node_Mux(ir_node *n) {
4850         ir_node *oldn = n, *sel = get_Mux_sel(n);
4851         ir_mode *mode = get_irn_mode(n);
4852         ir_node  *t   = get_Mux_true(n);
4853         ir_node  *f   = get_Mux_false(n);
4854         ir_graph *irg = current_ir_graph;
4855         ir_node  *conds[1], *vals[2];
4856
4857         /* first normalization step: move a possible zero to the false case */
4858         if (is_Proj(sel)) {
4859                 ir_node *cmp = get_Proj_pred(sel);
4860
4861                 if (is_Cmp(cmp)) {
4862                         if (is_Const(t) && is_Const_null(t)) {
4863                                 /* Psi(x, 0, y) => Psi(x, y, 0) */
4864                                 pn_Cmp pnc = get_Proj_proj(sel);
4865                                 sel = new_r_Proj(irg, get_nodes_block(cmp), cmp, mode_b,
4866                                         get_negated_pnc(pnc, get_irn_mode(get_Cmp_left(cmp))));
4867                                 conds[0] = sel;
4868                                 vals[0]  = f;
4869                                 vals[1]  = t;
4870                                 n        = new_rd_Psi(get_irn_dbg_info(n), irg, get_nodes_block(n), 1, conds, vals, mode);
4871                                 t = vals[0];
4872                                 f = vals[1];
4873                         }
4874                 }
4875         }
4876
4877         /* note: after normalization, false can only happen on default */
4878         if (mode == mode_b) {
4879                 dbg_info *dbg   = get_irn_dbg_info(n);
4880                 ir_node  *block = get_nodes_block(n);
4881                 ir_graph *irg   = current_ir_graph;
4882
4883                 if (is_Const(t)) {
4884                         tarval *tv_t = get_Const_tarval(t);
4885                         if (tv_t == tarval_b_true) {
4886                                 if (is_Const(f)) {
4887                                         /* Muxb(sel, true, false) = sel */
4888                                         assert(get_Const_tarval(f) == tarval_b_false);
4889                                         DBG_OPT_ALGSIM0(oldn, sel, FS_OPT_MUX_BOOL);
4890                                         return sel;
4891                                 } else {
4892                                         /* Muxb(sel, true, x) = Or(sel, x) */
4893                                         n = new_rd_Or(dbg, irg, block, sel, f, mode_b);
4894                                         DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_OR_BOOL);
4895                                         return n;
4896                                 }
4897                         }
4898                 } else if (is_Const(f)) {
4899                         tarval *tv_f = get_Const_tarval(f);
4900                         if (tv_f == tarval_b_true) {
4901                                 /* Muxb(sel, x, true) = Or(Not(sel), x) */
4902                                 ir_node* not_sel = new_rd_Not(dbg, irg, block, sel, mode_b);
4903                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_ORNOT_BOOL);
4904                                 n = new_rd_Or(dbg, irg, block, not_sel, t, mode_b);
4905                                 return n;
4906                         } else {
4907                                 /* Muxb(sel, x, false) = And(sel, x) */
4908                                 assert(tv_f == tarval_b_false);
4909                                 n = new_rd_And(dbg, irg, block, sel, t, mode_b);
4910                                 DBG_OPT_ALGSIM0(oldn, n, FS_OPT_MUX_AND_BOOL);
4911                                 return n;
4912                         }
4913                 }
4914         }
4915
4916         /* more normalization: try to normalize Mux(x, C1, C2) into Mux(x, +1/-1, 0) op C2 */
4917         if (is_Const(t) && is_Const(f) && mode_is_int(mode)) {
4918                 tarval *a = get_Const_tarval(t);
4919                 tarval *b = get_Const_tarval(f);
4920                 tarval *null = get_tarval_null(mode);
4921                 tarval *diff, *min;
4922
4923                 if (tarval_cmp(a, b) & pn_Cmp_Gt) {
4924                         diff = tarval_sub(a, b);
4925                         min  = b;
4926                 } else {
4927                         diff = tarval_sub(b, a);
4928                         min  = a;
4929                 }
4930
4931                 if (diff == get_tarval_one(mode) && min != null) {
4932                         dbg_info *dbg   = get_irn_dbg_info(n);
4933                         ir_node  *block = get_nodes_block(n);
4934                         ir_graph *irg   = current_ir_graph;
4935
4936
4937                         conds[0] = sel;
4938                         vals[0] = new_Const(mode, tarval_sub(a, min));
4939                         vals[1] = new_Const(mode, tarval_sub(b, min));
4940                         n = new_rd_Psi(dbg, irg, block, 1, conds, vals, mode);
4941                         n = new_rd_Add(dbg, irg, block, n, new_Const(mode, min), mode);
4942                         return n;
4943                 }
4944         }
4945
4946         if (is_Proj(sel)) {
4947                 ir_node *cmp = get_Proj_pred(sel);
4948                 long     pn  = get_Proj_proj(sel);
4949
4950                 /*
4951                  * Note: normalization puts the constant on the right side,
4952                  * so we check only one case.
4953                  *
4954                  * Note further that these optimization work even for floating point
4955                  * with NaN's because -NaN == NaN.
4956                  * However, if +0 and -0 is handled differently, we cannot use the Abs/-Abs
4957                  * transformations.
4958                  */
4959                 if (is_Cmp(cmp)) {
4960                         ir_node *cmp_r = get_Cmp_right(cmp);
4961                         if (is_Const(cmp_r) && is_Const_null(cmp_r)) {
4962                                 ir_node *block = get_nodes_block(n);
4963                                 ir_node *cmp_l = get_Cmp_left(cmp);
4964
4965                                 if (!mode_honor_signed_zeros(mode) && is_negated_value(f, t)) {
4966                                         /* f = -t */
4967
4968                                         if ( (cmp_l == t && (pn == pn_Cmp_Ge || pn == pn_Cmp_Gt))
4969                                                 || (cmp_l == f && (pn == pn_Cmp_Le || pn == pn_Cmp_Lt)))
4970                                         {
4971                                                 /* Psi(a >/>= 0, a, -a) = Psi(a </<= 0, -a, a) ==> Abs(a) */
4972                                                 n = new_rd_Abs(get_irn_dbg_info(n), current_ir_graph, block,
4973                                                                                  cmp_l, mode);
4974                                                 DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_ABS);
4975                                                 return n;
4976                                         } else if ((cmp_l == t && (pn == pn_Cmp_Le || pn == pn_Cmp_Lt))
4977                                                 || (cmp_l == f && (pn == pn_Cmp_Ge || pn == pn_Cmp_Gt)))
4978                                         {
4979                                                 /* Psi(a </<= 0, a, -a) = Psi(a >/>= 0, -a, a) ==> -Abs(a) */
4980                                                 n = new_rd_Abs(get_irn_dbg_info(n), current_ir_graph, block,
4981                                                                                  cmp_l, mode);
4982                                                 n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph,
4983                                                                                                                  block, n, mode);
4984                                                 DBG_OPT_ALGSIM1(oldn, cmp, sel, n, FS_OPT_MUX_TO_ABS);
4985                                                 return n;
4986                                         }
4987                                 }
4988
4989                                 if (mode_is_int(mode)) {
4990                                         /* integer only */
4991                                         if ((pn == pn_Cmp_Lg || pn == pn_Cmp_Eq) && is_And(cmp_l)) {
4992                                                 /* Psi((a & b) != 0, c, 0) */
4993                                                 ir_node *and_r = get_And_right(cmp_l);
4994                                                 ir_node *and_l;
4995
4996                                                 if (and_r == t && f == cmp_r) {
4997                                                         if (is_Const(t) && tarval_is_single_bit(get_Const_tarval(t))) {
4998                                                                 if (pn == pn_Cmp_Lg) {
4999                                                                         /* Psi((a & 2^C) != 0, 2^C, 0) */
5000                                                                         n = cmp_l;
5001                                                                 } else {
5002                                                                         /* Psi((a & 2^C) == 0, 2^C, 0) */
5003                                                                         n = new_rd_Eor(get_irn_dbg_info(n), current_ir_graph,
5004                                                                                 block, cmp_l, t, mode);
5005                                                                 }
5006                                                                 return n;
5007                                                         }
5008                                                 }
5009                                                 if (is_Shl(and_r)) {
5010                                                         ir_node *shl_l = get_Shl_left(and_r);
5011                                                         if (is_Const(shl_l) && is_Const_one(shl_l)) {
5012                                                                 if (and_r == t && f == cmp_r) {
5013                                                                         if (pn == pn_Cmp_Lg) {
5014                                                                                 /* (a & (1 << n)) != 0, (1 << n), 0) */
5015                                                                                 n = cmp_l;
5016                                                                         } else {
5017                                                                                 /* (a & (1 << n)) == 0, (1 << n), 0) */
5018                                                                                 n = new_rd_Eor(get_irn_dbg_info(n), current_ir_graph,
5019                                                                                         block, cmp_l, t, mode);
5020                                                                         }
5021                                                                         return n;
5022                                                                 }
5023                                                         }
5024                                                 }
5025                                                 and_l = get_And_left(cmp_l);
5026                                                 if (is_Shl(and_l)) {
5027                                                         ir_node *shl_l = get_Shl_left(and_l);
5028                                                         if (is_Const(shl_l) && is_Const_one(shl_l)) {
5029                                                                 if (and_l == t && f == cmp_r) {
5030                                                                         if (pn == pn_Cmp_Lg) {
5031                                                                                 /* ((1 << n) & a) != 0, (1 << n), 0) */
5032                                                                                 n = cmp_l;
5033                                                                         } else {
5034                                                                                 /* ((1 << n) & a) == 0, (1 << n), 0) */
5035                                                                                 n = new_rd_Eor(get_irn_dbg_info(n), current_ir_graph,
5036                                                                                         block, cmp_l, t, mode);
5037                                                                         }
5038                                                                         return n;
5039                                                                 }
5040                                                         }
5041                                                 }
5042                                         }
5043                                 }
5044                         }
5045                 }
5046         }
5047         return arch_transform_node_Mux(n);
5048 }  /* transform_node_Mux */
5049
5050 /**
5051  * Optimize a Psi into some simpler cases.
5052  */
5053 static ir_node *transform_node_Psi(ir_node *n) {
5054         if (is_Mux(n))
5055                 return transform_node_Mux(n);
5056
5057         return n;
5058 }  /* transform_node_Psi */
5059
5060 /**
5061  * optimize sync nodes that have other syncs as input we simply add the inputs
5062  * of the other sync to our own inputs
5063  */
5064 static ir_node *transform_node_Sync(ir_node *n) {
5065         int arity = get_Sync_n_preds(n);
5066         int i;
5067
5068         for (i = 0; i < arity;) {
5069                 ir_node *pred = get_Sync_pred(n, i);
5070                 int      pred_arity;
5071                 int      j;
5072
5073                 if (!is_Sync(pred)) {
5074                         ++i;
5075                         continue;
5076                 }
5077
5078                 del_Sync_n(n, i);
5079                 --arity;
5080
5081                 pred_arity = get_Sync_n_preds(pred);
5082                 for (j = 0; j < pred_arity; ++j) {
5083                         ir_node *pred_pred = get_Sync_pred(pred, j);
5084                         int      k;
5085
5086                         for (k = 0;; ++k) {
5087                                 if (k >= arity) {
5088                                         add_irn_n(n, pred_pred);
5089                                         ++arity;
5090                                         break;
5091                                 }
5092                                 if (get_Sync_pred(n, k) == pred_pred) break;
5093                         }
5094                 }
5095         }
5096
5097         /* rehash the sync node */
5098         add_identities(current_ir_graph->value_table, n);
5099
5100         return n;
5101 }
5102
5103 /**
5104  * Tries several [inplace] [optimizing] transformations and returns an
5105  * equivalent node.  The difference to equivalent_node() is that these
5106  * transformations _do_ generate new nodes, and thus the old node must
5107  * not be freed even if the equivalent node isn't the old one.
5108  */
5109 static ir_node *transform_node(ir_node *n) {
5110         ir_node *oldn;
5111
5112         /*
5113          * Transform_node is the only "optimizing transformation" that might
5114          * return a node with a different opcode. We iterate HERE until fixpoint
5115          * to get the final result.
5116          */
5117         do {
5118                 oldn = n;
5119                 if (n->op->ops.transform_node)
5120                         n = n->op->ops.transform_node(n);
5121         } while (oldn != n);
5122
5123         return n;
5124 }  /* transform_node */
5125
5126 /**
5127  * Sets the default transform node operation for an ir_op_ops.
5128  *
5129  * @param code   the opcode for the default operation
5130  * @param ops    the operations initialized
5131  *
5132  * @return
5133  *    The operations.
5134  */
5135 static ir_op_ops *firm_set_default_transform_node(ir_opcode code, ir_op_ops *ops)
5136 {
5137 #define CASE(a)                                 \
5138         case iro_##a:                                 \
5139                 ops->transform_node  = transform_node_##a;  \
5140                 break
5141
5142         switch (code) {
5143         CASE(Add);
5144         CASE(Sub);
5145         CASE(Mul);
5146         CASE(Div);
5147         CASE(Mod);
5148         CASE(DivMod);
5149         CASE(Quot);
5150         CASE(Abs);
5151         CASE(Cond);
5152         CASE(And);
5153         CASE(Or);
5154         CASE(Eor);
5155         CASE(Minus);
5156         CASE(Not);
5157         CASE(Cast);
5158         CASE(Proj);
5159         CASE(Phi);
5160         CASE(Sel);
5161         CASE(Shr);
5162         CASE(Shrs);
5163         CASE(Shl);
5164         CASE(Rot);
5165         CASE(Conv);
5166         CASE(End);
5167         CASE(Mux);
5168         CASE(Psi);
5169         CASE(Sync);
5170         default:
5171           /* leave NULL */;
5172         }
5173
5174         return ops;
5175 #undef CASE
5176 }  /* firm_set_default_transform_node */
5177
5178
5179 /* **************** Common Subexpression Elimination **************** */
5180
5181 /** The size of the hash table used, should estimate the number of nodes
5182     in a graph. */
5183 #define N_IR_NODES 512
5184
5185 /** Compares the attributes of two Const nodes. */
5186 static int node_cmp_attr_Const(ir_node *a, ir_node *b) {
5187         return (get_Const_tarval(a) != get_Const_tarval(b))
5188             || (get_Const_type(a) != get_Const_type(b));
5189 }  /* node_cmp_attr_Const */
5190
5191 /** Compares the attributes of two Proj nodes. */
5192 static int node_cmp_attr_Proj(ir_node *a, ir_node *b) {
5193         return get_irn_proj_attr(a) != get_irn_proj_attr(b);
5194 }  /* node_cmp_attr_Proj */
5195
5196 /** Compares the attributes of two Filter nodes. */
5197 static int node_cmp_attr_Filter(ir_node *a, ir_node *b) {
5198         return get_Filter_proj(a) != get_Filter_proj(b);
5199 }  /* node_cmp_attr_Filter */
5200
5201 /** Compares the attributes of two Alloc nodes. */
5202 static int node_cmp_attr_Alloc(ir_node *a, ir_node *b) {
5203         const alloc_attr *pa = get_irn_alloc_attr(a);
5204         const alloc_attr *pb = get_irn_alloc_attr(b);
5205         return (pa->where != pb->where) || (pa->type != pb->type);
5206 }  /* node_cmp_attr_Alloc */
5207
5208 /** Compares the attributes of two Free nodes. */
5209 static int node_cmp_attr_Free(ir_node *a, ir_node *b) {
5210         const free_attr *pa = get_irn_free_attr(a);
5211         const free_attr *pb = get_irn_free_attr(b);
5212         return (pa->where != pb->where) || (pa->type != pb->type);
5213 }  /* node_cmp_attr_Free */
5214
5215 /** Compares the attributes of two SymConst nodes. */
5216 static int node_cmp_attr_SymConst(ir_node *a, ir_node *b) {
5217         const symconst_attr *pa = get_irn_symconst_attr(a);
5218         const symconst_attr *pb = get_irn_symconst_attr(b);
5219         return (pa->kind       != pb->kind)
5220             || (pa->sym.type_p != pb->sym.type_p)
5221             || (pa->tp         != pb->tp);
5222 }  /* node_cmp_attr_SymConst */
5223
5224 /** Compares the attributes of two Call nodes. */
5225 static int node_cmp_attr_Call(ir_node *a, ir_node *b) {
5226         return get_irn_call_attr(a) != get_irn_call_attr(b);
5227 }  /* node_cmp_attr_Call */
5228
5229 /** Compares the attributes of two Sel nodes. */
5230 static int node_cmp_attr_Sel(ir_node *a, ir_node *b) {
5231         const ir_entity *a_ent = get_Sel_entity(a);
5232         const ir_entity *b_ent = get_Sel_entity(b);
5233         return
5234                 (a_ent->kind    != b_ent->kind)    ||
5235                 (a_ent->name    != b_ent->name)    ||
5236                 (a_ent->owner   != b_ent->owner)   ||
5237                 (a_ent->ld_name != b_ent->ld_name) ||
5238                 (a_ent->type    != b_ent->type);
5239 }  /* node_cmp_attr_Sel */
5240
5241 /** Compares the attributes of two Phi nodes. */
5242 static int node_cmp_attr_Phi(ir_node *a, ir_node *b) {
5243         /* we can only enter this function if both nodes have the same number of inputs,
5244            hence it is enough to check if one of them is a Phi0 */
5245         if (is_Phi0(a)) {
5246                 /* check the Phi0 pos attribute */
5247                 return get_irn_phi_attr(a)->u.pos != get_irn_phi_attr(b)->u.pos;
5248         }
5249         return 0;
5250 }  /* node_cmp_attr_Phi */
5251
5252 /** Compares the attributes of two Conv nodes. */
5253 static int node_cmp_attr_Conv(ir_node *a, ir_node *b) {
5254         return get_Conv_strict(a) != get_Conv_strict(b);
5255 }  /* node_cmp_attr_Conv */
5256
5257 /** Compares the attributes of two Cast nodes. */
5258 static int node_cmp_attr_Cast(ir_node *a, ir_node *b) {
5259         return get_Cast_type(a) != get_Cast_type(b);
5260 }  /* node_cmp_attr_Cast */
5261
5262 /** Compares the attributes of two Load nodes. */
5263 static int node_cmp_attr_Load(ir_node *a, ir_node *b) {
5264         if (get_Load_volatility(a) == volatility_is_volatile ||
5265             get_Load_volatility(b) == volatility_is_volatile)
5266                 /* NEVER do CSE on volatile Loads */
5267                 return 1;
5268         /* do not CSE Loads with different alignment. Be conservative. */
5269         if (get_Load_align(a) != get_Load_align(b))
5270                 return 1;
5271
5272         return get_Load_mode(a) != get_Load_mode(b);
5273 }  /* node_cmp_attr_Load */
5274
5275 /** Compares the attributes of two Store nodes. */
5276 static int node_cmp_attr_Store(ir_node *a, ir_node *b) {
5277         /* do not CSE Stores with different alignment. Be conservative. */
5278         if (get_Store_align(a) != get_Store_align(b))
5279                 return 1;
5280
5281         /* NEVER do CSE on volatile Stores */
5282         return (get_Store_volatility(a) == volatility_is_volatile ||
5283                 get_Store_volatility(b) == volatility_is_volatile);
5284 }  /* node_cmp_attr_Store */
5285
5286 /** Compares two exception attributes */
5287 static int node_cmp_exception(ir_node *a, ir_node *b) {
5288         const except_attr *ea = get_irn_except_attr(a);
5289         const except_attr *eb = get_irn_except_attr(b);
5290
5291         return ea->pin_state != eb->pin_state;
5292 }
5293
5294 #define node_cmp_attr_Bound  node_cmp_exception
5295
5296 /** Compares the attributes of two Div nodes. */
5297 static int node_cmp_attr_Div(ir_node *a, ir_node *b) {
5298         const divmod_attr *ma = get_irn_divmod_attr(a);
5299         const divmod_attr *mb = get_irn_divmod_attr(b);
5300         return ma->exc.pin_state != mb->exc.pin_state ||
5301                    ma->res_mode      != mb->res_mode ||
5302                    ma->no_remainder  != mb->no_remainder;
5303 }  /* node_cmp_attr_Div */
5304
5305 /** Compares the attributes of two DivMod nodes. */
5306 static int node_cmp_attr_DivMod(ir_node *a, ir_node *b) {
5307         const divmod_attr *ma = get_irn_divmod_attr(a);
5308         const divmod_attr *mb = get_irn_divmod_attr(b);
5309         return ma->exc.pin_state != mb->exc.pin_state ||
5310                    ma->res_mode      != mb->res_mode;
5311 }  /* node_cmp_attr_DivMod */
5312
5313 /** Compares the attributes of two Mod nodes. */
5314 static int node_cmp_attr_Mod(ir_node *a, ir_node *b) {
5315         const divmod_attr *ma = get_irn_divmod_attr(a);
5316         const divmod_attr *mb = get_irn_divmod_attr(b);
5317         return ma->exc.pin_state != mb->exc.pin_state ||
5318                    ma->res_mode      != mb->res_mode;
5319 }  /* node_cmp_attr_Mod */
5320
5321 /** Compares the attributes of two Quot nodes. */
5322 static int node_cmp_attr_Quot(ir_node *a, ir_node *b) {
5323         const divmod_attr *ma = get_irn_divmod_attr(a);
5324         const divmod_attr *mb = get_irn_divmod_attr(b);
5325         return ma->exc.pin_state != mb->exc.pin_state ||
5326                    ma->res_mode      != mb->res_mode;
5327 }  /* node_cmp_attr_Quot */
5328
5329 /** Compares the attributes of two Confirm nodes. */
5330 static int node_cmp_attr_Confirm(ir_node *a, ir_node *b) {
5331         return (get_Confirm_cmp(a) != get_Confirm_cmp(b));
5332 }  /* node_cmp_attr_Confirm */
5333
5334 /** Compares the attributes of two ASM nodes. */
5335 static int node_cmp_attr_ASM(ir_node *a, ir_node *b) {
5336         int i, n;
5337         const ir_asm_constraint *ca;
5338         const ir_asm_constraint *cb;
5339         ident **cla, **clb;
5340
5341         if (get_ASM_text(a) != get_ASM_text(b))
5342                 return 1;
5343
5344         /* Should we really check the constraints here? Should be better, but is strange. */
5345         n = get_ASM_n_input_constraints(a);
5346         if (n != get_ASM_n_input_constraints(b))
5347                 return 0;
5348
5349         ca = get_ASM_input_constraints(a);
5350         cb = get_ASM_input_constraints(b);
5351         for (i = 0; i < n; ++i) {
5352                 if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint)
5353                         return 1;
5354         }
5355
5356         n = get_ASM_n_output_constraints(a);
5357         if (n != get_ASM_n_output_constraints(b))
5358                 return 0;
5359
5360         ca = get_ASM_output_constraints(a);
5361         cb = get_ASM_output_constraints(b);
5362         for (i = 0; i < n; ++i) {
5363                 if (ca[i].pos != cb[i].pos || ca[i].constraint != cb[i].constraint)
5364                         return 1;
5365         }
5366
5367         n = get_ASM_n_clobbers(a);
5368         if (n != get_ASM_n_clobbers(b))
5369                 return 0;
5370
5371         cla = get_ASM_clobbers(a);
5372         clb = get_ASM_clobbers(b);
5373         for (i = 0; i < n; ++i) {
5374                 if (cla[i] != clb[i])
5375                         return 1;
5376         }
5377         return 0;
5378 }  /* node_cmp_attr_ASM */
5379
5380 /**
5381  * Set the default node attribute compare operation for an ir_op_ops.
5382  *
5383  * @param code   the opcode for the default operation
5384  * @param ops    the operations initialized
5385  *
5386  * @return
5387  *    The operations.
5388  */
5389 static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
5390 {
5391 #define CASE(a)                              \
5392         case iro_##a:                              \
5393                 ops->node_cmp_attr  = node_cmp_attr_##a; \
5394                 break
5395
5396         switch (code) {
5397         CASE(Const);
5398         CASE(Proj);
5399         CASE(Filter);
5400         CASE(Alloc);
5401         CASE(Free);
5402         CASE(SymConst);
5403         CASE(Call);
5404         CASE(Sel);
5405         CASE(Phi);
5406         CASE(Conv);
5407         CASE(Cast);
5408         CASE(Load);
5409         CASE(Store);
5410         CASE(Confirm);
5411         CASE(ASM);
5412         CASE(Div);
5413         CASE(DivMod);
5414         CASE(Mod);
5415         CASE(Quot);
5416         CASE(Bound);
5417         /* FIXME CopyB */
5418         default:
5419           /* leave NULL */;
5420         }
5421
5422         return ops;
5423 #undef CASE
5424 }  /* firm_set_default_node_cmp_attr */
5425
5426 /*
5427  * Compare function for two nodes in the value table. Gets two
5428  * nodes as parameters.  Returns 0 if the nodes are a Common Sub Expression.
5429  */
5430 int identities_cmp(const void *elt, const void *key) {
5431         ir_node *a = (ir_node *)elt;
5432         ir_node *b = (ir_node *)key;
5433         int i, irn_arity_a;
5434
5435         if (a == b) return 0;
5436
5437         if ((get_irn_op(a) != get_irn_op(b)) ||
5438             (get_irn_mode(a) != get_irn_mode(b))) return 1;
5439
5440         /* compare if a's in and b's in are of equal length */
5441         irn_arity_a = get_irn_intra_arity(a);
5442         if (irn_arity_a != get_irn_intra_arity(b))
5443                 return 1;
5444
5445         if (get_irn_pinned(a) == op_pin_state_pinned) {
5446                 /* for pinned nodes, the block inputs must be equal */
5447                 if (get_irn_intra_n(a, -1) != get_irn_intra_n(b, -1))
5448                         return 1;
5449         } else if (! get_opt_global_cse()) {
5450                 /* for block-local CSE both nodes must be in the same MacroBlock */
5451                 if (get_irn_MacroBlock(a) != get_irn_MacroBlock(b))
5452                         return 1;
5453         }
5454
5455         /* compare a->in[0..ins] with b->in[0..ins] */
5456         for (i = 0; i < irn_arity_a; i++)
5457                 if (get_irn_intra_n(a, i) != get_irn_intra_n(b, i))
5458                         return 1;
5459
5460         /*
5461          * here, we already now that the nodes are identical except their
5462          * attributes
5463          */
5464         if (a->op->ops.node_cmp_attr)
5465                 return a->op->ops.node_cmp_attr(a, b);
5466
5467         return 0;
5468 }  /* identities_cmp */
5469
5470 /*
5471  * Calculate a hash value of a node.
5472  */
5473 unsigned ir_node_hash(ir_node *node) {
5474         unsigned h;
5475         int i, irn_arity;
5476
5477         if (node->op == op_Const) {
5478                 /* special value for const, as they only differ in their tarval. */
5479                 h = HASH_PTR(node->attr.con.tv);
5480                 h = 9*h + HASH_PTR(get_irn_mode(node));
5481         } else if (node->op == op_SymConst) {
5482                 /* special value for const, as they only differ in their symbol. */
5483                 h = HASH_PTR(node->attr.symc.sym.type_p);
5484                 h = 9*h + HASH_PTR(get_irn_mode(node));
5485         } else {
5486
5487                 /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
5488                 h = irn_arity = get_irn_intra_arity(node);
5489
5490                 /* consider all in nodes... except the block if not a control flow. */
5491                 for (i = is_cfop(node) ? -1 : 0;  i < irn_arity;  i++) {
5492                         h = 9*h + HASH_PTR(get_irn_intra_n(node, i));
5493                 }
5494
5495                 /* ...mode,... */
5496                 h = 9*h + HASH_PTR(get_irn_mode(node));
5497                 /* ...and code */
5498                 h = 9*h + HASH_PTR(get_irn_op(node));
5499         }
5500
5501         return h;
5502 }  /* ir_node_hash */
5503
5504 pset *new_identities(void) {
5505         return new_pset(identities_cmp, N_IR_NODES);
5506 }  /* new_identities */
5507
5508 void del_identities(pset *value_table) {
5509         del_pset(value_table);
5510 }  /* del_identities */
5511
5512 /**
5513  * Normalize a node by putting constants (and operands with larger
5514  * node index) on the right (operator side).
5515  *
5516  * @param n   The node to normalize
5517  */
5518 static void normalize_node(ir_node *n) {
5519         if (is_op_commutative(get_irn_op(n))) {
5520                 ir_node *l = get_binop_left(n);
5521                 ir_node *r = get_binop_right(n);
5522
5523                 /* For commutative operators perform  a OP b == b OP a but keep
5524                  * constants on the RIGHT side. This helps greatly in some
5525                  * optimizations.  Moreover we use the idx number to make the form
5526                  * deterministic. */
5527                 if (!operands_are_normalized(l, r)) {
5528                         set_binop_left(n, r);
5529                         set_binop_right(n, l);
5530                 }
5531         }
5532 }  /* normalize_node */
5533
5534 /**
5535  * Update the nodes after a match in the value table. If both nodes have
5536  * the same MacroBlock but different Blocks, we must ensure that the node
5537  * with the dominating Block (the node that is near to the MacroBlock header
5538  * is stored in the table.
5539  * Because a MacroBlock has only one "non-exception" flow, we don't need
5540  * dominance info here: We known, that one block must dominate the other and
5541  * following the only block input will allow to find it.
5542  */
5543 static void update_known_irn(ir_node *known_irn, const ir_node *new_ir_node) {
5544         ir_node *known_blk, *new_block, *block, *mbh;
5545
5546         if (get_opt_global_cse()) {
5547                 /* Block inputs are meaning less */
5548                 return;
5549         }
5550         known_blk = get_irn_n(known_irn, -1);
5551         new_block = get_irn_n(new_ir_node, -1);
5552         if (known_blk == new_block) {
5553                 /* already in the same block */
5554                 return;
5555         }
5556         /*
5557          * We expect the typical case when we built the graph. In that case, the
5558          * known_irn is already the upper one, so checking this should be faster.
5559          */
5560         block = new_block;
5561         mbh   = get_Block_MacroBlock(new_block);
5562         for (;;) {
5563                 if (block == known_blk) {
5564                         /* ok, we have found it: known_block dominates new_block as expected */
5565                         return;
5566                 }
5567                 if (block == mbh) {
5568                         /*
5569                          * We have reached the MacroBlock header NOT founding
5570                          * the known_block. new_block must dominate known_block.
5571                          * Update known_irn.
5572                          */
5573                         set_irn_n(known_irn, -1, new_block);
5574                         return;
5575                 }
5576                 assert(get_Block_n_cfgpreds(block) == 1);
5577                 block = get_Block_cfgpred_block(block, 0);
5578         }
5579 }  /* update_value_table */
5580
5581 /**
5582  * Return the canonical node computing the same value as n.
5583  *
5584  * @param value_table  The value table
5585  * @param n            The node to lookup
5586  *
5587  * Looks up the node in a hash table.
5588  *
5589  * For Const nodes this is performed in the constructor, too.  Const
5590  * nodes are extremely time critical because of their frequent use in
5591  * constant string arrays.
5592  */
5593 static INLINE ir_node *identify(pset *value_table, ir_node *n) {
5594         ir_node *o = NULL;
5595
5596         if (!value_table) return n;
5597
5598         normalize_node(n);
5599
5600         o = pset_find(value_table, n, ir_node_hash(n));
5601         if (o == NULL)
5602                 return n;
5603
5604         update_known_irn(o, n);
5605         DBG_OPT_CSE(n, o);
5606
5607         return o;
5608 }  /* identify */
5609
5610 /**
5611  * During construction we set the op_pin_state_pinned flag in the graph right when the
5612  * optimization is performed.  The flag turning on procedure global cse could
5613  * be changed between two allocations.  This way we are safe.
5614  *
5615  * @param value_table  The value table
5616  * @param n            The node to lookup
5617  */
5618 static INLINE ir_node *identify_cons(pset *value_table, ir_node *n) {
5619         ir_node *old = n;
5620
5621         n = identify(value_table, n);
5622         if (n != old && get_irn_MacroBlock(old) != get_irn_MacroBlock(n))
5623                 set_irg_pinned(current_ir_graph, op_pin_state_floats);
5624         return n;
5625 }  /* identify_cons */
5626
5627 /*
5628  * Return the canonical node computing the same value as n.
5629  * Looks up the node in a hash table, enters it in the table
5630  * if it isn't there yet.
5631  *
5632  * @param value_table  the HashSet containing all nodes in the
5633  *                     current IR graph
5634  * @param n            the node to look up
5635  *
5636  * @return a node that computes the same value as n or n if no such
5637  *         node could be found
5638  */
5639 ir_node *identify_remember(pset *value_table, ir_node *n) {
5640         ir_node *o = NULL;
5641
5642         if (!value_table) return n;
5643
5644         normalize_node(n);
5645         /* lookup or insert in hash table with given hash key. */
5646         o = pset_insert(value_table, n, ir_node_hash(n));
5647
5648         if (o != n) {
5649                 update_known_irn(o, n);
5650                 DBG_OPT_CSE(n, o);
5651         }
5652
5653         return o;
5654 }  /* identify_remember */
5655
5656 /* Add a node to the identities value table. */
5657 void add_identities(pset *value_table, ir_node *node) {
5658         if (get_opt_cse() && is_no_Block(node))
5659                 identify_remember(value_table, node);
5660 }  /* add_identities */
5661
5662 /* Visit each node in the value table of a graph. */
5663 void visit_all_identities(ir_graph *irg, irg_walk_func visit, void *env) {
5664         ir_node *node;
5665         ir_graph *rem = current_ir_graph;
5666
5667         current_ir_graph = irg;
5668         foreach_pset(irg->value_table, node)
5669                 visit(node, env);
5670         current_ir_graph = rem;
5671 }  /* visit_all_identities */
5672
5673 /**
5674  * Garbage in, garbage out. If a node has a dead input, i.e., the
5675  * Bad node is input to the node, return the Bad node.
5676  */
5677 static ir_node *gigo(ir_node *node) {
5678         int i, irn_arity;
5679         ir_op *op = get_irn_op(node);
5680
5681         /* remove garbage blocks by looking at control flow that leaves the block
5682            and replacing the control flow by Bad. */
5683         if (get_irn_mode(node) == mode_X) {
5684                 ir_node *block = get_nodes_block(skip_Proj(node));
5685
5686                 /* Don't optimize nodes in immature blocks. */
5687                 if (!get_Block_matured(block))
5688                         return node;
5689                 /* Don't optimize End, may have Bads. */
5690                 if (op == op_End) return node;
5691
5692                 if (is_Block(block)) {
5693                         if (is_Block_dead(block)) {
5694                                 /* control flow from dead block is dead */
5695                                 return new_Bad();
5696                         }
5697
5698                         for (i = get_irn_arity(block) - 1; i >= 0; --i) {
5699                                 if (!is_Bad(get_irn_n(block, i)))
5700                                         break;
5701                         }
5702                         if (i < 0) {
5703                                 ir_graph *irg = get_irn_irg(block);
5704                                 /* the start block is never dead */
5705                                 if (block != get_irg_start_block(irg)
5706                                         && block != get_irg_end_block(irg)) {
5707                                         /*
5708                                          * Do NOT kill control flow without setting
5709                                          * the block to dead of bad things can happen:
5710                                          * We get a Block that is not reachable be irg_block_walk()
5711                                          * but can be found by irg_walk()!
5712                                          */
5713                                         set_Block_dead(block);
5714                                         return new_Bad();
5715                                 }
5716                         }
5717                 }
5718         }
5719
5720         /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
5721            blocks predecessors is dead. */
5722         if (op != op_Block && op != op_Phi && op != op_Tuple) {
5723                 irn_arity = get_irn_arity(node);
5724
5725                 /*
5726                  * Beware: we can only read the block of a non-floating node.
5727                  */
5728                 if (is_irn_pinned_in_irg(node) &&
5729                         is_Block_dead(get_nodes_block(skip_Proj(node))))
5730                         return new_Bad();
5731
5732                 for (i = 0; i < irn_arity; i++) {
5733                         ir_node *pred = get_irn_n(node, i);
5734
5735                         if (is_Bad(pred))
5736                                 return new_Bad();
5737 #if 0
5738                         /* Propagating Unknowns here seems to be a bad idea, because
5739                            sometimes we need a node as a input and did not want that
5740                            it kills it's user.
5741                            However, it might be useful to move this into a later phase
5742                            (if you think that optimizing such code is useful). */
5743                         if (is_Unknown(pred) && mode_is_data(get_irn_mode(node)))
5744                                 return new_Unknown(get_irn_mode(node));
5745 #endif
5746                 }
5747         }
5748 #if 0
5749         /* With this code we violate the agreement that local_optimize
5750            only leaves Bads in Block, Phi and Tuple nodes. */
5751         /* If Block has only Bads as predecessors it's garbage. */
5752         /* If Phi has only Bads as predecessors it's garbage. */
5753         if ((op == op_Block && get_Block_matured(node)) || op == op_Phi)  {
5754                 irn_arity = get_irn_arity(node);
5755                 for (i = 0; i < irn_arity; i++) {
5756                         if (!is_Bad(get_irn_n(node, i))) break;
5757                 }
5758                 if (i == irn_arity) node = new_Bad();
5759         }
5760 #endif
5761         return node;
5762 }  /* gigo */
5763
5764 /**
5765  * These optimizations deallocate nodes from the obstack.
5766  * It can only be called if it is guaranteed that no other nodes
5767  * reference this one, i.e., right after construction of a node.
5768  *
5769  * @param n   The node to optimize
5770  *
5771  * current_ir_graph must be set to the graph of the node!
5772  */
5773 ir_node *optimize_node(ir_node *n) {
5774         tarval *tv;
5775         ir_node *oldn = n;
5776         ir_opcode iro = get_irn_opcode(n);
5777
5778         /* Always optimize Phi nodes: part of the construction. */
5779         if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
5780
5781         /* constant expression evaluation / constant folding */
5782         if (get_opt_constant_folding()) {
5783                 /* neither constants nor Tuple values can be evaluated */
5784                 if (iro != iro_Const && (get_irn_mode(n) != mode_T)) {
5785                         unsigned fp_model = get_irg_fp_model(current_ir_graph);
5786                         int old_fp_mode = tarval_enable_fp_ops((fp_model & fp_strict_algebraic) == 0);
5787                         /* try to evaluate */
5788                         tv = computed_value(n);
5789                         if (tv != tarval_bad) {
5790                                 ir_node *nw;
5791                                 ir_type *old_tp = get_irn_type(n);
5792                                 int i, arity = get_irn_arity(n);
5793                                 int node_size;
5794
5795                                 /*
5796                                  * Try to recover the type of the new expression.
5797                                  */
5798                                 for (i = 0; i < arity && !old_tp; ++i)
5799                                         old_tp = get_irn_type(get_irn_n(n, i));
5800
5801                                 /*
5802                                  * we MUST copy the node here temporary, because it's still needed
5803                                  * for DBG_OPT_CSTEVAL
5804                                  */
5805                                 node_size = offsetof(ir_node, attr) +  n->op->attr_size;
5806                                 oldn = alloca(node_size);
5807
5808                                 memcpy(oldn, n, node_size);
5809                                 CLONE_ARR_A(ir_node *, oldn->in, n->in);
5810
5811                                 /* ARG, copy the in array, we need it for statistics */
5812                                 memcpy(oldn->in, n->in, ARR_LEN(n->in) * sizeof(n->in[0]));
5813
5814                                 /* note the inplace edges module */
5815                                 edges_node_deleted(n, current_ir_graph);
5816
5817                                 /* evaluation was successful -- replace the node. */
5818                                 irg_kill_node(current_ir_graph, n);
5819                                 nw = new_Const(get_tarval_mode(tv), tv);
5820
5821                                 if (old_tp && get_type_mode(old_tp) == get_tarval_mode(tv))
5822                                         set_Const_type(nw, old_tp);
5823                                 DBG_OPT_CSTEVAL(oldn, nw);
5824                                 tarval_enable_fp_ops(old_fp_mode);
5825                                 return nw;
5826                         }
5827                         tarval_enable_fp_ops(old_fp_mode);
5828                 }
5829         }
5830
5831         /* remove unnecessary nodes */
5832         if (get_opt_constant_folding() ||
5833             (iro == iro_Phi)  ||   /* always optimize these nodes. */
5834             (iro == iro_Id)   ||
5835             (iro == iro_Proj) ||
5836             (iro == iro_Block)  )  /* Flags tested local. */
5837                 n = equivalent_node(n);
5838
5839         /* Common Subexpression Elimination.
5840          *
5841          * Checks whether n is already available.
5842          * The block input is used to distinguish different subexpressions. Right
5843          * now all nodes are op_pin_state_pinned to blocks, i.e., the CSE only finds common
5844          * subexpressions within a block.
5845          */
5846         if (get_opt_cse())
5847                 n = identify_cons(current_ir_graph->value_table, n);
5848
5849         if (n != oldn) {
5850                 edges_node_deleted(oldn, current_ir_graph);
5851
5852                 /* We found an existing, better node, so we can deallocate the old node. */
5853                 irg_kill_node(current_ir_graph, oldn);
5854                 return n;
5855         }
5856
5857         /* Some more constant expression evaluation that does not allow to
5858            free the node. */
5859         iro = get_irn_opcode(n);
5860         if (get_opt_constant_folding() ||
5861             (iro == iro_Cond) ||
5862             (iro == iro_Proj))     /* Flags tested local. */
5863                 n = transform_node(n);
5864
5865         /* Remove nodes with dead (Bad) input.
5866            Run always for transformation induced Bads. */
5867         n = gigo (n);
5868
5869         /* Now we have a legal, useful node. Enter it in hash table for CSE */
5870         if (get_opt_cse() && (get_irn_opcode(n) != iro_Block)) {
5871                 n = identify_remember(current_ir_graph->value_table, n);
5872         }
5873
5874         return n;
5875 }  /* optimize_node */
5876
5877
5878 /**
5879  * These optimizations never deallocate nodes (in place).  This can cause dead
5880  * nodes lying on the obstack.  Remove these by a dead node elimination,
5881  * i.e., a copying garbage collection.
5882  */
5883 ir_node *optimize_in_place_2(ir_node *n) {
5884         tarval *tv;
5885         ir_node *oldn = n;
5886         ir_opcode iro = get_irn_opcode(n);
5887
5888         if (!get_opt_optimize() && !is_Phi(n)) return n;
5889
5890         /* constant expression evaluation / constant folding */
5891         if (get_opt_constant_folding()) {
5892                 /* neither constants nor Tuple values can be evaluated */
5893                 if (iro != iro_Const && get_irn_mode(n) != mode_T) {
5894                         unsigned fp_model = get_irg_fp_model(current_ir_graph);
5895                         int old_fp_mode = tarval_enable_fp_ops((fp_model & fp_strict_algebraic) == 0);
5896                         /* try to evaluate */
5897                         tv = computed_value(n);
5898                         if (tv != tarval_bad) {
5899                                 /* evaluation was successful -- replace the node. */
5900                                 ir_type *old_tp = get_irn_type(n);
5901                                 int i, arity = get_irn_arity(n);
5902
5903                                 /*
5904                                  * Try to recover the type of the new expression.
5905                                  */
5906                                 for (i = 0; i < arity && !old_tp; ++i)
5907                                         old_tp = get_irn_type(get_irn_n(n, i));
5908
5909                                 n = new_Const(get_tarval_mode(tv), tv);
5910
5911                                 if (old_tp && get_type_mode(old_tp) == get_tarval_mode(tv))
5912                                         set_Const_type(n, old_tp);
5913
5914                                 DBG_OPT_CSTEVAL(oldn, n);
5915                                 tarval_enable_fp_ops(old_fp_mode);
5916                                 return n;
5917                         }
5918                         tarval_enable_fp_ops(old_fp_mode);
5919                 }
5920         }
5921
5922         /* remove unnecessary nodes */
5923         if (get_opt_constant_folding() ||
5924             (iro == iro_Phi)  ||   /* always optimize these nodes. */
5925             (iro == iro_Id)   ||   /* ... */
5926             (iro == iro_Proj) ||   /* ... */
5927             (iro == iro_Block)  )  /* Flags tested local. */
5928                 n = equivalent_node(n);
5929
5930         /** common subexpression elimination **/
5931         /* Checks whether n is already available. */
5932         /* The block input is used to distinguish different subexpressions.  Right
5933            now all nodes are op_pin_state_pinned to blocks, i.e., the cse only finds common
5934            subexpressions within a block. */
5935         if (get_opt_cse()) {
5936                 n = identify(current_ir_graph->value_table, n);
5937         }
5938
5939         /* Some more constant expression evaluation. */
5940         iro = get_irn_opcode(n);
5941         if (get_opt_constant_folding() ||
5942                 (iro == iro_Cond) ||
5943                 (iro == iro_Proj))     /* Flags tested local. */
5944                 n = transform_node(n);
5945
5946         /* Remove nodes with dead (Bad) input.
5947            Run always for transformation induced Bads.  */
5948         n = gigo(n);
5949
5950         /* Now we can verify the node, as it has no dead inputs any more. */
5951         irn_vrfy(n);
5952
5953         /* Now we have a legal, useful node. Enter it in hash table for cse.
5954            Blocks should be unique anyways.  (Except the successor of start:
5955            is cse with the start block!) */
5956         if (get_opt_cse() && (get_irn_opcode(n) != iro_Block))
5957                 n = identify_remember(current_ir_graph->value_table, n);
5958
5959         return n;
5960 }  /* optimize_in_place_2 */
5961
5962 /**
5963  * Wrapper for external use, set proper status bits after optimization.
5964  */
5965 ir_node *optimize_in_place(ir_node *n) {
5966         /* Handle graph state */
5967         assert(get_irg_phase_state(current_ir_graph) != phase_building);
5968
5969         if (get_opt_global_cse())
5970                 set_irg_pinned(current_ir_graph, op_pin_state_floats);
5971         if (get_irg_outs_state(current_ir_graph) == outs_consistent)
5972                 set_irg_outs_inconsistent(current_ir_graph);
5973
5974         /* FIXME: Maybe we could also test whether optimizing the node can
5975            change the control graph. */
5976         set_irg_doms_inconsistent(current_ir_graph);
5977         return optimize_in_place_2(n);
5978 }  /* optimize_in_place */
5979
5980 /*
5981  * Sets the default operation for an ir_ops.
5982  */
5983 ir_op_ops *firm_set_default_operations(ir_opcode code, ir_op_ops *ops) {
5984         ops = firm_set_default_computed_value(code, ops);
5985         ops = firm_set_default_equivalent_node(code, ops);
5986         ops = firm_set_default_transform_node(code, ops);
5987         ops = firm_set_default_node_cmp_attr(code, ops);
5988         ops = firm_set_default_get_type(code, ops);
5989         ops = firm_set_default_get_type_attr(code, ops);
5990         ops = firm_set_default_get_entity_attr(code, ops);
5991
5992         return ops;
5993 }  /* firm_set_default_operations */