574e492ae1f0f894269b82c9417b733ae3a247ab
[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_bytes(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 tarval *computed_value(ir_node *n)
417 {
418   if (n->op->computed_value)
419     return n->op->computed_value(n);
420   return tarval_bad;
421 }
422
423 /**
424  * set the default computed_value evaluator
425  */
426 static ir_op *firm_set_default_computed_value(ir_op *op)
427 {
428 #define CASE(a)                                 \
429   case iro_##a:                                 \
430     op->computed_value  = computed_value_##a;   \
431     break
432
433   switch (op->code) {
434   CASE(Const);
435   CASE(SymConst);
436   CASE(Add);
437   CASE(Sub);
438   CASE(Minus);
439   CASE(Mul);
440   CASE(Quot);
441   CASE(Div);
442   CASE(Mod);
443   CASE(Abs);
444   CASE(And);
445   CASE(Or);
446   CASE(Eor);
447   CASE(Not);
448   CASE(Shl);
449   CASE(Shr);
450   CASE(Shrs);
451   CASE(Rot);
452   CASE(Conv);
453   CASE(Proj);
454   default:
455     op->computed_value  = NULL;
456   }
457
458   return op;
459 #undef CASE
460 }
461
462 #if 0
463 /* returns 1 if the a and b are pointers to different locations. */
464 static bool
465 different_identity (ir_node *a, ir_node *b)
466 {
467   assert (mode_is_reference(get_irn_mode (a))
468           && mode_is_reference(get_irn_mode (b)));
469
470   if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
471     ir_node *a1 = get_Proj_pred (a);
472     ir_node *b1 = get_Proj_pred (b);
473     if (a1 != b1 && get_irn_op (a1) == op_Alloc
474                 && get_irn_op (b1) == op_Alloc)
475       return 1;
476   }
477   return 0;
478 }
479 #endif
480
481 static ir_node *equivalent_node_Block(ir_node *n)
482 {
483   ir_node *oldn = n;
484
485   /* The Block constructor does not call optimize, but mature_block
486      calls the optimization. */
487   assert(get_Block_matured(n));
488
489   /* Straightening: a single entry Block following a single exit Block
490      can be merged, if it is not the Start block. */
491   /* !!! Beware, all Phi-nodes of n must have been optimized away.
492      This should be true, as the block is matured before optimize is called.
493      But what about Phi-cycles with the Phi0/Id that could not be resolved?
494      Remaining Phi nodes are just Ids. */
495    if ((get_Block_n_cfgpreds(n) == 1) &&
496        (get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp)) {
497      ir_node *predblock = get_nodes_Block(get_Block_cfgpred(n, 0));
498      if (predblock == oldn) {
499        /* Jmp jumps into the block it is in -- deal self cycle. */
500        n = new_Bad();                                      DBG_OPT_DEAD;
501      } else if (get_opt_control_flow_straightening()) {
502        n = predblock;                                      DBG_OPT_STG;
503      }
504    }
505    else if ((get_Block_n_cfgpreds(n) == 1) &&
506             (get_irn_op(skip_Proj(get_Block_cfgpred(n, 0))) == op_Cond)) {
507      ir_node *predblock = get_nodes_Block(get_Block_cfgpred(n, 0));
508      if (predblock == oldn) {
509        /* Jmp jumps into the block it is in -- deal self cycle. */
510        n = new_Bad();                                      DBG_OPT_DEAD;
511      }
512    }
513    else if ((get_Block_n_cfgpreds(n) == 2) &&
514             (get_opt_control_flow_weak_simplification())) {
515     /* Test whether Cond jumps twice to this block
516        @@@ we could do this also with two loops finding two preds from several ones. */
517     ir_node *a = get_Block_cfgpred(n, 0);
518     ir_node *b = get_Block_cfgpred(n, 1);
519
520     if ((get_irn_op(a) == op_Proj) &&
521         (get_irn_op(b) == op_Proj) &&
522         (get_Proj_pred(a) == get_Proj_pred(b)) &&
523         (get_irn_op(get_Proj_pred(a)) == op_Cond) &&
524         (get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
525       /* Also a single entry Block following a single exit Block.  Phis have
526          twice the same operand and will be optimized away. */
527       n = get_nodes_Block(a);                                         DBG_OPT_IFSIM;
528     }
529   } else if (get_opt_unreachable_code() &&
530              (n != current_ir_graph->start_block) &&
531              (n != current_ir_graph->end_block)     ) {
532     int i;
533     /* If all inputs are dead, this block is dead too, except if it is
534        the start or end block.  This is a step of unreachable code
535        elimination */
536     for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
537       if (!is_Bad(get_Block_cfgpred(n, i))) break;
538     }
539     if (i == get_Block_n_cfgpreds(n))
540       n = new_Bad();
541   }
542
543   return n;
544 }
545
546 /**
547  * Returns a equivalent node for a Jmp, a Bad :-)
548  * Of course this only happens if the Block of the Jmp is Bad.
549  */
550 static ir_node *equivalent_node_Jmp(ir_node *n)
551 {
552   /* GL: Why not same for op_Raise?? */
553   /* unreachable code elimination */
554   if (is_Bad(get_nodes_Block(n)))
555     n = new_Bad();
556
557   return n;
558 }
559
560 static ir_node *equivalent_node_Cond(ir_node *n)
561 {
562   /* We do not evaluate Cond here as we replace it by a new node, a Jmp.
563      See cases for iro_Cond and iro_Proj in transform_node. */
564   return n;
565 }
566
567 /**
568  * Use algebraic simplification a v a = a.
569  */
570 static ir_node *equivalent_node_Or(ir_node *n)
571 {
572   ir_node *oldn = n;
573
574   ir_node *a = get_Or_left(n);
575   ir_node *b = get_Or_right(n);
576
577   /* remove a v a */
578   if (a == b) {
579     n = a;                                                             DBG_OPT_ALGSIM1;
580   }
581
582   return n;
583 }
584
585 /**
586  * optimize operations that are commutative and have neutral 0,
587  * so a op 0 = 0 op a = a.
588  */
589 static ir_node *equivalent_node_neutral_zero(ir_node *n)
590 {
591   ir_node *oldn = n;
592
593   ir_node *a = get_binop_left(n);
594   ir_node *b = get_binop_right(n);
595
596   tarval *tv;
597   ir_node *on;
598
599   /* After running compute_node there is only one constant predecessor.
600      Find this predecessors value and remember the other node: */
601   if ((tv = computed_value(a)) != tarval_bad) {
602     on = b;
603   } else if ((tv = computed_value(b)) != tarval_bad) {
604     on = a;
605   } else
606     return n;
607
608   /* If this predecessors constant value is zero, the operation is
609      unnecessary. Remove it: */
610   if (tarval_classify (tv) == TV_CLASSIFY_NULL) {
611     n = on;                                                             DBG_OPT_ALGSIM1;
612   }
613
614   return n;
615 }
616
617 #define equivalent_node_Add  equivalent_node_neutral_zero
618 #define equivalent_node_Eor  equivalent_node_neutral_zero
619
620 /**
621  * optimize operations that are not commutative but have neutral 0 on left,
622  * so a op 0 = a.
623  */
624 static ir_node *equivalent_node_left_zero(ir_node *n)
625 {
626   ir_node *oldn = n;
627
628   ir_node *a = get_binop_left(n);
629   ir_node *b = get_binop_right(n);
630
631   if (tarval_classify(computed_value(b)) == TV_CLASSIFY_NULL) {
632     n = a;                                                              DBG_OPT_ALGSIM1;
633   }
634
635   return n;
636 }
637
638 #define equivalent_node_Sub   equivalent_node_left_zero
639 #define equivalent_node_Shl   equivalent_node_left_zero
640 #define equivalent_node_Shr   equivalent_node_left_zero
641 #define equivalent_node_Shrs  equivalent_node_left_zero
642 #define equivalent_node_Rot   equivalent_node_left_zero
643
644 /**
645  * Er, a "symmetic unop", ie op(op(n)) = n.
646  */
647 static ir_node *equivalent_node_symmetric_unop(ir_node *n)
648 {
649   ir_node *oldn = n;
650
651   /* optimize symmetric unop */
652   if (get_irn_op(get_unop_op(n)) == get_irn_op(n)) {
653     n = get_unop_op(get_unop_op(n));                                    DBG_OPT_ALGSIM2;
654   }
655   return n;
656 }
657
658 /* NotNot x == x */
659 #define equivalent_node_Not    equivalent_node_symmetric_unop
660
661 /* --x == x */  /* ??? Is this possible or can --x raise an
662                        out of bounds exception if min =! max? */
663 #define equivalent_node_Minus  equivalent_node_symmetric_unop
664
665 /**
666  * Optimize a * 1 = 1 * a = a.
667  */
668 static ir_node *equivalent_node_Mul(ir_node *n)
669 {
670   ir_node *oldn = n;
671
672   ir_node *a = get_Mul_left(n);
673   ir_node *b = get_Mul_right(n);
674
675   /* Mul is commutative and has again an other neutral element. */
676   if (tarval_classify (computed_value (a)) == TV_CLASSIFY_ONE) {
677     n = b;                                                              DBG_OPT_ALGSIM1;
678   } else if (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE) {
679     n = a;                                                              DBG_OPT_ALGSIM1;
680   }
681   return n;
682 }
683
684 /**
685  * Optimize a / 1 = a.
686  */
687 static ir_node *equivalent_node_Div(ir_node *n)
688 {
689   ir_node *a = get_Div_left(n);
690   ir_node *b = get_Div_right(n);
691
692   /* Div is not commutative. */
693   if (tarval_classify(computed_value(b)) == TV_CLASSIFY_ONE) { /* div(x, 1) == x */
694     /* Turn Div into a tuple (mem, bad, a) */
695     ir_node *mem = get_Div_mem(n);
696     turn_into_tuple(n, 3);
697     set_Tuple_pred(n, pn_Div_M,        mem);
698     set_Tuple_pred(n, pn_Div_X_except, new_Bad());      /* no exception */
699     set_Tuple_pred(n, pn_Div_res,      a);
700   }
701   return n;
702 }
703
704 /**
705  * Optimize a & 0b1...1 = 0b1...1 & a =  a & a = a.
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 /**
726  * Try to remove useless conv's:
727  */
728 static ir_node *equivalent_node_Conv(ir_node *n)
729 {
730   ir_node *oldn = n;
731   ir_node *a = get_Conv_op(n);
732   ir_node *b;
733
734   ir_mode *n_mode = get_irn_mode(n);
735   ir_mode *a_mode = get_irn_mode(a);
736
737   if (n_mode == a_mode) { /* No Conv necessary */
738     n = a;                                                              DBG_OPT_ALGSIM3;
739   } else if (get_irn_op(a) == op_Conv) { /* Conv(Conv(b)) */
740     ir_mode *b_mode;
741
742     b = get_Conv_op(a);
743     n_mode = get_irn_mode(n);
744     b_mode = get_irn_mode(b);
745
746     if (n_mode == b_mode) {
747       if (n_mode == mode_b) {
748         n = b;  /* Convb(Conv*(xxxb(...))) == xxxb(...) */              DBG_OPT_ALGSIM1;
749       }
750       else if (mode_is_int(n_mode) || mode_is_character(n_mode)) {
751         if (smaller_mode(b_mode, a_mode)){
752           n = b;        /* ConvS(ConvL(xxxS(...))) == xxxS(...) */      DBG_OPT_ALGSIM1;
753         }
754       }
755     }
756   }
757   return n;
758 }
759
760 static ir_node *equivalent_node_Phi(ir_node *n)
761 {
762   /* Several optimizations:
763      - no Phi in start block.
764      - remove Id operators that are inputs to Phi
765      - fold Phi-nodes, iff they have only one predecessor except
766              themselves.
767   */
768   int i, n_preds;
769
770   ir_node *oldn = n;
771   ir_node *block = NULL;     /* to shutup gcc */
772   ir_node *first_val = NULL; /* to shutup gcc */
773   ir_node *scnd_val = NULL;  /* to shutup gcc */
774
775   if (!get_opt_normalize()) return n;
776
777   n_preds = get_Phi_n_preds(n);
778
779   block = get_nodes_block(n);
780   /* @@@ fliegt 'raus, sollte aber doch immer wahr sein!!!
781      assert(get_irn_arity(block) == n_preds && "phi in wrong block!"); */
782   if ((is_Bad(block)) ||                         /* Control dead */
783       (block == current_ir_graph->start_block))  /* There should be no Phi nodes */
784     return new_Bad();                        /* in the Start Block. */
785
786   if (n_preds == 0) return n;           /* Phi of dead Region without predecessors. */
787
788 #if 0
789   /* first we test for a special case: */
790   /* Confirm is a special node fixing additional information for a
791      value that is known at a certain point.  This is useful for
792      dataflow analysis. */
793   if (n_preds == 2) {
794     ir_node *a = get_Phi_pred(n, 0);
795     ir_node *b = get_Phi_pred(n, 1);
796     if (   (get_irn_op(a) == op_Confirm)
797         && (get_irn_op(b) == op_Confirm)
798         && follow_Id (get_irn_n(a, 0) == get_irn_n(b, 0))
799         && (get_irn_n(a, 1) == get_irn_n (b, 1))
800         && (a->data.num == (~b->data.num & irpn_True) )) {
801       return get_irn_n(a, 0);
802     }
803   }
804 #endif
805
806   /* If the Block has a Bad pred, we also have one. */
807   for (i = 0;  i < n_preds;  ++i)
808     if (is_Bad (get_Block_cfgpred(block, i)))
809       set_Phi_pred(n, i, new_Bad());
810
811   /* Find first non-self-referencing input */
812   for (i = 0;  i < n_preds;  ++i) {
813     first_val = get_Phi_pred(n, i);
814     if (   (first_val != n)                            /* not self pointer */
815 #if 1
816         && (get_irn_op(first_val) != op_Bad)
817 #endif
818            ) {        /* value not dead */
819       break;          /* then found first value. */
820     }
821   }
822
823   /* A totally Bad or self-referencing Phi (we didn't break the above loop) */
824   if (i >= n_preds) { return new_Bad(); }
825
826   scnd_val = NULL;
827
828   /* follow_Id () for rest of inputs, determine if any of these
829      are non-self-referencing */
830   while (++i < n_preds) {
831     scnd_val = get_Phi_pred(n, i);
832     if (   (scnd_val != n)
833         && (scnd_val != first_val)
834 #if 1
835         && (get_irn_op(scnd_val) != op_Bad)
836 #endif
837            ) {
838       break;
839     }
840   }
841
842   /* Fold, if no multiple distinct non-self-referencing inputs */
843   if (i >= n_preds) {
844     n = first_val;                                     DBG_OPT_PHI;
845   } else {
846     /* skip the remaining Ids (done in get_Phi_pred). */
847     /* superfluous, since we walk all to propagate Block's Bads.
848        while (++i < n_preds) get_Phi_pred(n, i);     */
849   }
850   return n;
851 }
852
853 static ir_node *equivalent_node_Load(ir_node *n)
854 {
855 #if 0  /* Is an illegal transformation: different nodes can
856           represent the same pointer value!! */
857  ir_node *a = skip_Proj(get_Load_mem(n));
858  ir_node *b = get_Load_ptr(n);
859
860  if (get_irn_op(a) == op_Store) {
861    if ( different_identity (b, get_Store_ptr(a))) {
862          /* load and store use different pointers, therefore load
863                 needs not take store's memory but the state before. */
864          set_Load_mem (n, get_Store_mem(a));
865    } else if (( 0 /* ???didn't get cryptic test that returns 0 */ )) {
866    }
867  }
868 #endif
869  return n;
870 }
871
872 /**
873  * Optimize store after store and load atfter store.
874  *
875  * @todo FAILS for volatile entities
876  */
877 static ir_node *equivalent_node_Store(ir_node *n)
878 {
879   ir_node *oldn = n;
880
881   /* remove unnecessary store. */
882   ir_node *a = skip_Proj(get_Store_mem(n));
883   ir_node *b = get_Store_ptr(n);
884   ir_node *c = skip_Proj(get_Store_value(n));
885
886   if (get_irn_op(a) == op_Store
887       && get_Store_ptr(a) == b
888       && skip_Proj(get_Store_value(a)) == c) {
889     /* We have twice exactly the same store -- a write after write. */
890     n = a;                                                         DBG_OPT_WAW;
891   } else if (get_irn_op(c) == op_Load
892              && (a == c || skip_Proj(get_Load_mem(c)) == a)
893              && get_Load_ptr(c) == b ) {
894     /* We just loaded the value from the same memory, i.e., the store
895        doesn't change the memory -- a write after read. */
896     a = get_Store_mem(n);
897     turn_into_tuple(n, 2);
898     set_Tuple_pred(n, pn_Store_M,        a);
899     set_Tuple_pred(n, pn_Store_X_except, new_Bad());               DBG_OPT_WAR;
900   }
901   return n;
902 }
903
904 static ir_node *equivalent_node_Proj(ir_node *n)
905 {
906   ir_node *oldn = n;
907
908   ir_node *a = get_Proj_pred(n);
909
910   if ( get_irn_op(a) == op_Tuple) {
911     /* Remove the Tuple/Proj combination. */
912     if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
913       n = get_Tuple_pred(a, get_Proj_proj(n));                     DBG_OPT_TUPLE;
914     } else {
915       assert(0); /* This should not happen! */
916       n = new_Bad();
917     }
918   } else if (get_irn_mode(n) == mode_X &&
919              is_Bad(get_nodes_Block(n))) {
920     /* Remove dead control flow -- early gigo. */
921     n = new_Bad();
922   }
923   return n;
924 }
925
926 /**
927  * Remove Id's.
928  */
929 static ir_node *equivalent_node_Id(ir_node *n)
930 {
931   ir_node *oldn = n;
932
933   n = follow_Id(n);                                                 DBG_OPT_ID;
934   return n;
935 }
936
937 /*
938 case iro_Mod, Quot, DivMod
939   DivMod allocates new nodes --> it's treated in transform node.
940   What about Quot, DivMod?
941 */
942
943 /**
944  * equivalent_node() returns a node equivalent to input n. It skips all nodes that
945  * perform no actual computation, as, e.g., the Id nodes.  It does not create
946  * new nodes.  It is therefore safe to free n if the node returned is not n.
947  * If a node returns a Tuple we can not just skip it.  If the size of the
948  * in array fits, we transform n into a tuple (e.g., Div).
949  */
950 ir_node *
951 equivalent_node(ir_node *n)
952 {
953   if (n->op->equivalent_node)
954     return n->op->equivalent_node(n);
955   return n;
956 }
957
958 /**
959  * set the default equivalent node operation
960  */
961 static ir_op *firm_set_default_equivalent_node(ir_op *op)
962 {
963 #define CASE(a)                                 \
964   case iro_##a:                                 \
965     op->equivalent_node  = equivalent_node_##a; \
966     break
967
968   switch (op->code) {
969   CASE(Block);
970   CASE(Jmp);
971   CASE(Cond);
972   CASE(Or);
973   CASE(Add);
974   CASE(Eor);
975   CASE(Sub);
976   CASE(Shl);
977   CASE(Shr);
978   CASE(Shrs);
979   CASE(Rot);
980   CASE(Not);
981   CASE(Minus);
982   CASE(Mul);
983   CASE(Div);
984   CASE(And);
985   CASE(Conv);
986   CASE(Phi);
987   CASE(Load);           /* dangerous */
988   CASE(Store);          /* dangerous, see todo */
989   CASE(Proj);
990   CASE(Id);
991   default:
992     op->equivalent_node  = NULL;
993   }
994
995   return op;
996 #undef CASE
997 }
998
999 /**
1000  * Do node specific optimizations of nodes predecessors.
1001  */
1002 static void
1003 optimize_preds(ir_node *n) {
1004   ir_node *a = NULL, *b = NULL;
1005
1006   /* get the operands we will work on for simple cases. */
1007   if (is_binop(n)) {
1008     a = get_binop_left(n);
1009     b = get_binop_right(n);
1010   } else if (is_unop(n)) {
1011     a = get_unop_op(n);
1012   }
1013
1014   switch (get_irn_opcode(n)) {
1015
1016   case iro_Cmp:
1017     /* We don't want Cast as input to Cmp. */
1018     if (get_irn_op(a) == op_Cast) {
1019       a = get_Cast_op(a);
1020       set_Cmp_left(n, a);
1021     }
1022     if (get_irn_op(b) == op_Cast) {
1023       b = get_Cast_op(b);
1024       set_Cmp_right(n, b);
1025     }
1026     break;
1027
1028   default: break;
1029   } /* end switch */
1030 }
1031
1032 static ir_node *transform_node_Div(ir_node *n)
1033 {
1034   tarval *tv = computed_value(n);
1035
1036   /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
1037
1038   if (tv != tarval_bad) {
1039     /* Turn Div into a tuple (mem, bad, value) */
1040     ir_node *mem = get_Div_mem(n);
1041
1042     turn_into_tuple(n, 3);
1043     set_Tuple_pred(n, pn_Div_M, mem);
1044     set_Tuple_pred(n, pn_Div_X_except, new_Bad());
1045     set_Tuple_pred(n, pn_Div_res, new_Const(get_tarval_mode(tv), tv));
1046   }
1047   return n;
1048 }
1049
1050 static ir_node *transform_node_Mod(ir_node *n)
1051 {
1052   tarval *tv = computed_value(n);
1053
1054   /* BEWARE: it is NOT possible to optimize a%a to 0, as this may cause a exception */
1055
1056   if (tv != tarval_bad) {
1057     /* Turn Mod into a tuple (mem, bad, value) */
1058     ir_node *mem = get_Mod_mem(n);
1059     turn_into_tuple(n, 3);
1060     set_Tuple_pred(n, pn_Mod_M, mem);
1061     set_Tuple_pred(n, pn_Mod_X_except, new_Bad());
1062     set_Tuple_pred(n, pn_Mod_res, new_Const(get_tarval_mode(tv), tv));
1063   }
1064   return n;
1065 }
1066
1067 static ir_node *transform_node_DivMod(ir_node *n)
1068 {
1069   int evaluated = 0;
1070
1071   ir_node *a = get_DivMod_left(n);
1072   ir_node *b = get_DivMod_right(n);
1073   ir_mode *mode = get_irn_mode(a);
1074   tarval *ta = value_of(a);
1075   tarval *tb = value_of(b);
1076
1077   if (!(mode_is_int(mode) && mode_is_int(get_irn_mode(b))))
1078     return n;
1079
1080   /* BEWARE: it is NOT possible to optimize a/a to 1, as this may cause a exception */
1081
1082   if (tb != tarval_bad) {
1083     if (tb == get_mode_one(get_tarval_mode(tb))) {
1084       b = new_Const (mode, get_mode_null(mode));
1085       evaluated = 1;
1086     } else if (ta != tarval_bad) {
1087       tarval *resa, *resb;
1088       resa = tarval_div (ta, tb);
1089       if (resa == tarval_bad) return n; /* Causes exception!!! Model by replacing through
1090                                         Jmp for X result!? */
1091       resb = tarval_mod (ta, tb);
1092       if (resb == tarval_bad) return n; /* Causes exception! */
1093       a = new_Const (mode, resa);
1094       b = new_Const (mode, resb);
1095       evaluated = 1;
1096     }
1097   } else if (ta == get_mode_null(mode)) {
1098     b = a;
1099     evaluated = 1;
1100   }
1101   if (evaluated) { /* replace by tuple */
1102     ir_node *mem = get_DivMod_mem(n);
1103     turn_into_tuple(n, 4);
1104     set_Tuple_pred(n, pn_DivMod_M,        mem);
1105     set_Tuple_pred(n, pn_DivMod_X_except, new_Bad());  /* no exception */
1106     set_Tuple_pred(n, pn_DivMod_res_div,  a);
1107     set_Tuple_pred(n, pn_DivMod_res_mod,  b);
1108     assert(get_nodes_Block(n));
1109   }
1110
1111   return n;
1112 }
1113
1114 static ir_node *transform_node_Cond(ir_node *n)
1115 {
1116   /* Replace the Cond by a Jmp if it branches on a constant
1117      condition. */
1118   ir_node *jmp;
1119   ir_node *a = get_Cond_selector(n);
1120   tarval *ta = value_of(a);
1121
1122   if ((ta != tarval_bad) &&
1123       (get_irn_mode(a) == mode_b) &&
1124       (get_opt_unreachable_code())) {
1125     /* It's a boolean Cond, branching on a boolean constant.
1126                Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
1127     jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
1128     turn_into_tuple(n, 2);
1129     if (ta == tarval_b_true) {
1130       set_Tuple_pred(n, pn_Cond_false, new_Bad());
1131       set_Tuple_pred(n, pn_Cond_true, jmp);
1132     } else {
1133       set_Tuple_pred(n, pn_Cond_false, jmp);
1134       set_Tuple_pred(n, pn_Cond_true, new_Bad());
1135     }
1136     /* We might generate an endless loop, so keep it alive. */
1137     add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
1138   } else if ((ta != tarval_bad) &&
1139              (get_irn_mode(a) == mode_Iu) &&
1140              (get_Cond_kind(n) == dense) &&
1141              (get_opt_unreachable_code())) {
1142     /* I don't want to allow Tuples smaller than the biggest Proj.
1143        Also this tuple might get really big...
1144        I generate the Jmp here, and remember it in link.  Link is used
1145        when optimizing Proj. */
1146     set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
1147     /* We might generate an endless loop, so keep it alive. */
1148     add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
1149   } else if ((get_irn_op(a) == op_Eor)
1150              && (get_irn_mode(a) == mode_b)
1151              && (tarval_classify(computed_value(get_Eor_right(a))) == TV_CLASSIFY_ONE)) {
1152     /* The Eor is a negate.  Generate a new Cond without the negate,
1153        simulate the negate by exchanging the results. */
1154     set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
1155                                get_Eor_left(a)));
1156   } else if ((get_irn_op(a) == op_Not)
1157              && (get_irn_mode(a) == mode_b)) {
1158     /* A Not before the Cond.  Generate a new Cond without the Not,
1159        simulate the Not by exchanging the results. */
1160     set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
1161                                get_Not_op(a)));
1162   }
1163   return n;
1164 }
1165
1166 static ir_node *transform_node_Eor(ir_node *n)
1167 {
1168   ir_node *a = get_Eor_left(n);
1169   ir_node *b = get_Eor_right(n);
1170
1171   if ((get_irn_mode(n) == mode_b)
1172       && (get_irn_op(a) == op_Proj)
1173       && (get_irn_mode(a) == mode_b)
1174       && (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE)
1175       && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
1176     /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
1177     n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
1178                    mode_b, get_negated_pnc(get_Proj_proj(a)));
1179   else if ((get_irn_mode(n) == mode_b)
1180            && (tarval_classify (computed_value (b)) == TV_CLASSIFY_ONE))
1181     /* The Eor is a Not. Replace it by a Not. */
1182     /*   ????!!!Extend to bitfield 1111111. */
1183     n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b);
1184
1185   return n;
1186 }
1187
1188 /**
1189  * Transfor a boolean Not.
1190  */
1191 static ir_node *transform_node_Not(ir_node *n)
1192 {
1193   ir_node *a = get_Not_op(n);
1194
1195   if (   (get_irn_mode(n) == mode_b)
1196       && (get_irn_op(a) == op_Proj)
1197       && (get_irn_mode(a) == mode_b)
1198       && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
1199     /* We negate a Cmp. The Cmp has the negated result anyways! */
1200     n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
1201                    mode_b, get_negated_pnc(get_Proj_proj(a)));
1202
1203   return n;
1204 }
1205
1206 /**
1207  * Transform a Div/Mod/DivMod with a non-zero constant. Must be
1208  * done here to avoid that this optimization runs more than once...
1209  */
1210 static ir_node *transform_node_Proj(ir_node *proj)
1211 {
1212   ir_node *n = get_Proj_pred(proj);
1213   ir_node *b;
1214   tarval *tb;
1215
1216   switch (get_irn_opcode(n)) {
1217   case iro_Div:
1218     b = get_Div_right(n);
1219     tb = computed_value(b);
1220
1221     if (tb != tarval_bad && tarval_classify(tb) != TV_CLASSIFY_NULL) { /* div(x, c) && c != 0 */
1222       ir_node *div, *proj;
1223       ir_node *a = get_Div_left(n);
1224       ir_node *mem = get_Div_mem(n);
1225       int rem = get_optimize();
1226
1227       set_optimize(0);
1228       {
1229         div = new_rd_Div(get_irn_dbg_info(n), current_ir_graph,
1230           get_nodes_Block(n), get_irg_initial_mem(current_ir_graph), a, b);
1231
1232         proj = new_r_Proj(current_ir_graph, get_nodes_Block(n), div, get_irn_mode(a), pn_Div_res);
1233       }
1234       set_optimize(rem);
1235
1236       turn_into_tuple(n, 3);
1237       set_Tuple_pred(n, pn_Mod_M, mem);
1238       set_Tuple_pred(n, pn_Mod_X_except, new_Bad());
1239       set_Tuple_pred(n, pn_Mod_res, proj);
1240     }
1241     break;
1242   case iro_Mod:
1243     b = get_Mod_right(n);
1244     tb = computed_value(b);
1245
1246     if (tb != tarval_bad && tarval_classify(tb) != TV_CLASSIFY_NULL) { /* mod(x, c) && c != 0 */
1247       ir_node *mod, *proj;
1248       ir_node *a = get_Mod_left(n);
1249       ir_node *mem = get_Mod_mem(n);
1250       int rem = get_optimize();
1251
1252       set_optimize(0);
1253       {
1254         mod = new_rd_Mod(get_irn_dbg_info(n), current_ir_graph,
1255           get_nodes_Block(n), get_irg_initial_mem(current_ir_graph), a, b);
1256
1257         proj = new_r_Proj(current_ir_graph, get_nodes_Block(n), mod, get_irn_mode(a), pn_Mod_res);
1258       }
1259       set_optimize(rem);
1260
1261       turn_into_tuple(n, 3);
1262       set_Tuple_pred(n, pn_Mod_M, mem);
1263       set_Tuple_pred(n, pn_Mod_X_except, new_Bad());
1264       set_Tuple_pred(n, pn_Mod_res, proj);
1265     }
1266     break;
1267   case iro_DivMod:
1268     b = get_DivMod_right(n);
1269     tb = computed_value(b);
1270
1271     if (tb != tarval_bad && tarval_classify(tb) != TV_CLASSIFY_NULL) { /* DivMod(x, c) && c != 0 */
1272       ir_node *div_mod, *proj_div, *proj_mod;
1273       ir_node *a = get_Mod_left(n);
1274       ir_node *mem = get_Mod_mem(n);
1275       int rem = get_optimize();
1276
1277       set_optimize(0);
1278       {
1279         div_mod = new_rd_DivMod(get_irn_dbg_info(n), current_ir_graph,
1280           get_nodes_Block(n), get_irg_initial_mem(current_ir_graph), a, b);
1281
1282         proj_div = new_r_Proj(current_ir_graph, get_nodes_Block(n), div_mod, get_irn_mode(a), pn_DivMod_res_div);
1283         proj_mod = new_r_Proj(current_ir_graph, get_nodes_Block(n), div_mod, get_irn_mode(a), pn_DivMod_res_mod);
1284       }
1285       set_optimize(rem);
1286
1287       turn_into_tuple(n, 4);
1288       set_Tuple_pred(n, pn_DivMod_M, mem);
1289       set_Tuple_pred(n, pn_DivMod_X_except, new_Bad());
1290       set_Tuple_pred(n, pn_DivMod_res_div, proj_div);
1291       set_Tuple_pred(n, pn_DivMod_res_mod, proj_mod);
1292     }
1293     break;
1294   default:
1295     /* do nothing */
1296     return proj;
1297   }
1298
1299   /* we have added a Tuple, optimize it for the current Proj away */
1300   return equivalent_node_Proj(proj);
1301 }
1302
1303 /**
1304  * Tries several [inplace] [optimizing] transformations and returns an
1305  * equivalent node.  The difference to equivalent_node() is that these
1306  * transformations _do_ generate new nodes, and thus the old node must
1307  * not be freed even if the equivalent node isn't the old one.
1308  */
1309 static ir_node *transform_node(ir_node *n)
1310 {
1311   if (n->op->transform_node)
1312     n = n->op->transform_node(n);
1313   return n;
1314 }
1315
1316 /**
1317  * set the default transform node operation
1318  */
1319 static ir_op *firm_set_default_transform_node(ir_op *op)
1320 {
1321 #define CASE(a)                                 \
1322   case iro_##a:                                 \
1323     op->transform_node  = transform_node_##a;   \
1324     break
1325
1326   switch (op->code) {
1327   CASE(Div);
1328   CASE(Mod);
1329   CASE(DivMod);
1330   CASE(Cond);
1331   CASE(Eor);
1332   CASE(Not);
1333   CASE(Proj);
1334   default:
1335     op->transform_node  = NULL;
1336   }
1337
1338   return op;
1339 #undef CASE
1340 }
1341
1342
1343 /* **************** Common Subexpression Elimination **************** */
1344
1345 /** The size of the hash table used, should estimate the number of nodes
1346     in a graph. */
1347 #define N_IR_NODES 512
1348
1349 static int node_cmp_attr_Const(ir_node *a, ir_node *b)
1350 {
1351   return (get_Const_tarval(a) != get_Const_tarval(b))
1352       || (get_Const_type(a) != get_Const_type(b));
1353 }
1354
1355 static int node_cmp_attr_Proj(ir_node *a, ir_node *b)
1356 {
1357     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
1358 }
1359
1360 static int node_cmp_attr_Filter(ir_node *a, ir_node *b)
1361 {
1362     return get_Filter_proj(a) != get_Filter_proj(b);
1363 }
1364
1365 static int node_cmp_attr_Alloc(ir_node *a, ir_node *b)
1366 {
1367     return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
1368       || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
1369 }
1370
1371 static int node_cmp_attr_Free(ir_node *a, ir_node *b)
1372 {
1373     return (get_irn_free_attr(a) != get_irn_free_attr(b));
1374 }
1375
1376 static int node_cmp_attr_SymConst(ir_node *a, ir_node *b)
1377 {
1378     return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
1379       || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
1380 }
1381
1382 static int node_cmp_attr_Call(ir_node *a, ir_node *b)
1383 {
1384     return (get_irn_call_attr(a) != get_irn_call_attr(b));
1385 }
1386
1387 static int node_cmp_attr_FuncCall(ir_node *a, ir_node *b)
1388 {
1389     return (get_irn_funccall_attr(a) != get_irn_funccall_attr(b));
1390 }
1391
1392 static int node_cmp_attr_Sel(ir_node *a, ir_node *b)
1393 {
1394     return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
1395       || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
1396       || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
1397       || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
1398       || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type);
1399 }
1400
1401 static int node_cmp_attr_Phi(ir_node *a, ir_node *b)
1402 {
1403     return get_irn_phi_attr (a) != get_irn_phi_attr (b);
1404 }
1405
1406 static int node_cmp_attr_Cast(ir_node *a, ir_node *b)
1407 {
1408     return get_Cast_type(a) != get_Cast_type(b);
1409 }
1410
1411 /**
1412  * set the default node attribute compare operation
1413  */
1414 static ir_op *firm_set_default_node_cmp_attr(ir_op *op)
1415 {
1416 #define CASE(a)                                 \
1417   case iro_##a:                                 \
1418     op->node_cmp_attr  = node_cmp_attr_##a;     \
1419     break
1420
1421   switch (op->code) {
1422   CASE(Const);
1423   CASE(Proj);
1424   CASE(Filter);
1425   CASE(Alloc);
1426   CASE(Free);
1427   CASE(SymConst);
1428   CASE(Call);
1429   CASE(FuncCall);
1430   CASE(Sel);
1431   CASE(Phi);
1432   CASE(Cast);
1433   default:
1434     op->node_cmp_attr  = NULL;
1435   }
1436
1437   return op;
1438 #undef CASE
1439 }
1440
1441 /**
1442  * Compare function for two nodes in the hash table. Gets two
1443  * nodes as parameters.  Returns 0 if the nodes are a cse.
1444  */
1445 static int
1446 vt_cmp (const void *elt, const void *key)
1447 {
1448   ir_node *a, *b;
1449   int i, irn_arity_a;
1450
1451   a = (void *)elt;
1452   b = (void *)key;
1453
1454   if (a == b) return 0;
1455
1456   if ((get_irn_op(a) != get_irn_op(b)) ||
1457       (get_irn_mode(a) != get_irn_mode(b))) return 1;
1458
1459   /* compare if a's in and b's in are equal */
1460   irn_arity_a = get_irn_arity (a);
1461   if (irn_arity_a != get_irn_arity(b))
1462     return 1;
1463
1464   /* for block-local cse and pinned nodes: */
1465   if (!get_opt_global_cse() || (get_op_pinned(get_irn_op(a)) == pinned)) {
1466     if (get_irn_n(a, -1) != get_irn_n(b, -1))
1467       return 1;
1468   }
1469
1470   /* compare a->in[0..ins] with b->in[0..ins] */
1471   for (i = 0; i < irn_arity_a; i++)
1472     if (get_irn_n(a, i) != get_irn_n(b, i))
1473       return 1;
1474
1475   /*
1476    * here, we already now that the nodes are identical except their
1477    * attributes
1478    */
1479   if (a->op->node_cmp_attr)
1480     return a->op->node_cmp_attr(a, b);
1481
1482   return 0;
1483 }
1484
1485 /**
1486  * Calculate a hash value of a node.
1487  */
1488 static unsigned
1489 ir_node_hash (ir_node *node)
1490 {
1491   unsigned h;
1492   int i, irn_arity;
1493
1494   /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
1495   h = irn_arity = get_irn_arity(node);
1496
1497   /* consider all in nodes... except the block. */
1498   for (i = 0;  i < irn_arity;  i++) {
1499     h = 9*h + (unsigned long)get_irn_n(node, i);
1500   }
1501
1502   /* ...mode,... */
1503   h = 9*h + (unsigned long) get_irn_mode (node);
1504   /* ...and code */
1505   h = 9*h + (unsigned long) get_irn_op (node);
1506
1507   return h;
1508 }
1509
1510 pset *
1511 new_identities (void)
1512 {
1513   return new_pset (vt_cmp, N_IR_NODES);
1514 }
1515
1516 void
1517 del_identities (pset *value_table)
1518 {
1519   del_pset (value_table);
1520 }
1521
1522 /**
1523  * Return the canonical node computing the same value as n.
1524  * Looks up the node in a hash table.
1525  */
1526 static INLINE ir_node *
1527 identify (pset *value_table, ir_node *n)
1528 {
1529   ir_node *o = NULL;
1530
1531   if (!value_table) return n;
1532
1533   /* TODO: use a generic commutative attribute */
1534   if (get_opt_reassociation()) {
1535     if (is_op_commutative(get_irn_op(n))) {
1536       /* for commutative operators perform  a OP b == b OP a */
1537       if (get_binop_left(n) > get_binop_right(n)) {
1538         ir_node *h = get_binop_left(n);
1539         set_binop_left(n, get_binop_right(n));
1540         set_binop_right(n, h);
1541       }
1542     }
1543   }
1544
1545   o = pset_find (value_table, n, ir_node_hash (n));
1546   if (!o) return n;
1547
1548   return o;
1549 }
1550
1551 /**
1552  * During construction we set the pinned flag in the graph right when the
1553  * optimizatin is performed.  The flag turning on procedure global cse could
1554  * be changed between two allocations.  This way we are safe.
1555  */
1556 static INLINE ir_node *
1557 identify_cons (pset *value_table, ir_node *n) {
1558   ir_node *old = n;
1559   n = identify(value_table, n);
1560   if (get_irn_n(old, -1) != get_irn_n(n, -1))
1561     set_irg_pinned(current_ir_graph, floats);
1562   return n;
1563 }
1564
1565 /**
1566  * Return the canonical node computing the same value as n.
1567  * Looks up the node in a hash table, enters it in the table
1568  * if it isn't there yet.
1569  */
1570 static ir_node *
1571 identify_remember (pset *value_table, ir_node *node)
1572 {
1573   ir_node *o = NULL;
1574
1575   if (!value_table) return node;
1576
1577   /* lookup or insert in hash table with given hash key. */
1578   o = pset_insert (value_table, node, ir_node_hash (node));
1579
1580   if (o == node) return node;
1581
1582   return o;
1583 }
1584
1585 void
1586 add_identities (pset *value_table, ir_node *node) {
1587   identify_remember (value_table, node);
1588 }
1589
1590 /**
1591  * garbage in, garbage out. If a node has a dead input, i.e., the
1592  * Bad node is input to the node, return the Bad node.
1593  */
1594 static INLINE ir_node *
1595 gigo (ir_node *node)
1596 {
1597   int i, irn_arity;
1598   ir_op* op = get_irn_op(node);
1599
1600   /* remove garbage blocks by looking at control flow that leaves the block
1601      and replacing the control flow by Bad. */
1602   if (get_irn_mode(node) == mode_X) {
1603     ir_node *block = get_nodes_block(node);
1604     if (op == op_End) return node;     /* Don't optimize End, may have Bads. */
1605     if (get_irn_op(block) == op_Block && get_Block_matured(block)) {
1606       irn_arity = get_irn_arity(block);
1607       for (i = 0; i < irn_arity; i++) {
1608         if (!is_Bad(get_irn_n(block, i))) break;
1609       }
1610       if (i == irn_arity) return new_Bad();
1611     }
1612   }
1613
1614   /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
1615      blocks predecessors is dead. */
1616   if ( op != op_Block && op != op_Phi && op != op_Tuple) {
1617     irn_arity = get_irn_arity(node);
1618     for (i = -1; i < irn_arity; i++) {
1619       if (is_Bad(get_irn_n(node, i))) {
1620         return new_Bad();
1621       }
1622     }
1623   }
1624 #if 0
1625   /* With this code we violate the agreement that local_optimize
1626      only leaves Bads in Block, Phi and Tuple nodes. */
1627   /* If Block has only Bads as predecessors it's garbage. */
1628   /* If Phi has only Bads as predecessors it's garbage. */
1629   if ((op == op_Block && get_Block_matured(node)) || op == op_Phi)  {
1630     irn_arity = get_irn_arity(node);
1631     for (i = 0; i < irn_arity; i++) {
1632       if (!is_Bad(get_irn_n(node, i))) break;
1633     }
1634     if (i == irn_arity) node = new_Bad();
1635   }
1636 #endif
1637   return node;
1638 }
1639
1640
1641 /**
1642  * These optimizations deallocate nodes from the obstack.
1643  * It can only be called if it is guaranteed that no other nodes
1644  * reference this one, i.e., right after construction of a node.
1645  */
1646 ir_node *
1647 optimize_node (ir_node *n)
1648 {
1649   tarval *tv;
1650   ir_node *oldn = n;
1651   opcode iro = get_irn_opcode(n);
1652
1653   /* Allways optimize Phi nodes: part of the construction. */
1654   if ((!get_opt_optimize()) && (iro != iro_Phi)) return n;
1655
1656   /* constant expression evaluation / constant folding */
1657   if (get_opt_constant_folding()) {
1658     /* constants can not be evaluated */
1659     if (iro != iro_Const) {
1660       /* try to evaluate */
1661       tv = computed_value (n);
1662       if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1663         /*
1664          * we MUST copy the node here temparary, because it's still needed
1665          * for DBG_OPT_ALGSIM0
1666          */
1667         int node_size = offsetof(ir_node, attr) +  n->op->attr_size;
1668         ir_node *x = alloca(node_size);
1669
1670         memcpy(x, n, node_size);
1671         oldn = x;
1672
1673         /* evaluation was successful -- replace the node. */
1674         obstack_free (current_ir_graph->obst, n);
1675         n = new_Const (get_tarval_mode (tv), tv);
1676                                                         DBG_OPT_ALGSIM0;
1677         return n;
1678       }
1679     }
1680   }
1681
1682   /* remove unnecessary nodes */
1683   if (get_opt_constant_folding() ||
1684       (iro == iro_Phi)  ||   /* always optimize these nodes. */
1685       (iro == iro_Id)   ||
1686       (iro == iro_Proj) ||
1687       (iro == iro_Block)  )  /* Flags tested local. */
1688     n = equivalent_node (n);
1689
1690   optimize_preds(n);                  /* do node specific optimizations of nodes predecessors. */
1691
1692   /** common subexpression elimination **/
1693   /* Checks whether n is already available. */
1694   /* The block input is used to distinguish different subexpressions. Right
1695      now all nodes are pinned to blocks, i.e., the cse only finds common
1696      subexpressions within a block. */
1697   if (get_opt_cse())
1698     n = identify_cons (current_ir_graph->value_table, n);
1699
1700   if (n != oldn) {
1701     /* We found an existing, better node, so we can deallocate the old node. */
1702     obstack_free (current_ir_graph->obst, oldn);
1703
1704     return n;
1705   }
1706
1707   /* Some more constant expression evaluation that does not allow to
1708      free the node. */
1709   iro = get_irn_opcode(n);
1710   if (get_opt_constant_folding() ||
1711       (iro == iro_Cond) ||
1712       (iro == iro_Proj))     /* Flags tested local. */
1713     n = transform_node (n);
1714
1715   /* Remove nodes with dead (Bad) input.
1716      Run always for transformation induced Bads. */
1717   n = gigo (n);
1718
1719   /* Now we have a legal, useful node. Enter it in hash table for cse */
1720   if (get_opt_cse() && (get_irn_opcode(n) != iro_Block)) {
1721     n = identify_remember (current_ir_graph->value_table, n);
1722   }
1723
1724   return n;
1725 }
1726
1727
1728 /**
1729  * These optimizations never deallocate nodes.  This can cause dead
1730  * nodes lying on the obstack.  Remove these by a dead node elimination,
1731  * i.e., a copying garbage collection.
1732  */
1733 ir_node *
1734 optimize_in_place_2 (ir_node *n)
1735 {
1736   tarval *tv;
1737   ir_node *oldn = n;
1738   opcode iro = get_irn_opcode(n);
1739
1740   if (!get_opt_optimize() && (get_irn_op(n) != op_Phi)) return n;
1741
1742   /* if not optimize return n */
1743   if (n == NULL) {
1744     assert(0);
1745     /* Here this is possible.  Why? */
1746     return n;
1747   }
1748
1749
1750   /* constant expression evaluation / constant folding */
1751   if (get_opt_constant_folding()) {
1752     /* constants can not be evaluated */
1753     if (iro != iro_Const) {
1754       /* try to evaluate */
1755       tv = computed_value (n);
1756       if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1757         /* evaluation was successful -- replace the node. */
1758         n = new_Const (get_tarval_mode (tv), tv);
1759                                                 DBG_OPT_ALGSIM0;
1760         return n;
1761       }
1762     }
1763   }
1764
1765   /* remove unnecessary nodes */
1766   /*if (get_opt_constant_folding()) */
1767   if (get_opt_constant_folding() ||
1768       (iro == iro_Phi)  ||   /* always optimize these nodes. */
1769       (iro == iro_Id)   ||   /* ... */
1770       (iro == iro_Proj) ||   /* ... */
1771       (iro == iro_Block)  )  /* Flags tested local. */
1772     n = equivalent_node (n);
1773
1774   optimize_preds(n);                  /* do node specific optimizations of nodes predecessors. */
1775
1776   /** common subexpression elimination **/
1777   /* Checks whether n is already available. */
1778   /* The block input is used to distinguish different subexpressions.  Right
1779      now all nodes are pinned to blocks, i.e., the cse only finds common
1780      subexpressions within a block. */
1781   if (get_opt_cse()) {
1782     n = identify (current_ir_graph->value_table, n);
1783   }
1784
1785   /* Some more constant expression evaluation. */
1786   iro = get_irn_opcode(n);
1787   if (get_opt_constant_folding() ||
1788       (iro == iro_Cond) ||
1789       (iro == iro_Proj))     /* Flags tested local. */
1790     n = transform_node (n);
1791
1792   /* Remove nodes with dead (Bad) input.
1793      Run always for transformation induced Bads.  */
1794   n = gigo (n);
1795
1796   /* Now we can verify the node, as it has no dead inputs any more. */
1797   irn_vrfy(n);
1798
1799   /* Now we have a legal, useful node. Enter it in hash table for cse.
1800      Blocks should be unique anyways.  (Except the successor of start:
1801      is cse with the start block!) */
1802   if (get_opt_cse() && (get_irn_opcode(n) != iro_Block))
1803     n = identify_remember (current_ir_graph->value_table, n);
1804
1805   return n;
1806 }
1807
1808 /**
1809  * Wrapper for external use, set proper status bits after optimization.
1810  */
1811 ir_node *
1812 optimize_in_place (ir_node *n)
1813 {
1814   /* Handle graph state */
1815   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1816
1817   if (get_opt_global_cse())
1818     set_irg_pinned(current_ir_graph, floats);
1819   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
1820     set_irg_outs_inconsistent(current_ir_graph);
1821   /* Maybe we could also test whether optimizing the node can
1822      change the control graph. */
1823   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
1824     set_irg_dom_inconsistent(current_ir_graph);
1825   return optimize_in_place_2 (n);
1826 }
1827
1828 /**
1829  * set the default ir op operations
1830  */
1831 ir_op *firm_set_default_operations(ir_op *op)
1832 {
1833   op = firm_set_default_computed_value(op);
1834   op = firm_set_default_equivalent_node(op);
1835   op = firm_set_default_transform_node(op);
1836   op = firm_set_default_node_cmp_attr(op);
1837
1838   return op;
1839 }