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