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