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