f103ddd5621051a041888e3a9b9fd19de2ba8a1e
[libfirm] / ir / ir / iropt.c
1 /*
2  * Project:     libFIRM
3  * File name:   ir/ir/iropt.c
4  * Purpose:     iropt --- optimizations intertwined with IR construction.
5  * Author:      Christian Schaefer
6  * Modified by: Goetz Lindenmaier
7  * Created:
8  * CVS-ID:      $Id$
9  * Copyright:   (c) 1998-2003 Universität Karlsruhe
10  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include <config.h>
15 #endif
16
17 # include "irnode_t.h"
18 # include "irgraph_t.h"
19 # include "iropt_t.h"
20 # include "ircons.h"
21 # include "irgmod.h"
22 # include "irvrfy.h"
23 # include "tv.h"
24 # include "dbginfo_t.h"
25 # include "iropt_dbg.h"
26 # include "irflag_t.h"
27 # include "firmstat.h"
28
29 /* Make types visible to allow most efficient access */
30 # include "entity_t.h"
31
32 /**
33  * Trivial INLINEable routine for copy propagation.
34  * Does follow Ids, needed to optimize INLINEd code.
35  */
36 static INLINE ir_node *
37 follow_Id (ir_node *n)
38 {
39   while (intern_get_irn_op (n) == op_Id) n = get_Id_pred (n);
40   return n;
41 }
42
43 /**
44  * Returns the tarval of a Const node or tarval_bad for all other nodes.
45  */
46 static INLINE tarval *
47 value_of (ir_node *n)
48 {
49   if ((n != NULL) && (intern_get_irn_op(n) == op_Const))
50     return get_Const_tarval(n); /* might return tarval_bad */
51   else
52     return tarval_bad;
53 }
54
55 static tarval *computed_value_Const(ir_node *n)
56 {
57     return get_Const_tarval(n);
58 }
59
60 static tarval *computed_value_SymConst(ir_node *n)
61 {
62   if ((get_SymConst_kind(n) == size) &&
63       (get_type_state(get_SymConst_type(n))) == layout_fixed)
64     return new_tarval_from_long (get_type_size(get_SymConst_type(n)), mode_Is);
65   return tarval_bad;
66 }
67
68 static tarval *computed_value_Add(ir_node *n)
69 {
70   ir_node *a = get_Add_left(n);
71   ir_node *b = get_Add_right(n);
72
73   tarval *ta = value_of(a);
74   tarval *tb = value_of(b);
75
76   if ((ta != tarval_bad) && (tb != tarval_bad)
77         && (intern_get_irn_mode(a) == intern_get_irn_mode(b))
78         && !(get_mode_sort(intern_get_irn_mode(a)) == irms_reference)) {
79     return tarval_add(ta, tb);
80   }
81   return tarval_bad;
82 }
83
84 static tarval *computed_value_Sub(ir_node *n)
85 {
86   ir_node *a = get_Sub_left(n);
87   ir_node *b = get_Sub_right(n);
88
89   tarval *ta = value_of(a);
90   tarval *tb = value_of(b);
91
92   if ((ta != tarval_bad) && (tb != tarval_bad)
93         && (intern_get_irn_mode(a) == intern_get_irn_mode(b))
94         && !(get_mode_sort(intern_get_irn_mode(a)) == irms_reference)) {
95     return tarval_sub(ta, tb);
96   }
97   return tarval_bad;
98 }
99
100 static tarval *computed_value_Minus(ir_node *n)
101 {
102   ir_node *a = get_Minus_op(n);
103   tarval *ta = value_of(a);
104
105   if ((ta != tarval_bad) && mode_is_signed(intern_get_irn_mode(a)))
106     return tarval_neg(ta);
107
108   return tarval_bad;
109 }
110
111 static tarval *computed_value_Mul(ir_node *n)
112 {
113   ir_node *a = get_Mul_left(n);
114   ir_node *b = get_Mul_right(n);
115
116   tarval *ta = value_of(a);
117   tarval *tb = value_of(b);
118
119   if ((ta != tarval_bad) && (tb != tarval_bad) && (intern_get_irn_mode(a) == intern_get_irn_mode(b))) {
120     return tarval_mul(ta, tb);
121   } else {
122     /* a*0 = 0 or 0*b = 0:
123        calls computed_value recursive and returns the 0 with proper
124        mode. */
125     tarval *v;
126
127     if ( ( ((v = ta) != tarval_bad)
128              && (v == get_mode_null(get_tarval_mode(v))) )
129       || ( ((v = tb) != tarval_bad)
130              && (v == get_mode_null(get_tarval_mode(v))) )) {
131         return v;
132     }
133   }
134   return tarval_bad;
135 }
136
137 static tarval *computed_value_Quot(ir_node *n)
138 {
139   ir_node *a = get_Quot_left(n);
140   ir_node *b = get_Quot_right(n);
141
142   tarval *ta = value_of(a);
143   tarval *tb = value_of(b);
144
145   /* This was missing in original implementation. Why? */
146   if ((ta != tarval_bad) && (tb != tarval_bad) && (intern_get_irn_mode(a) == intern_get_irn_mode(b))) {
147     if (tb != get_mode_null(get_tarval_mode(tb)))   /* div by zero: return tarval_bad */
148       return tarval_quo(ta, tb);
149   }
150   return tarval_bad;
151 }
152
153 static tarval *computed_value_Div(ir_node *n)
154 {
155   ir_node *a = get_Div_left(n);
156   ir_node *b = get_Div_right(n);
157
158   tarval *ta = value_of(a);
159   tarval *tb = value_of(b);
160
161   /* This was missing in original implementation. Why? */
162   if ((ta != tarval_bad) && (tb != tarval_bad) && (intern_get_irn_mode(a) == intern_get_irn_mode(b))) {
163     if (tb != get_mode_null(get_tarval_mode(tb)))   /* div by zero: return tarval_bad */
164       return tarval_div(ta, tb);
165   }
166   return tarval_bad;
167 }
168
169 static tarval *computed_value_Mod(ir_node *n)
170 {
171   ir_node *a = get_Mod_left(n);
172   ir_node *b = get_Mod_right(n);
173
174   tarval *ta = value_of(a);
175   tarval *tb = value_of(b);
176
177   /* This was missing in original implementation. Why? */
178   if ((ta != tarval_bad) && (tb != tarval_bad) && (intern_get_irn_mode(a) == intern_get_irn_mode(b))) {
179     if (tb != get_mode_null(get_tarval_mode(tb)))   /* div by zero: return tarval_bad */
180       return tarval_mod(ta, tb);
181   }
182   return tarval_bad;
183 }
184
185 static tarval *computed_value_Abs(ir_node *n)
186 {
187   ir_node *a = get_Abs_op(n);
188   tarval *ta = value_of(a);
189
190   if (ta != tarval_bad)
191     return tarval_abs(ta);
192
193   return tarval_bad;
194 }
195
196 static tarval *computed_value_And(ir_node *n)
197 {
198   ir_node *a = get_And_left(n);
199   ir_node *b = get_And_right(n);
200
201   tarval *ta = value_of(a);
202   tarval *tb = value_of(b);
203
204   if ((ta != tarval_bad) && (tb != tarval_bad)) {
205     return tarval_and (ta, tb);
206   } else {
207     tarval *v;
208
209     if (   (tarval_classify ((v = computed_value (a))) == TV_CLASSIFY_NULL)
210         || (tarval_classify ((v = computed_value (b))) == TV_CLASSIFY_NULL)) {
211       return v;
212     }
213   }
214   return tarval_bad;
215 }
216
217 static tarval *computed_value_Or(ir_node *n)
218 {
219   ir_node *a = get_Or_left(n);
220   ir_node *b = get_Or_right(n);
221
222   tarval *ta = value_of(a);
223   tarval *tb = value_of(b);
224
225   if ((ta != tarval_bad) && (tb != tarval_bad)) {
226     return tarval_or (ta, tb);
227   } else {
228     tarval *v;
229     if (   (tarval_classify ((v = computed_value (a))) == TV_CLASSIFY_ALL_ONE)
230         || (tarval_classify ((v = computed_value (b))) == TV_CLASSIFY_ALL_ONE)) {
231       return v;
232     }
233   }
234   return tarval_bad;
235 }
236
237 static tarval *computed_value_Eor(ir_node *n)
238 {
239   ir_node *a = get_Eor_left(n);
240   ir_node *b = get_Eor_right(n);
241
242   tarval *ta = value_of(a);
243   tarval *tb = value_of(b);
244
245   if ((ta != tarval_bad) && (tb != tarval_bad)) {
246     return tarval_eor (ta, tb);
247   }
248   return tarval_bad;
249 }
250
251 static tarval *computed_value_Not(ir_node *n)
252 {
253   ir_node *a = get_Not_op(n);
254   tarval *ta = value_of(a);
255
256   if (ta != tarval_bad)
257     return tarval_not(ta);
258
259   return tarval_bad;
260 }
261
262 static tarval *computed_value_Shl(ir_node *n)
263 {
264   ir_node *a = get_Shl_left(n);
265   ir_node *b = get_Shl_right(n);
266
267   tarval *ta = value_of(a);
268   tarval *tb = value_of(b);
269
270   if ((ta != tarval_bad) && (tb != tarval_bad)) {
271     return tarval_shl (ta, tb);
272   }
273   return tarval_bad;
274 }
275
276 static tarval *computed_value_Shr(ir_node *n)
277 {
278   ir_node *a = get_Shr_left(n);
279   ir_node *b = get_Shr_right(n);
280
281   tarval *ta = value_of(a);
282   tarval *tb = value_of(b);
283
284   if ((ta != tarval_bad) && (tb != tarval_bad)) {
285     return tarval_shr (ta, tb);
286   }
287   return tarval_bad;
288 }
289
290 static tarval *computed_value_Shrs(ir_node *n)
291 {
292   ir_node *a = get_Shrs_left(n);
293   ir_node *b = get_Shrs_right(n);
294
295   tarval *ta = value_of(a);
296   tarval *tb = value_of(b);
297
298   if ((ta != tarval_bad) && (tb != tarval_bad)) {
299     return tarval_shrs (ta, tb);
300   }
301   return tarval_bad;
302 }
303
304 static tarval *computed_value_Rot(ir_node *n)
305 {
306   ir_node *a = get_Rot_left(n);
307   ir_node *b = get_Rot_right(n);
308
309   tarval *ta = value_of(a);
310   tarval *tb = value_of(b);
311
312   if ((ta != tarval_bad) && (tb != tarval_bad)) {
313     /* return tarval_rot (ta, tb); */
314   }
315   return tarval_bad;
316 }
317
318 static tarval *computed_value_Conv(ir_node *n)
319 {
320   ir_node *a = get_Conv_op(n);
321   tarval *ta = value_of(a);
322
323   if (ta != tarval_bad)
324     return tarval_convert_to(ta, intern_get_irn_mode(n));
325
326   return tarval_bad;
327 }
328
329 static tarval *computed_value_Proj(ir_node *n)
330 {
331   ir_node *a = get_Proj_pred(n), *b;
332   ir_node *aa, *ab;
333
334   /* Optimize Cmp nodes.
335      This performs a first step of unreachable code elimination.
336      Proj can not be computed, but folding a Cmp above the Proj here is
337      not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
338      only 1 is used.
339      There are several case where we can evaluate a Cmp node:
340      1. The nodes compared are both the same.  If we compare for
341         equal, greater equal, ... this will return true, else it
342         will return false.  This step relies on cse.
343      2. The predecessors of Cmp are target values.  We can evaluate
344         the Cmp.
345      3. The predecessors are Allocs or void* constants.  Allocs never
346         return NULL, they raise an exception.   Therefore we can predict
347         the Cmp result. */
348   if (intern_get_irn_op(a) == op_Cmp) {
349     aa = get_Cmp_left(a);
350     ab = get_Cmp_right(a);
351
352     if (aa == ab) { /* 1.: */
353       /* This is a tric with the bits used for encoding the Cmp
354          Proj numbers, the following statement is not the same:
355       return new_tarval_from_long ((get_Proj_proj(n) == Eq), mode_b) */
356       return new_tarval_from_long ((get_Proj_proj(n) & Eq), mode_b);
357     } else {
358       tarval *taa = computed_value (aa);
359       tarval *tab = computed_value (ab);
360
361       if ((taa != tarval_bad) && (tab != tarval_bad)) { /* 2.: */
362         /* strange checks... */
363         pnc_number flags = tarval_cmp (taa, tab);
364         if (flags != False) {
365           return new_tarval_from_long (get_Proj_proj(n) & flags, mode_b);
366         }
367       } else {  /* check for 3.: */
368         ir_node *aaa = skip_nop(skip_Proj(aa));
369         ir_node *aba = skip_nop(skip_Proj(ab));
370
371         if (   (   (/* aa is ProjP and aaa is Alloc */
372                        (intern_get_irn_op(aa) == op_Proj)
373                     && (mode_is_reference(intern_get_irn_mode(aa)))
374                     && (intern_get_irn_op(aaa) == op_Alloc))
375                 && (   (/* ab is constant void */
376                            (intern_get_irn_op(ab) == op_Const)
377                         && (mode_is_reference(intern_get_irn_mode(ab)))
378                         && (get_Const_tarval(ab) == get_mode_null(intern_get_irn_mode(ab))))
379                     || (/* ab is other Alloc */
380                            (intern_get_irn_op(ab) == op_Proj)
381                         && (mode_is_reference(intern_get_irn_mode(ab)))
382                         && (intern_get_irn_op(aba) == op_Alloc)
383                         && (aaa != aba))))
384             || (/* aa is void and aba is Alloc */
385                    (intern_get_irn_op(aa) == op_Const)
386                 && (mode_is_reference(intern_get_irn_mode(aa)))
387                 && (get_Const_tarval(aa) == get_mode_null(intern_get_irn_mode(aa)))
388                 && (intern_get_irn_op(ab) == op_Proj)
389                 && (mode_is_reference(intern_get_irn_mode(ab)))
390                 && (intern_get_irn_op(aba) == op_Alloc)))
391           /* 3.: */
392           return new_tarval_from_long (get_Proj_proj(n) & Ne, mode_b);
393       }
394     }
395   } else if (intern_get_irn_op(a) == op_DivMod) {
396     tarval *tb = value_of(b = get_DivMod_right(a));
397     tarval *ta = value_of(a = get_DivMod_left(a));
398
399     if ((ta != tarval_bad)  && (tb != tarval_bad) && (intern_get_irn_mode(a) == intern_get_irn_mode(b))) {
400       if (tb == get_mode_null(get_tarval_mode(tb)))  /* div by zero: return tarval_bad */
401         return tarval_bad;
402       if (get_Proj_proj(n)== 0) /* Div */
403         return tarval_div(ta, tb);
404       else /* Mod */
405         return tarval_mod(ta, tb);
406     }
407   }
408   return tarval_bad;
409 }
410
411 /**
412  * If the parameter n can be computed, return its value, else tarval_bad.
413  * Performs constant folding.
414  *
415  * GL: Only if n is arithmetic operator?
416  */
417 tarval *computed_value(ir_node *n)
418 {
419   if (n->op->computed_value)
420     return n->op->computed_value(n);
421   return tarval_bad;
422 }
423
424 /**
425  * set the default computed_value evaluator
426  */
427 static ir_op *firm_set_default_computed_value(ir_op *op)
428 {
429 #define CASE(a)                                 \
430   case iro_##a:                                 \
431     op->computed_value  = computed_value_##a;   \
432     break
433
434   switch (op->code) {
435   CASE(Const);
436   CASE(SymConst);
437   CASE(Add);
438   CASE(Sub);
439   CASE(Minus);
440   CASE(Mul);
441   CASE(Quot);
442   CASE(Div);
443   CASE(Mod);
444   CASE(Abs);
445   CASE(And);
446   CASE(Or);
447   CASE(Eor);
448   CASE(Not);
449   CASE(Shl);
450   CASE(Shr);
451   CASE(Shrs);
452   CASE(Rot);
453   CASE(Conv);
454   CASE(Proj);
455   default:
456     op->computed_value  = NULL;
457   }
458
459   return op;
460 #undef CASE
461 }
462
463 #if 0
464 /* returns 1 if the a and b are pointers to different locations. */
465 static bool
466 different_identity (ir_node *a, ir_node *b)
467 {
468   assert (mode_is_reference(get_irn_mode (a))
469           && mode_is_reference(get_irn_mode (b)));
470
471   if (intern_get_irn_op (a) == op_Proj && intern_get_irn_op(b) == op_Proj) {
472     ir_node *a1 = get_Proj_pred (a);
473     ir_node *b1 = get_Proj_pred (b);
474     if (a1 != b1 && intern_get_irn_op (a1) == op_Alloc
475                 && intern_get_irn_op (b1) == op_Alloc)
476       return 1;
477   }
478   return 0;
479 }
480 #endif
481
482 static ir_node *equivalent_node_Block(ir_node *n)
483 {
484   ir_node *oldn = n;
485
486   /* The Block constructor does not call optimize, but mature_block
487      calls the optimization. */
488   assert(get_Block_matured(n));
489
490   /* Straightening: a single entry Block following a single exit Block
491      can be merged, if it is not the Start block. */
492   /* !!! Beware, all Phi-nodes of n must have been optimized away.
493      This should be true, as the block is matured before optimize is called.
494      But what about Phi-cycles with the Phi0/Id that could not be resolved?
495      Remaining Phi nodes are just Ids. */
496   if ((get_Block_n_cfgpreds(n) == 1) &&
497       (intern_get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) &&
498       (get_opt_control_flow_straightening())) {
499     n = get_nodes_Block(get_Block_cfgpred(n, 0));                     DBG_OPT_STG;
500
501   } else if ((get_Block_n_cfgpreds(n) == 2) &&
502              (get_opt_control_flow_weak_simplification())) {
503     /* Test whether Cond jumps twice to this block
504        @@@ we could do this also with two loops finding two preds from several ones. */
505     ir_node *a = get_Block_cfgpred(n, 0);
506     ir_node *b = get_Block_cfgpred(n, 1);
507
508     if ((intern_get_irn_op(a) == op_Proj) &&
509         (intern_get_irn_op(b) == op_Proj) &&
510         (get_Proj_pred(a) == get_Proj_pred(b)) &&
511         (intern_get_irn_op(get_Proj_pred(a)) == op_Cond) &&
512         (intern_get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
513       /* Also a single entry Block following a single exit Block.  Phis have
514          twice the same operand and will be optimized away. */
515       n = get_nodes_Block(a);                                         DBG_OPT_IFSIM;
516     }
517   } else if (get_opt_unreachable_code() &&
518              (n != current_ir_graph->start_block) &&
519              (n != current_ir_graph->end_block)     ) {
520     int i;
521     /* If all inputs are dead, this block is dead too, except if it is
522        the start or end block.  This is a step of unreachable code
523        elimination */
524     for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
525       if (!is_Bad(get_Block_cfgpred(n, i))) break;
526     }
527     if (i == get_Block_n_cfgpreds(n))
528       n = new_Bad();
529   }
530
531   return n;
532 }
533
534 static ir_node *equivalent_node_Jmp(ir_node *n)
535 {
536   /* GL: Why not same for op_Raise?? */
537   /* unreachable code elimination */
538   if (is_Bad(get_nodes_Block(n)))
539     n = new_Bad();
540
541   return n;
542 }
543
544 static ir_node *equivalent_node_Cond(ir_node *n)
545 {
546   /* We do not evaluate Cond here as we replace it by a new node, a Jmp.
547      See cases for iro_Cond and iro_Proj in transform_node. */
548   return n;
549 }
550
551 static ir_node *equivalent_node_Or(ir_node *n)
552 {
553   ir_node *oldn = n;
554
555   ir_node *a = get_Or_left(n);
556   ir_node *b = get_Or_right(n);
557
558   /* remove a v a */
559   if (a == b) {
560     n = a;                                                             DBG_OPT_ALGSIM1;
561   }
562
563   return n;
564 }
565
566 /**
567  * optimize operations that are commutative and have neutral 0.
568  */
569 static ir_node *equivalent_node_neutral_zero(ir_node *n)
570 {
571   ir_node *oldn = n;
572
573   ir_node *a = get_binop_left(n);
574   ir_node *b = get_binop_right(n);
575
576   tarval *tv;
577   ir_node *on;
578
579   /* After running compute_node there is only one constant predecessor.
580      Find this predecessors value and remember the other node: */
581   if ((tv = computed_value (a)) != tarval_bad) {
582     on = b;
583   } else if ((tv = computed_value (b)) != tarval_bad) {
584     on = a;
585   } else
586     return n;
587
588   /* If this predecessors constant value is zero, the operation is
589      unnecessary. Remove it: */
590   if (tarval_classify (tv) == TV_CLASSIFY_NULL) {
591     n = on;                                                             DBG_OPT_ALGSIM1;
592   }
593
594   return n;
595 }
596
597 static ir_node *equivalent_node_Add(ir_node *n)
598 {
599   return equivalent_node_neutral_zero(n);
600 }
601
602 static ir_node *equivalent_node_Eor(ir_node *n)
603 {
604   return equivalent_node_neutral_zero(n);
605 }
606
607 /**
608  * optimize operations that are not commutative but have neutral 0 on left.
609  * Test only one predecessor.
610  */
611 static ir_node *equivalent_node_left_zero(ir_node *n)
612 {
613   ir_node *oldn = n;
614
615   ir_node *a = get_binop_left(n);
616   ir_node *b = get_binop_right(n);
617
618   if (tarval_classify (computed_value (b)) == TV_CLASSIFY_NULL) {
619     n = a;                                                              DBG_OPT_ALGSIM1;
620   }
621
622   return n;
623 }
624
625 static ir_node *equivalent_node_Sub(ir_node *n)
626 {
627   return equivalent_node_left_zero(n);
628 }
629
630 static ir_node *equivalent_node_Shl(ir_node *n)
631 {
632   return equivalent_node_left_zero(n);
633 }
634
635 static ir_node *equivalent_node_Shr(ir_node *n)
636 {
637   return equivalent_node_left_zero(n);
638 }
639
640 static ir_node *equivalent_node_Shrs(ir_node *n)
641 {
642   return equivalent_node_left_zero(n);
643 }
644
645 static ir_node *equivalent_node_Rot(ir_node *n)
646 {
647   return equivalent_node_left_zero(n);
648 }
649
650 static ir_node *equivalent_node_symmetric_unop(ir_node *n)
651 {
652   ir_node *oldn = n;
653
654   /* optimize symmetric unop */
655   if (intern_get_irn_op(get_unop_op(n)) == intern_get_irn_op(n)) {
656     n = get_unop_op(get_unop_op(n));                                    DBG_OPT_ALGSIM2;
657   }
658   return n;
659 }
660
661 static ir_node *equivalent_node_Not(ir_node *n)
662 {
663   /* NotNot x == x */
664   return equivalent_node_symmetric_unop(n);
665 }
666
667 static ir_node *equivalent_node_Minus(ir_node *n)
668 {
669   /* --x == x */  /* ??? Is this possible or can --x raise an
670                          out of bounds exception if min =! max? */
671   return equivalent_node_symmetric_unop(n);
672 }
673
674 static ir_node *equivalent_node_Mul(ir_node *n)
675 {
676   ir_node *oldn = n;
677
678   ir_node *a = get_Mul_left(n);
679   ir_node *b = get_Mul_right(n);
680
681   /* Mul is commutative and has again an other neutral element. */
682   if (tarval_classify (computed_value (a)) == TV_CLASSIFY_ONE) {
683     n = b;                                                              DBG_OPT_ALGSIM1;
684   } else if (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE) {
685     n = a;                                                              DBG_OPT_ALGSIM1;
686   }
687   return n;
688 }
689
690 static ir_node *equivalent_node_Div(ir_node *n)
691 {
692   ir_node *a = get_Div_left(n);
693   ir_node *b = get_Div_right(n);
694
695   /* Div is not commutative. */
696   if (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
697     /* Turn Div into a tuple (mem, bad, a) */
698     ir_node *mem = get_Div_mem(n);
699     turn_into_tuple(n, 3);
700     set_Tuple_pred(n, pn_Div_M,        mem);
701     set_Tuple_pred(n, pn_Div_X_except, new_Bad());      /* no exception */
702     set_Tuple_pred(n, pn_Div_res,      a);
703   }
704   return n;
705 }
706
707 static ir_node *equivalent_node_And(ir_node *n)
708 {
709   ir_node *oldn = n;
710
711   ir_node *a = get_And_left(n);
712   ir_node *b = get_And_right(n);
713
714   if (a == b) {
715     n = a;    /* And has it's own neutral element */
716   } else if (tarval_classify (computed_value (a)) == TV_CLASSIFY_ALL_ONE) {
717     n = b;
718   } else if (tarval_classify (computed_value (b)) == TV_CLASSIFY_ALL_ONE) {
719     n = a;
720   }
721   if (n != oldn)                                                        DBG_OPT_ALGSIM1;
722   return n;
723 }
724
725 static ir_node *equivalent_node_Conv(ir_node *n)
726 {
727   ir_node *oldn = n;
728   ir_node *a = get_Conv_op(n);
729   ir_node *b;
730
731   ir_mode *n_mode = intern_get_irn_mode(n);
732   ir_mode *a_mode = intern_get_irn_mode(a);
733
734   if (n_mode == a_mode) { /* No Conv necessary */
735     n = a;                                                              DBG_OPT_ALGSIM3;
736   } else if (intern_get_irn_op(a) == op_Conv) { /* Conv(Conv(b)) */
737     ir_mode *b_mode;
738
739     b = get_Conv_op(a);
740     n_mode = intern_get_irn_mode(n);
741     b_mode = intern_get_irn_mode(b);
742
743     if (n_mode == b_mode) {
744       if (n_mode == mode_b) {
745         n = b;  /* Convb(Conv*(xxxb(...))) == xxxb(...) */              DBG_OPT_ALGSIM1;
746       }
747       else if (mode_is_int(n_mode) || mode_is_character(n_mode)) {
748         if (smaller_mode(b_mode, a_mode)){
749           n = b;        /* ConvS(ConvL(xxxS(...))) == xxxS(...) */      DBG_OPT_ALGSIM1;
750         }
751       }
752     }
753   }
754   return n;
755 }
756
757 static ir_node *equivalent_node_Phi(ir_node *n)
758 {
759   /* Several optimizations:
760      - no Phi in start block.
761      - remove Id operators that are inputs to Phi
762      - fold Phi-nodes, iff they have only one predecessor except
763              themselves.
764   */
765   int i, n_preds;
766
767   ir_node *oldn = n;
768   ir_node *block = NULL;     /* to shutup gcc */
769   ir_node *first_val = NULL; /* to shutup gcc */
770   ir_node *scnd_val = NULL;  /* to shutup gcc */
771
772   if (!get_opt_normalize()) return n;
773
774   n_preds = get_Phi_n_preds(n);
775
776   block = get_nodes_Block(n);
777   /* @@@ fliegt 'raus, sollte aber doch immer wahr sein!!!
778      assert(get_irn_arity(block) == n_preds && "phi in wrong block!"); */
779   if ((is_Bad(block)) ||                         /* Control dead */
780       (block == current_ir_graph->start_block))  /* There should be no Phi nodes */
781     return new_Bad();                        /* in the Start Block. */
782
783   if (n_preds == 0) return n;           /* Phi of dead Region without predecessors. */
784
785 #if 0
786   /* first we test for a special case: */
787   /* Confirm is a special node fixing additional information for a
788      value that is known at a certain point.  This is useful for
789      dataflow analysis. */
790   if (n_preds == 2) {
791     ir_node *a = follow_Id (get_Phi_pred(n, 0));
792     ir_node *b = follow_Id (get_Phi_pred(n, 1));
793     if (   (intern_get_irn_op(a) == op_Confirm)
794         && (intern_get_irn_op(b) == op_Confirm)
795         && follow_Id (intern_get_irn_n(a, 0) == intern_get_irn_n(b, 0))
796         && (intern_get_irn_n(a, 1) == intern_get_irn_n (b, 1))
797         && (a->data.num == (~b->data.num & irpn_True) )) {
798       return intern_get_irn_n(a, 0);
799     }
800   }
801 #endif
802
803   /* Find first non-self-referencing input */
804   for (i = 0;  i < n_preds;  ++i) {
805     first_val = follow_Id(get_Phi_pred(n, i));
806     /* skip Id's */
807     set_Phi_pred(n, i, first_val);
808     if (   (first_val != n)                            /* not self pointer */
809         && (intern_get_irn_op(first_val) != op_Bad)           /* value not dead */
810         && !(is_Bad (get_Block_cfgpred(block, i))) ) { /* not dead control flow */
811       break;                         /* then found first value. */
812     }
813   }
814
815   /* A totally Bad or self-referencing Phi (we didn't break the above loop) */
816   if (i >= n_preds) { return new_Bad(); }
817
818   scnd_val = NULL;
819
820   /* follow_Id () for rest of inputs, determine if any of these
821      are non-self-referencing */
822   while (++i < n_preds) {
823     scnd_val = follow_Id(get_Phi_pred(n, i));
824     /* skip Id's */
825     set_Phi_pred(n, i, scnd_val);
826     if (   (scnd_val != n)
827         && (scnd_val != first_val)
828         && (intern_get_irn_op(scnd_val) != op_Bad)
829         && !(is_Bad (get_Block_cfgpred(block, i))) ) {
830       break;
831     }
832   }
833
834   /* Fold, if no multiple distinct non-self-referencing inputs */
835   if (i >= n_preds) {
836     n = first_val;                                     DBG_OPT_PHI;
837   } else {
838     /* skip the remaining Ids. */
839     while (++i < n_preds) {
840       set_Phi_pred(n, i, follow_Id(get_Phi_pred(n, i)));
841     }
842   }
843   return n;
844 }
845
846 static ir_node *equivalent_node_Load(ir_node *n)
847 {
848 #if 0  /* Is an illegal transformation: different nodes can
849           represent the same pointer value!! */
850  ir_node *a = skip_Proj(get_Load_mem(n));
851  ir_node *b = get_Load_ptr(n);
852
853  if (intern_get_irn_op(a) == op_Store) {
854    if ( different_identity (b, get_Store_ptr(a))) {
855          /* load and store use different pointers, therefore load
856                 needs not take store's memory but the state before. */
857          set_Load_mem (n, get_Store_mem(a));
858    } else if (( 0 /* ???didn't get cryptic test that returns 0 */ )) {
859    }
860  }
861 #endif
862  return n;
863 }
864
865 static ir_node *equivalent_node_Store(ir_node *n)
866 {
867   ir_node *oldn = n;
868
869   /* remove unnecessary store. */
870   ir_node *a = skip_Proj(get_Store_mem(n));
871   ir_node *b = get_Store_ptr(n);
872   ir_node *c = skip_Proj(get_Store_value(n));
873
874   if (intern_get_irn_op(a) == op_Store
875       && get_Store_ptr(a) == b
876       && skip_Proj(get_Store_value(a)) == c) {
877     /* We have twice exactly the same store -- a write after write. */
878     n = a;                                                         DBG_OPT_WAW;
879   } else if (intern_get_irn_op(c) == op_Load
880              && (a == c || skip_Proj(get_Load_mem(c)) == a)
881              && get_Load_ptr(c) == b ) {
882     /* We just loaded the value from the same memory, i.e., the store
883        doesn't change the memory -- a write after read. */
884     a = get_Store_mem(n);
885     turn_into_tuple(n, 2);
886     set_Tuple_pred(n, pn_Store_M,        a);
887     set_Tuple_pred(n, pn_Store_X_except, new_Bad());               DBG_OPT_WAR;
888   }
889   return n;
890 }
891
892 static ir_node *equivalent_node_Proj(ir_node *n)
893 {
894   ir_node *oldn = n;
895
896   ir_node *a = get_Proj_pred(n);
897
898   if ( intern_get_irn_op(a) == op_Tuple) {
899     /* Remove the Tuple/Proj combination. */
900     if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
901       n = get_Tuple_pred(a, get_Proj_proj(n));                     DBG_OPT_TUPLE;
902     } else {
903       assert(0); /* This should not happen! */
904       n = new_Bad();
905     }
906   } else if (intern_get_irn_mode(n) == mode_X &&
907              is_Bad(get_nodes_Block(n))) {
908     /* Remove dead control flow -- early gigo. */
909     n = new_Bad();
910   }
911   return n;
912 }
913
914 static ir_node *equivalent_node_Id(ir_node *n)
915 {
916   ir_node *oldn = n;
917
918   n = follow_Id (n);                                                 DBG_OPT_ID;
919   return n;
920 }
921
922 /*
923 case iro_Mod, Quot, DivMod
924   DivMod allocates new nodes --> it's treated in transform node.
925   What about Quot, DivMod?
926 */
927
928 /**
929  * equivalent_node() returns a node equivalent to input n. It skips all nodes that
930  * perform no actual computation, as, e.g., the Id nodes.  It does not create
931  * new nodes.  It is therefore safe to free n if the node returned is not n.
932  * If a node returns a Tuple we can not just skip it.  If the size of the
933  * in array fits, we transform n into a tuple (e.g., Div).
934  */
935 ir_node *
936 equivalent_node (ir_node *n)
937 {
938   if (n->op->equivalent_node)
939     return n->op->equivalent_node(n);
940   return n;
941 }
942
943 /**
944  * set the default equivalent node operation
945  */
946 static ir_op *firm_set_default_equivalent_node(ir_op *op)
947 {
948 #define CASE(a)                                 \
949   case iro_##a:                                 \
950     op->equivalent_node  = equivalent_node_##a; \
951     break
952
953   switch (op->code) {
954   CASE(Block);
955   CASE(Jmp);
956   CASE(Cond);
957   CASE(Or);
958   CASE(Add);
959   CASE(Eor);
960   CASE(Sub);
961   CASE(Shl);
962   CASE(Shr);
963   CASE(Shrs);
964   CASE(Rot);
965   CASE(Not);
966   CASE(Minus);
967   CASE(Mul);
968   CASE(Div);
969   CASE(And);
970   CASE(Conv);
971   CASE(Phi);
972   CASE(Load);
973   CASE(Store);
974   CASE(Proj);
975   CASE(Id);
976   default:
977     op->equivalent_node  = NULL;
978   }
979
980   return op;
981 #undef CASE
982 }
983
984 /**
985  * Do node specific optimizations of nodes predecessors.
986  */
987 static void
988 optimize_preds(ir_node *n) {
989   ir_node *a = NULL, *b = NULL;
990
991   /* get the operands we will work on for simple cases. */
992   if (is_binop(n)) {
993     a = get_binop_left(n);
994     b = get_binop_right(n);
995   } else if (is_unop(n)) {
996     a = get_unop_op(n);
997   }
998
999   switch (intern_get_irn_opcode(n)) {
1000
1001   case iro_Cmp:
1002     /* We don't want Cast as input to Cmp. */
1003     if (intern_get_irn_op(a) == op_Cast) {
1004       a = get_Cast_op(a);
1005       set_Cmp_left(n, a);
1006     }
1007     if (intern_get_irn_op(b) == op_Cast) {
1008       b = get_Cast_op(b);
1009       set_Cmp_right(n, b);
1010     }
1011     break;
1012
1013   default: break;
1014   } /* end switch */
1015 }
1016
1017 static ir_node *transform_node_Div(ir_node *n)
1018 {
1019   tarval *ta = computed_value(n);
1020
1021   if (ta != tarval_bad) {
1022     /* Turn Div into a tuple (mem, bad, value) */
1023     ir_node *mem = get_Div_mem(n);
1024
1025     turn_into_tuple(n, 3);
1026     set_Tuple_pred(n, pn_Div_M, mem);
1027     set_Tuple_pred(n, pn_Div_X_except, new_Bad());
1028     set_Tuple_pred(n, pn_Div_res, new_Const(get_tarval_mode(ta), ta));
1029   }
1030   return n;
1031 }
1032
1033 static ir_node *transform_node_Mod(ir_node *n)
1034 {
1035   tarval *ta = computed_value(n);
1036
1037   if (ta != tarval_bad) {
1038     /* Turn Mod into a tuple (mem, bad, value) */
1039     ir_node *mem = get_Mod_mem(n);
1040     turn_into_tuple(n, 3);
1041     set_Tuple_pred(n, pn_Mod_M, mem);
1042     set_Tuple_pred(n, pn_Mod_X_except, new_Bad());
1043     set_Tuple_pred(n, pn_Mod_res, new_Const(get_tarval_mode(ta), ta));
1044   }
1045   return n;
1046 }
1047
1048 static ir_node *transform_node_DivMod(ir_node *n)
1049 {
1050   int evaluated = 0;
1051
1052   ir_node *a = get_DivMod_left(n);
1053   ir_node *b = get_DivMod_right(n);
1054   ir_mode *mode = intern_get_irn_mode(a);
1055
1056   if (!(mode_is_int(mode) && mode_is_int(intern_get_irn_mode(b))))
1057     return n;
1058
1059   if (a == b) {
1060     a = new_Const(mode, get_mode_one(mode));
1061     b = new_Const(mode, get_mode_null(mode));
1062     evaluated = 1;
1063   } else {
1064     tarval *ta = value_of(a);
1065     tarval *tb = value_of(b);
1066
1067     if (tb != tarval_bad) {
1068       if (tb == get_mode_one(get_tarval_mode(tb))) {
1069         b = new_Const (mode, get_mode_null(mode));
1070         evaluated = 1;
1071       } else if (ta != tarval_bad) {
1072         tarval *resa, *resb;
1073         resa = tarval_div (ta, tb);
1074         if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
1075                                           Jmp for X result!? */
1076         resb = tarval_mod (ta, tb);
1077         if (resb == tarval_bad) return n; /* Causes exception! */
1078         a = new_Const (mode, resa);
1079         b = new_Const (mode, resb);
1080         evaluated = 1;
1081       }
1082     } else if (ta == get_mode_null(get_tarval_mode(ta))) {
1083       b = a;
1084       evaluated = 1;
1085     }
1086   }
1087   if (evaluated) { /* replace by tuple */
1088     ir_node *mem = get_DivMod_mem(n);
1089     turn_into_tuple(n, 4);
1090     set_Tuple_pred(n, pn_DivMod_M,        mem);
1091     set_Tuple_pred(n, pn_DivMod_X_except, new_Bad());  /* no exception */
1092     set_Tuple_pred(n, pn_DivMod_res_div,  a);
1093     set_Tuple_pred(n, pn_DivMod_res_mod,  b);
1094     assert(get_nodes_Block(n));
1095   }
1096
1097   return n;
1098 }
1099
1100 static ir_node *transform_node_Cond(ir_node *n)
1101 {
1102   /* Replace the Cond by a Jmp if it branches on a constant
1103      condition. */
1104   ir_node *jmp;
1105   ir_node *a = get_Cond_selector(n);
1106   tarval *ta = value_of(a);
1107
1108   if ((ta != tarval_bad) &&
1109       (intern_get_irn_mode(a) == mode_b) &&
1110       (get_opt_unreachable_code())) {
1111     /* It's a boolean Cond, branching on a boolean constant.
1112                Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
1113     jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
1114     turn_into_tuple(n, 2);
1115     if (ta == tarval_b_true) {
1116       set_Tuple_pred(n, pn_Cond_false, new_Bad());
1117       set_Tuple_pred(n, pn_Cond_true, jmp);
1118     } else {
1119       set_Tuple_pred(n, pn_Cond_false, jmp);
1120       set_Tuple_pred(n, pn_Cond_true, new_Bad());
1121     }
1122     /* We might generate an endless loop, so keep it alive. */
1123     add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
1124   } else if ((ta != tarval_bad) &&
1125              (intern_get_irn_mode(a) == mode_Iu) &&
1126              (get_Cond_kind(n) == dense) &&
1127              (get_opt_unreachable_code())) {
1128     /* I don't want to allow Tuples smaller than the biggest Proj.
1129        Also this tuple might get really big...
1130        I generate the Jmp here, and remember it in link.  Link is used
1131        when optimizing Proj. */
1132     set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
1133     /* We might generate an endless loop, so keep it alive. */
1134     add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
1135   } else if ((intern_get_irn_op(a) == op_Eor)
1136              && (intern_get_irn_mode(a) == mode_b)
1137              && (tarval_classify(computed_value(get_Eor_right(a))) == TV_CLASSIFY_ONE)) {
1138     /* The Eor is a negate.  Generate a new Cond without the negate,
1139        simulate the negate by exchanging the results. */
1140     set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
1141                                get_Eor_left(a)));
1142   } else if ((intern_get_irn_op(a) == op_Not)
1143              && (intern_get_irn_mode(a) == mode_b)) {
1144     /* A Not before the Cond.  Generate a new Cond without the Not,
1145        simulate the Not by exchanging the results. */
1146     set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
1147                                get_Not_op(a)));
1148   }
1149   return n;
1150 }
1151
1152 static ir_node *transform_node_Eor(ir_node *n)
1153 {
1154   ir_node *a = get_Eor_left(n);
1155   ir_node *b = get_Eor_right(n);
1156
1157   if ((intern_get_irn_mode(n) == mode_b)
1158       && (intern_get_irn_op(a) == op_Proj)
1159       && (intern_get_irn_mode(a) == mode_b)
1160       && (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE)
1161       && (intern_get_irn_op(get_Proj_pred(a)) == op_Cmp))
1162     /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
1163     n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
1164                    mode_b, get_negated_pnc(get_Proj_proj(a)));
1165   else if ((intern_get_irn_mode(n) == mode_b)
1166            && (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE))
1167     /* The Eor is a Not. Replace it by a Not. */
1168     /*   ????!!!Extend to bitfield 1111111. */
1169     n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b);
1170
1171   return n;
1172 }
1173
1174 static ir_node *transform_node_Not(ir_node *n)
1175 {
1176   ir_node *a = get_Not_op(n);
1177
1178   if (   (intern_get_irn_mode(n) == mode_b)
1179       && (intern_get_irn_op(a) == op_Proj)
1180       && (intern_get_irn_mode(a) == mode_b)
1181       && (intern_get_irn_op(get_Proj_pred(a)) == op_Cmp))
1182     /* We negate a Cmp. The Cmp has the negated result anyways! */
1183     n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
1184                    mode_b, get_negated_pnc(get_Proj_proj(a)));
1185
1186   return n;
1187 }
1188
1189
1190 /**
1191  * Tries several [inplace] [optimizing] transformations and returns an
1192  * equivalent node.  The difference to equivalent_node() is that these
1193  * transformations _do_ generate new nodes, and thus the old node must
1194  * not be freed even if the equivalent node isn't the old one.
1195  */
1196 static ir_node *transform_node(ir_node *n)
1197 {
1198   if (n->op->transform_node)
1199     n = n->op->transform_node(n);
1200   return n;
1201 }
1202
1203 /**
1204  * set the default transform node operation
1205  */
1206 static ir_op *firm_set_default_transform_node(ir_op *op)
1207 {
1208 #define CASE(a)                                 \
1209   case iro_##a:                                 \
1210     op->transform_node  = transform_node_##a;   \
1211     break
1212
1213   switch (op->code) {
1214   CASE(Div);
1215   CASE(Mod);
1216   CASE(DivMod);
1217   CASE(Cond);
1218   CASE(Eor);
1219   CASE(Not);
1220   default:
1221     op->transform_node  = NULL;
1222   }
1223
1224   return op;
1225 #undef CASE
1226 }
1227
1228
1229 /* **************** Common Subexpression Elimination **************** */
1230
1231 /** The size of the hash table used, should estimate the number of nodes
1232     in a graph. */
1233 #define N_IR_NODES 512
1234
1235 static int node_cmp_attr_Const(ir_node *a, ir_node *b)
1236 {
1237   return (get_Const_tarval(a) != get_Const_tarval(b))
1238       || (get_Const_type(a) != get_Const_type(b));
1239 }
1240
1241 static int node_cmp_attr_Proj(ir_node *a, ir_node *b)
1242 {
1243     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
1244 }
1245
1246 static int node_cmp_attr_Filter(ir_node *a, ir_node *b)
1247 {
1248     return get_Filter_proj(a) != get_Filter_proj(b);
1249 }
1250
1251 static int node_cmp_attr_Alloc(ir_node *a, ir_node *b)
1252 {
1253     return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
1254       || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
1255 }
1256
1257 static int node_cmp_attr_Free(ir_node *a, ir_node *b)
1258 {
1259     return (get_irn_free_attr(a) != get_irn_free_attr(b));
1260 }
1261
1262 static int node_cmp_attr_SymConst(ir_node *a, ir_node *b)
1263 {
1264     return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
1265       || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
1266 }
1267
1268 static int node_cmp_attr_Call(ir_node *a, ir_node *b)
1269 {
1270     return (get_irn_call_attr(a) != get_irn_call_attr(b));
1271 }
1272
1273 static int node_cmp_attr_FuncCall(ir_node *a, ir_node *b)
1274 {
1275     return (get_irn_funccall_attr(a) != get_irn_funccall_attr(b));
1276 }
1277
1278 static int node_cmp_attr_Sel(ir_node *a, ir_node *b)
1279 {
1280     return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
1281       || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
1282       || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
1283       || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
1284       || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type);
1285 }
1286
1287 static int node_cmp_attr_Phi(ir_node *a, ir_node *b)
1288 {
1289     return get_irn_phi_attr (a) != get_irn_phi_attr (b);
1290 }
1291
1292 static int node_cmp_attr_Cast(ir_node *a, ir_node *b)
1293 {
1294     return get_Cast_type(a) != get_Cast_type(b);
1295 }
1296
1297 /**
1298  * set the default node attribute compare operation
1299  */
1300 static ir_op *firm_set_default_node_cmp_attr(ir_op *op)
1301 {
1302 #define CASE(a)                                 \
1303   case iro_##a:                                 \
1304     op->node_cmp_attr  = node_cmp_attr_##a;     \
1305     break
1306
1307   switch (op->code) {
1308   CASE(Const);
1309   CASE(Proj);
1310   CASE(Filter);
1311   CASE(Alloc);
1312   CASE(Free);
1313   CASE(SymConst);
1314   CASE(Call);
1315   CASE(FuncCall);
1316   CASE(Sel);
1317   CASE(Phi);
1318   CASE(Cast);
1319   default:
1320     op->node_cmp_attr  = NULL;
1321   }
1322
1323   return op;
1324 #undef CASE
1325 }
1326
1327 /**
1328  * Compare function for two nodes in the hash table. Gets two
1329  * nodes as parameters.  Returns 0 if the nodes are a cse.
1330  */
1331 static int
1332 vt_cmp (const void *elt, const void *key)
1333 {
1334   ir_node *a, *b;
1335   int i, irn_arity_a;
1336
1337   a = (void *)elt;
1338   b = (void *)key;
1339
1340   if (a == b) return 0;
1341
1342   if ((intern_get_irn_op(a) != intern_get_irn_op(b)) ||
1343       (intern_get_irn_mode(a) != intern_get_irn_mode(b))) return 1;
1344
1345   /* compare if a's in and b's in are equal */
1346   irn_arity_a = intern_get_irn_arity (a);
1347   if (irn_arity_a != intern_get_irn_arity(b))
1348     return 1;
1349
1350   /* for block-local cse and pinned nodes: */
1351   if (!get_opt_global_cse() || (get_op_pinned(intern_get_irn_op(a)) == pinned)) {
1352     if (intern_get_irn_n(a, -1) != intern_get_irn_n(b, -1))
1353       return 1;
1354   }
1355
1356   /* compare a->in[0..ins] with b->in[0..ins] */
1357   for (i = 0; i < irn_arity_a; i++)
1358     if (intern_get_irn_n(a, i) != intern_get_irn_n(b, i))
1359       return 1;
1360
1361   /*
1362    * here, we already now that the nodes are identical except their
1363    * attributes
1364    */
1365   if (a->op->node_cmp_attr)
1366     return a->op->node_cmp_attr(a, b);
1367
1368   return 0;
1369 }
1370
1371 /**
1372  * Calculate a hash value of a node.
1373  */
1374 static unsigned
1375 ir_node_hash (ir_node *node)
1376 {
1377   unsigned h;
1378   int i, irn_arity;
1379
1380   /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
1381   h = irn_arity = intern_get_irn_arity(node);
1382
1383   /* consider all in nodes... except the block. */
1384   for (i = 0;  i < irn_arity;  i++) {
1385     h = 9*h + (unsigned long)intern_get_irn_n(node, i);
1386   }
1387
1388   /* ...mode,... */
1389   h = 9*h + (unsigned long) intern_get_irn_mode (node);
1390   /* ...and code */
1391   h = 9*h + (unsigned long) intern_get_irn_op (node);
1392
1393   return h;
1394 }
1395
1396 pset *
1397 new_identities (void)
1398 {
1399   return new_pset (vt_cmp, N_IR_NODES);
1400 }
1401
1402 void
1403 del_identities (pset *value_table)
1404 {
1405   del_pset (value_table);
1406 }
1407
1408 /**
1409  * Return the canonical node computing the same value as n.
1410  * Looks up the node in a hash table.
1411  */
1412 static INLINE ir_node *
1413 identify (pset *value_table, ir_node *n)
1414 {
1415   ir_node *o = NULL;
1416
1417   if (!value_table) return n;
1418
1419   /* TODO: use a generic commutative attribute */
1420   if (get_opt_reassociation()) {
1421     if (is_op_commutative(intern_get_irn_op(n))) {
1422       /* for commutative operators perform  a OP b == b OP a */
1423       if (get_binop_left(n) > get_binop_right(n)) {
1424         ir_node *h = get_binop_left(n);
1425         set_binop_left(n, get_binop_right(n));
1426         set_binop_right(n, h);
1427       }
1428     }
1429   }
1430
1431   o = pset_find (value_table, n, ir_node_hash (n));
1432   if (!o) return n;
1433
1434   return o;
1435 }
1436
1437 /**
1438  * During construction we set the pinned flag in the graph right when the
1439  * optimizatin is performed.  The flag turning on procedure global cse could
1440  * be changed between two allocations.  This way we are safe.
1441  */
1442 static INLINE ir_node *
1443 identify_cons (pset *value_table, ir_node *n) {
1444   ir_node *old = n;
1445   n = identify(value_table, n);
1446   if (intern_get_irn_n(old, -1) != intern_get_irn_n(n, -1))
1447     set_irg_pinned(current_ir_graph, floats);
1448   return n;
1449 }
1450
1451 /**
1452  * Return the canonical node computing the same value as n.
1453  * Looks up the node in a hash table, enters it in the table
1454  * if it isn't there yet.
1455  */
1456 static ir_node *
1457 identify_remember (pset *value_table, ir_node *node)
1458 {
1459   ir_node *o = NULL;
1460
1461   if (!value_table) return node;
1462
1463   /* lookup or insert in hash table with given hash key. */
1464   o = pset_insert (value_table, node, ir_node_hash (node));
1465
1466   if (o == node) return node;
1467
1468   return o;
1469 }
1470
1471 void
1472 add_identities (pset *value_table, ir_node *node) {
1473   identify_remember (value_table, node);
1474 }
1475
1476 /**
1477  * garbage in, garbage out. If a node has a dead input, i.e., the
1478  * Bad node is input to the node, return the Bad node.
1479  */
1480 static INLINE ir_node *
1481 gigo (ir_node *node)
1482 {
1483   int i, irn_arity;
1484   ir_op* op = intern_get_irn_op(node);
1485
1486   /* remove garbage blocks by looking at control flow that leaves the block
1487      and replacing the control flow by Bad. */
1488   if (intern_get_irn_mode(node) == mode_X) {
1489     ir_node *block = get_nodes_block(node);
1490     if (op == op_End) return node;     /* Don't optimize End, may have Bads. */
1491     if (intern_get_irn_op(block) == op_Block && get_Block_matured(block)) {
1492       irn_arity = intern_get_irn_arity(block);
1493       for (i = 0; i < irn_arity; i++) {
1494         if (!is_Bad(intern_get_irn_n(block, i))) break;
1495       }
1496       if (i == irn_arity) return new_Bad();
1497     }
1498   }
1499
1500   /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
1501      blocks predecessors is dead. */
1502   if ( op != op_Block && op != op_Phi && op != op_Tuple) {
1503     irn_arity = intern_get_irn_arity(node);
1504     for (i = -1; i < irn_arity; i++) {
1505       if (is_Bad(intern_get_irn_n(node, i))) {
1506         return new_Bad();
1507       }
1508     }
1509   }
1510 #if 0
1511   /* With this code we violate the agreement that local_optimize
1512      only leaves Bads in Block, Phi and Tuple nodes. */
1513   /* If Block has only Bads as predecessors it's garbage. */
1514   /* If Phi has only Bads as predecessors it's garbage. */
1515   if ((op == op_Block && get_Block_matured(node)) || op == op_Phi)  {
1516     irn_arity = intern_get_irn_arity(node);
1517     for (i = 0; i < irn_arity; i++) {
1518       if (!is_Bad(intern_get_irn_n(node, i))) break;
1519     }
1520     if (i == irn_arity) node = new_Bad();
1521   }
1522 #endif
1523   return node;
1524 }
1525
1526
1527 /**
1528  * These optimizations deallocate nodes from the obstack.
1529  * It can only be called if it is guaranteed that no other nodes
1530  * reference this one, i.e., right after construction of a node.
1531  */
1532 ir_node *
1533 optimize_node (ir_node *n)
1534 {
1535   tarval *tv;
1536   ir_node *oldn = n;
1537   opcode iro = intern_get_irn_opcode(n);
1538
1539   /* Allways optimize Phi nodes: part of the construction. */
1540   if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
1541
1542   /* constant expression evaluation / constant folding */
1543   if (get_opt_constant_folding()) {
1544     /* constants can not be evaluated */
1545     if  (intern_get_irn_op(n) != op_Const) {
1546       /* try to evaluate */
1547       tv = computed_value (n);
1548       if ((intern_get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1549         /*
1550          * we MUST copy the node here temparary, because it's still needed
1551          * for DBG_OPT_ALGSIM0
1552          */
1553         ir_node x = *n;
1554         oldn = &x;
1555         /* evaluation was succesful -- replace the node. */
1556         obstack_free (current_ir_graph->obst, n);
1557         n = new_Const (get_tarval_mode (tv), tv);
1558                                                         DBG_OPT_ALGSIM0;
1559         return n;
1560       }
1561     }
1562   }
1563
1564   /* remove unnecessary nodes */
1565   if (get_opt_constant_folding() ||
1566       (iro == iro_Phi)  ||   /* always optimize these nodes. */
1567       (iro == iro_Id)   ||
1568       (iro == iro_Proj) ||
1569       (iro == iro_Block)  )  /* Flags tested local. */
1570     n = equivalent_node (n);
1571
1572   optimize_preds(n);                  /* do node specific optimizations of nodes predecessors. */
1573
1574   /** common subexpression elimination **/
1575   /* Checks whether n is already available. */
1576   /* The block input is used to distinguish different subexpressions. Right
1577      now all nodes are pinned to blocks, i.e., the cse only finds common
1578      subexpressions within a block. */
1579   if (get_opt_cse())
1580     n = identify_cons (current_ir_graph->value_table, n);
1581
1582   if (n != oldn) {
1583     /* We found an existing, better node, so we can deallocate the old node. */
1584     obstack_free (current_ir_graph->obst, oldn);
1585
1586     return n;
1587   }
1588
1589   /* Some more constant expression evaluation that does not allow to
1590      free the node. */
1591   iro = intern_get_irn_opcode(n);
1592   if (get_opt_constant_folding() ||
1593       (iro == iro_Cond) ||
1594       (iro == iro_Proj))     /* Flags tested local. */
1595     n = transform_node (n);
1596
1597   /* Remove nodes with dead (Bad) input.
1598      Run always for transformation induced Bads. */
1599   n = gigo (n);
1600
1601   /* Now we have a legal, useful node. Enter it in hash table for cse */
1602   if (get_opt_cse() && (intern_get_irn_opcode(n) != iro_Block)) {
1603     n = identify_remember (current_ir_graph->value_table, n);
1604   }
1605
1606   return n;
1607 }
1608
1609
1610 /**
1611  * These optimizations never deallocate nodes.  This can cause dead
1612  * nodes lying on the obstack.  Remove these by a dead node elimination,
1613  * i.e., a copying garbage collection.
1614  */
1615 ir_node *
1616 optimize_in_place_2 (ir_node *n)
1617 {
1618   tarval *tv;
1619   ir_node *oldn = n;
1620   opcode iro = intern_get_irn_opcode(n);
1621
1622   if (!get_opt_optimize() && (intern_get_irn_op(n) != op_Phi)) return n;
1623
1624   /* if not optimize return n */
1625   if (n == NULL) {
1626     assert(0);
1627     /* Here this is possible.  Why? */
1628     return n;
1629   }
1630
1631
1632   /* constant expression evaluation / constant folding */
1633   if (get_opt_constant_folding()) {
1634     /* constants can not be evaluated */
1635     if (iro != iro_Const) {
1636       /* try to evaluate */
1637       tv = computed_value (n);
1638       if ((intern_get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1639         /* evaluation was succesful -- replace the node. */
1640         n = new_Const (get_tarval_mode (tv), tv);
1641                                                 DBG_OPT_ALGSIM0;
1642         return n;
1643       }
1644     }
1645   }
1646
1647   /* remove unnecessary nodes */
1648   /*if (get_opt_constant_folding()) */
1649   if (get_opt_constant_folding() ||
1650       (iro == iro_Phi)  ||   /* always optimize these nodes. */
1651       (iro == iro_Id)   ||   /* ... */
1652       (iro == iro_Proj) ||   /* ... */
1653       (iro == iro_Block)  )  /* Flags tested local. */
1654     n = equivalent_node (n);
1655
1656   optimize_preds(n);                  /* do node specific optimizations of nodes predecessors. */
1657
1658   /** common subexpression elimination **/
1659   /* Checks whether n is already available. */
1660   /* The block input is used to distinguish different subexpressions.  Right
1661      now all nodes are pinned to blocks, i.e., the cse only finds common
1662      subexpressions within a block. */
1663   if (get_opt_cse()) {
1664     n = identify (current_ir_graph->value_table, n);
1665   }
1666
1667   /* Some more constant expression evaluation. */
1668   iro = intern_get_irn_opcode(n);
1669   if (get_opt_constant_folding() ||
1670       (iro == iro_Cond) ||
1671       (iro == iro_Proj))     /* Flags tested local. */
1672     n = transform_node (n);
1673
1674   /* Remove nodes with dead (Bad) input.
1675      Run always for transformation induced Bads.  */
1676   n = gigo (n);
1677
1678   /* Now we can verify the node, as it has no dead inputs any more. */
1679   irn_vrfy(n);
1680
1681   /* Now we have a legal, useful node. Enter it in hash table for cse.
1682      Blocks should be unique anyways.  (Except the successor of start:
1683      is cse with the start block!) */
1684   if (get_opt_cse() && (intern_get_irn_opcode(n) != iro_Block))
1685     n = identify_remember (current_ir_graph->value_table, n);
1686
1687   return n;
1688 }
1689
1690 /**
1691  * Wrapper for external use, set proper status bits after optimization.
1692  */
1693 ir_node *
1694 optimize_in_place (ir_node *n)
1695 {
1696   /* Handle graph state */
1697   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1698
1699   if (get_opt_global_cse())
1700     set_irg_pinned(current_ir_graph, floats);
1701   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
1702     set_irg_outs_inconsistent(current_ir_graph);
1703   /* Maybe we could also test whether optimizing the node can
1704      change the control graph. */
1705   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
1706     set_irg_dom_inconsistent(current_ir_graph);
1707   return optimize_in_place_2 (n);
1708 }
1709
1710 /**
1711  * set the default ir op operations
1712  */
1713 ir_op *firm_set_default_operations(ir_op *op)
1714 {
1715   op = firm_set_default_computed_value(op);
1716   op = firm_set_default_equivalent_node(op);
1717   op = firm_set_default_transform_node(op);
1718   op = firm_set_default_node_cmp_attr(op);
1719
1720   return op;
1721 }