562bddf272d6fccafbe75d755e1152c11fce1757
[libfirm] / ir / ir / iropt.c
1 /* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
2 ** All rights reserved.
3 **
4 ** Authors: Christian Schaefer, Goetz Lindenmaier
5 **
6 ** iropt --- optimizations intertwined with IR construction.
7 */
8
9 # include "iropt.h"
10 # include "ircons.h"
11 # include "irgwalk.h"
12 # include "tv.h"
13
14 /* Trivial inlineable routine for copy propagation.
15    Does follow Ids, needed to optimize inlined code. */
16 static inline ir_node *
17 follow_Id (ir_node *n)
18 {
19   while (get_irn_op (n) == op_Id) n = get_Id_pred (n);
20   return n;
21 }
22
23
24 static inline tarval *
25 value_of (ir_node *n)
26 {
27   if ((n != NULL) && (get_irn_op(n) == op_Const))
28     return get_Const_tarval(n);
29   else
30     return NULL;
31 }
32
33
34 /* if n can be computed, return the value, else NULL. Performs
35    constant Folding. GL: Only if n is arithmetic operator? */
36 tarval *
37 computed_value (ir_node *n)
38 {
39   tarval *res;
40
41   ir_node *a = NULL, *b = NULL;  /* initialized to shut up gcc */
42   tarval *ta = NULL, *tb = NULL; /* initialized to shut up gcc */
43
44   res = NULL;
45
46   /* get the operands we will work on for simple cases. */
47   if (is_binop(n)) {
48     a = get_binop_left(n);
49     b = get_binop_right(n);
50   } else if (is_unop(n)) {
51     a = get_unop_op(n);
52   }
53
54   /* if the operands are constants, get the target value, else set it NULL.
55      (a and b may be NULL if we treat a node that is no computation.) */
56   ta = value_of (a);
57   tb = value_of (b);
58
59   /* Perform the constant evaluation / computation. */
60   switch (get_irn_opcode(n)) {
61   case iro_Const:
62     res = get_Const_tarval(n);
63   case iro_Add:
64     if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
65         && (get_irn_mode(a) != mode_p)) {
66       res = tarval_add (ta, tb);
67     }
68     break;
69   case iro_Sub:
70     if (ta && tb && (get_irn_mode(a) == get_irn_mode(b))
71         && (get_irn_mode(a) != mode_p)) {
72       res = tarval_sub (ta, tb);
73     } else if (a == b) {
74       res = tarval_mode_null [get_irn_modecode (n)];
75     }
76     break;
77   case iro_Minus:
78       if (ta && mode_is_float(get_irn_mode(a)))
79         res = /*tarval_minus (ta);*/ res;
80     break;
81   case iro_Mul:
82     if (ta && tb) /* tarval_mul tests for equivalent modes itself */ {
83       res = tarval_mul (ta, tb);
84     } else {
85       /* calls computed_value recursive and returns the 0 with proper
86          mode.  Why is this an extra case? */
87       tarval *v;
88       if (   (tarval_classify ((v = computed_value (a))) == 0)
89           || (tarval_classify ((v = computed_value (b))) == 0)) {
90         res = v;
91       }
92     }
93     break;
94   case iro_Abs:
95     if (ta)
96       res = /*tarval_abs (ta);*/ res;
97     /* allowded or problems with max/min ?? */
98     break;
99   case iro_And:
100     if (ta && tb) {
101       res = tarval_and (ta, tb);
102     } else {
103       tarval *v;
104       if (   (tarval_classify ((v = computed_value (a))) == 0)
105           || (tarval_classify ((v = computed_value (b))) == 0)) {
106         res = v;
107       }
108     }
109     break;
110   case iro_Or:
111     if (ta && tb) {
112       res = tarval_or (ta, tb);
113     } else {
114       tarval *v;
115       if (   (tarval_classify ((v = computed_value (a))) == -1)
116           || (tarval_classify ((v = computed_value (b))) == -1)) {
117         res = v;
118       }
119     }
120     break;
121   case iro_Eor: if (ta && tb) { res = tarval_eor (ta, tb); } break;
122   case iro_Not: if(ta) { /*res = tarval_not (ta)*/; } break;
123   case iro_Shl: if (ta && tb) { res = tarval_shl (ta, tb); } break;
124   case iro_Shr: if (ta && tb) { res = tarval_shr (ta, tb); } break;
125   case iro_Shrs: if(ta && tb) { /*res = tarval_shrs (ta, tb)*/; } break;
126   case iro_Rot: if(ta && tb) { /*res = tarval_rot (ta, tb)*/; } break;
127   case iro_Conv: if (ta) { res = tarval_convert_to (ta, get_irn_mode (n)); }
128     break;
129   case iro_Proj:
130     {
131       ir_node *aa, *ab;
132
133       a = get_Proj_pred(n);
134       /* Optimize Cmp nodes.
135          This performs a first step of unreachable code elimination.
136          Proj can not be computed, but folding a Cmp above the Proj here is
137          not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
138          only 1 is used.
139          There are several case where we can evaluate a Cmp node:
140          1. The nodes compared are both the same.  If we compare for
141             equal, this will return true, else it will return false.
142             This step relies on cse.
143          2. The predecessors of Cmp are target values.  We can evaluate
144             the Cmp.
145          3. The predecessors are Allocs or void* constants.  Allocs never
146             return NULL, they raise an exception.   Therefore we can predict
147             the Cmp result. */
148       if (get_irn_op(a) == op_Cmp) {
149         aa = get_Cmp_left(a);
150         ab = get_Cmp_right(a);
151         if (aa == ab) { /* 1.: */
152           /* This is a tric with the bits used for encoding the Cmp
153              Proj numbers, the following statement is not the same:
154           res = tarval_from_long (mode_b, (get_Proj_proj(n) == Eq)):    */
155           res = tarval_from_long (mode_b, (get_Proj_proj(n) & irpn_Eq));
156         } else {
157           tarval *taa = computed_value (aa);
158           tarval *tab = computed_value (ab);
159           if (taa && tab) { /* 2.: */
160             /* strange checks... */
161             ir_pncmp flags = tarval_comp (taa, tab);
162             if (flags != irpn_False) {
163               res = tarval_from_long (mode_b, get_Proj_proj(n) & flags);
164             }
165           } else {  /* check for 3.: */
166             ir_node *aaa = skip_nop(skip_Proj(aa));
167             ir_node *aba = skip_nop(skip_Proj(ab));
168             if (   (   (/* aa is ProjP and aaa is Alloc */
169                            (get_irn_op(aa) == op_Proj)
170                         && (get_irn_mode(aa) == mode_p)
171                         && (get_irn_op(aaa) == op_Alloc))
172                     && (   (/* ab is constant void */
173                                (get_irn_op(ab) == op_Const)
174                             && (get_irn_mode(ab) == mode_p)
175                             && (get_Const_tarval(ab) == tarval_p_void))
176                         || (/* ab is other Alloc */
177                                (get_irn_op(ab) == op_Proj)
178                             && (get_irn_mode(ab) == mode_p)
179                             && (get_irn_op(aba) == op_Alloc)
180                             && (aaa != aba))))
181                 || (/* aa is void and aba is Alloc */
182                        (get_irn_op(aa) == op_Const)
183                     && (get_irn_mode(aa) == mode_p)
184                     && (get_Const_tarval(aa) == tarval_p_void)
185                     && (get_irn_op(ab) == op_Proj)
186                     && (get_irn_mode(ab) == mode_p)
187                     && (get_irn_op(aba) == op_Alloc)))
188               /* 3.: */
189               res = tarval_from_long (mode_b, get_Proj_proj(n) & irpn_Ne);
190           }
191         }
192       } else {
193         /* printf(" # comp_val: Proj node, not optimized\n"); */
194       }
195     }
196     break;
197   default:  ;
198   }
199
200   return res;
201 }  /* compute node */
202
203
204
205 /* returns 1 if the a and b are pointers to different locations. */
206 bool
207 different_identity (ir_node *a, ir_node *b)
208 {
209   assert (get_irn_mode (a) == mode_p
210           && get_irn_mode (b) == mode_p);
211
212   if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
213     ir_node *a1 = get_Proj_pred (a);
214     ir_node *b1 = get_Proj_pred (b);
215     if (a1 != b1 && get_irn_op (a1) == op_Alloc
216                  && get_irn_op (b1) == op_Alloc)
217       return 1;
218   }
219   return 0;
220 }
221
222
223 /* equivalent_node returns a node equivalent to N.  It skips all nodes that
224    perform no actual computation, as, e.g., the Id nodes.  It does not create
225    new nodes.  It is therefore safe to free N if the node returned is not N.
226    If a node returns a Tuple we can not just skip it.  If the size of the
227    in array fits, we transform n into a tuple (e.g., Div). */
228 static ir_node *
229 equivalent_node (ir_node *n)
230 {
231   int ins;
232   ir_node *a = NULL; /* to shutup gcc */
233   ir_node *b = NULL; /* to shutup gcc */
234   ir_node *c = NULL; /* to shutup gcc */
235
236   ins = get_irn_arity (n);
237
238   /* get the operands we will work on */
239   if (is_binop(n)) {
240     a = get_binop_left(n);
241     b = get_binop_right(n);
242   } else if (is_unop(n)) {
243     a = get_unop_op(n);
244   }
245
246
247   /* skip unnecessary nodes. */
248   switch (get_irn_opcode (n)) {
249   case iro_Block:
250     {
251       /* The Block constructor does not call optimize, therefore
252          dead blocks are not removed without an extra optimizing
253          pass through the graph. */
254       assert(get_Block_matured(n));
255
256       /* a single entry Region following a single exit Region can be merged */
257       /* !!! Beware, all Phi-nodes of n must have been optimized away.
258          This is true, as the block is matured before optimize is called.   */
259       if (get_Block_n_cfgpreds(n) == 1
260           && get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) {
261         n = get_nodes_Block(get_Block_cfgpred(n, 0));
262       } else if (n != current_ir_graph->start_block) {
263         int i;
264
265         /* If all inputs are dead, this block is dead too, except if it is
266            the start block.  This is a step of unreachable code elimination */
267
268         for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
269           if (!is_Bad(get_Block_cfgpred(n, i))) break;
270         }
271         if (i == get_Block_n_cfgpreds(n))
272           n = new_Bad();
273       }
274     }
275     break;
276
277   case iro_Jmp:  /* GL: ??? Why not same for op_Raise?? */
278     /* unreachable code elimination */
279     if (is_Bad(get_nodes_Block(n)))  n = new_Bad();
280     break;
281   /* GL: Why isn't there a case that checks whether input ot Cond is
282      constant true or false?  For unreachable code elimination
283      is this done in Proj? It's not here as it generates a new node,
284      a Jmp. It is in transform_node. *
285   case iro_Cond:
286     break;
287   */
288     /* remove stuff as x+0, x*1 x&true ... constant expression evaluation */
289   case iro_Or:  if (a == b) {n = a; break;}
290   case iro_Add:
291   case iro_Eor:
292     { tarval *tv;
293       ir_node *on;
294       /* After running compute_node there is only one constant predecessor.
295          Find this predecessors value and remember the other node: */
296       if ((tv = computed_value (a))) {
297         on = b;
298       } else if ((tv = computed_value (b))) {
299         on = a;
300       } else break;
301
302       /* If this predecessors constant value is zero, the operation is
303          unnecessary. Remove it: */
304       if (tarval_classify (tv) == 0) {
305         n = on;
306       }
307     }
308     break;
309   case iro_Sub:
310   case iro_Shl:
311   case iro_Shr:
312   case iro_Shrs:
313   case iro_Rot:
314     /* these operations are not commutative.  Test only one predecessor. */
315     if (tarval_classify (computed_value (b)) == 0) {
316       n = a;
317       /* Test if b > #bits of a ==> return 0 / divide b by #bits
318          --> transform node? */
319     }
320     break;
321   case iro_Not:   /* NotNot x == x */
322   case iro_Minus: /* --x == x */  /* ??? Is this possible or can --x raise an
323                                      out of bounds exception if min =! max? */
324     if (get_irn_op(get_unop_op(n)) == get_irn_op(n))
325       n = get_unop_op(get_unop_op(n));
326     break;
327   case iro_Mul:
328     /* Mul is commutative and has again an other neutral element. */
329     if (tarval_classify (computed_value (a)) == 1) {
330       n = b;
331     } else if (tarval_classify (computed_value (b)) == 1) {
332       n = a;
333     }
334     break;
335   case iro_Div:
336     /* Div is not commutative. */
337     if (tarval_classify (computed_value (b)) == 1) { /* div(x, 1) == x */
338       /* Turn Div into a tuple (mem, bad, a) */
339       ir_node *mem = get_Div_mem(n);
340       turn_into_tuple(n, 3);
341       set_Tuple_pred(n, 0, mem);
342       set_Tuple_pred(n, 1, new_Bad());
343       set_Tuple_pred(n, 2, a);
344     }
345     break;
346     /* GL: Why are they skipped?  DivMod allocates new nodes --> it's
347        teated in transform node.
348   case iro_Mod, Quot, DivMod
349     */
350   case iro_And:
351     if (a == b) n = a;
352     /* And has it's own neutral element */
353     else if (tarval_classify (computed_value (a)) == -1) {
354       n = b;
355     } else if (tarval_classify (computed_value (b)) == -1) {
356       n = a;
357     }
358     break;
359   case iro_Conv:
360     if (get_irn_mode(n) == get_irn_mode(a)) { /* No Conv necessary */
361       n = a;
362     } else if (get_irn_mode(n) == mode_b) {
363       if (get_irn_op(a) == op_Conv &&
364           get_irn_mode (get_Conv_op(a)) == mode_b) {
365         n = get_Conv_op(a);     /* Convb(Conv*(xxxb(...))) == xxxb(...) */
366       }
367     }
368     break;
369
370   case iro_Phi:
371     {
372       /* Several optimizations:
373          - no Phi in start block.
374          - remove Id operators that are inputs to Phi
375          - fold Phi-nodes, iff they have only one predecessor except
376            themselves.
377       */
378       int i, n_preds;
379       ir_node *block = NULL;     /* to shutup gcc */
380       ir_node *first_val = NULL; /* to shutup gcc */
381       ir_node *scnd_val = NULL;  /* to shutup gcc */
382
383       n_preds = get_Phi_n_preds(n);
384
385       block = get_nodes_Block(n);
386       assert(get_irn_op (block) == op_Block);
387
388       /* there should be no Phi nodes in the Start region. */
389       if (block == current_ir_graph->start_block) {
390         n = new_Bad();
391         break;
392       }
393
394       if (n_preds == 0) {       /* Phi of dead Region without predecessors. */
395         /* GL: why not return new_Bad? */
396         break;
397       }
398
399 #if 0
400       /* first we test for a special case: */
401       /* Confirm is a special node fixing additional information for a
402          value that is known at a certain point.  This is useful for
403          dataflow analysis. */
404       if (n_preds == 2) {
405         ir_node *a = follow_Id (get_Phi_pred(n, 0));
406         ir_node *b = follow_Id (get_Phi_pred(n, 1));
407         if (   (get_irn_op(a) == op_Confirm)
408             && (get_irn_op(b) == op_Confirm)
409             && (follow_Id (get_irn_n(a, 0)) == follow_Id(get_irn_n(b, 0)))
410             && (get_irn_n(a, 1) == get_irn_n (b, 1))
411             && (a->data.num == (~b->data.num & irpn_True) )) {
412           n = follow_Id (get_irn_n(a, 0));
413           break;
414         }
415       }
416 #endif
417
418       /* Find first non-self-referencing input */
419       for (i = 0;  i < n_preds;  ++i) {
420         first_val = follow_Id(get_Phi_pred(n, i));
421         /* skip Id's */
422         set_Phi_pred(n, i, first_val);
423         if (   (first_val != n)                            /* not self pointer */
424             && (get_irn_op(first_val) != op_Bad)      /* value not dead */
425             && !(is_Bad (get_Block_cfgpred(block, i))) ) { /* not dead control flow */
426           break;                         /* then found first value. */
427         }
428       }
429
430       /* A totally Bad or self-referencing Phi */
431       if (i > n_preds) { n = new_Bad();  break; }
432
433       scnd_val = NULL;
434
435       /* follow_Id () for rest of inputs, determine if any of these
436          are non-self-referencing */
437       while (++i < n_preds) {
438         scnd_val = follow_Id(get_Phi_pred(n, i));
439         /* skip Id's */
440         set_Phi_pred(n, i, scnd_val);
441         if (   (scnd_val != n)
442             && (scnd_val != first_val)
443             && (get_irn_op(scnd_val) != op_Bad)
444             && !(is_Bad (get_Block_cfgpred(block, i))) ) {
445           break;
446         }
447       }
448
449       /* Fold, if no multiple distinct non-self-referencing inputs */
450       if (i > n_preds) {
451         n = a;
452       } else {
453       /* skip the remaining Ids. */
454         while (++i < n_preds)
455           set_Phi_pred(n, i, follow_Id(get_Phi_pred(n, i)));
456       }
457     }
458     break;
459
460   case iro_Load:
461     {
462       a = skip_Proj(get_Load_mem(n));
463       b = skip_Proj(get_Load_ptr(n));
464
465       if (get_irn_op(a) == op_Store) {
466         if ( different_identity (b, get_Store_ptr(a))) {
467           /* load and store use different pointers, therefore load
468              needs not take store's memory but the state before. */
469           set_Load_mem (n, get_Store_mem(a));
470         } else if (( 0 /* ???didn't get cryptic test that returns 0 */ )) {
471         }
472       }
473     }
474       break;
475   case iro_Store:
476     /* remove unnecessary store. */
477     {
478       a = skip_Proj(get_Store_mem(n));
479       b = get_Store_ptr(n);
480       c = skip_Proj(get_Store_value(n));
481
482       if (get_irn_op(a) == op_Store
483           && get_Store_ptr(a) == b
484           && skip_Proj(get_Store_value(a)) == c) {
485         /* We have twice exactly the same store -- a write after write. */
486         n = a;
487       } else if (get_irn_op(c) == op_Load
488                  && (a == c || skip_Proj(get_Load_mem(c)) == a)
489                  && get_Load_ptr(c) == b )
490                  /* !!!??? and a cryptic test */ {
491         /* We just loaded the value from the same memory, i.e., the store
492            doesn't change the memory -- a write after read. */
493         turn_into_tuple(n, 2);
494         set_Tuple_pred(n, 0, a);
495         set_Tuple_pred(n, 1, new_Bad());
496       }
497     }
498     break;
499
500   case iro_Proj:
501     {
502       a = get_Proj_pred(n);
503
504       if ( get_irn_op(a) == op_Tuple) {
505         /* Remove the Tuple/Proj combination. */
506         if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
507           n = get_Tuple_pred(a, get_Proj_proj(n));
508         } else {
509           assert(0); /* This should not happen?! (GL added this assert) */
510           n = new_Bad();
511         }
512       } else if (get_irn_mode(n) == mode_X &&
513                  is_Bad(get_nodes_Block(n))) {
514         /* Remove dead control flow. */
515         n = new_Bad();
516       }
517     }
518     break;
519
520   case iro_Id:
521     n = follow_Id (n);
522     break;
523
524   default: break;
525   }
526
527   return n;
528 } /* end equivalent_node() */
529
530
531 #if 0
532 /* tries several [inplace] [optimizing] transformations and returns a
533    equivalent node.  The difference to equivalent_node is that these
534    transformations _do_ generate new nodes, and thus the old node must
535    not be freed even if the equivalent node isn't the old one. */
536 static ir_node *
537 transform_node (ir_node *n)
538 {
539
540   ir_node *a, *b;
541   tarval *ta, *tb;
542
543   switch (get_irn_opcode(n)) {
544   case iro_DivMod: {
545     int evaluated = 0;
546     ir_mode *mode = get_irn_mode(a);
547
548     a = get_DivMod_left(n);
549     b = get_DivMod_right(n);
550
551     if (!(   mode_is_int(get_irn_mode(a))
552           && mode_is_int(get_irn_mode(b))))
553       break;
554
555     if (a == b) {
556       a = new_Const (mode, tarval_from_long (mode, 1));
557       b = new_Const (mode, tarval_from_long (mode, 0));
558       evaluated = 1;
559     } else {
560       ta = value_of(a);
561       tb = value_of(b);
562
563       if (tb) {
564         if (tarval_classify(tb) == 1) {
565           b = new_Const (mode, tarval_from_long (mode, 0));
566           evaluated = 1;
567         } else if (ta) {
568           tarval *resa, *resb;
569           resa = tarval_div (ta, tb);
570           if (!resa) break; /* Causes exception!!! Model by replacing through
571                                Jmp for X result!? */
572           resb = tarval_mod (ta, tb);
573           if (!resb) break; /* Causes exception! */
574           a = new_Const (mode, resa);
575           b = new_Const (mode, resb);
576           evaluated = 1;
577         }
578       } else if (tarval_classify (ta) == 0) {
579         b = a;
580         evaluated = 1;
581       }
582     }
583     if (evaluated) { /* replace by tuple */
584       ir_node *mem = get_DivMod_mem(n);
585       turn_into_tuple(n, 4);
586       set_Tuple_pred(n, 0, mem);
587       set_Tuple_pred(n, 1, new_Bad());
588       set_Tuple_pred(n, 2, a);
589       set_Tuple_pred(n, 3, b);
590     }
591   }
592   break;
593
594   case iro_Cond: {
595     /* Replace the Cond by a Jmp if it branches on a constant
596        condition. */
597     ir_node *jmp;
598
599     a = get_Cond_selector(n);
600     ta = value_of(a);
601
602     if (ta && (get_irn_mode(a) == mode_b)) {
603       /* It's a boolean Cond, branching on a boolean constant.
604          Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
605       jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
606       turn_into_tuple(n, 2);
607       if (tv_val_b(ta) == 1)  /* GL: I hope this returns 1 if true */ {
608         set_Tuple_pred(n, 0, new_Bad());
609         set_Tuple_pred(n, 1, jmp);
610       } else {
611         set_Tuple_pred(n, 0, jmp);
612         set_Tuple_pred(n, 1, new_Bad());
613       }
614     } else if (ta && (get_irn_mode(a) == mode_I)) {
615       /* I don't want to allow Tuples smaller than the biggest Proj.
616          Also this tuple might get really big...
617          I generate the Jmp here, and remember it in link.  Link is used
618          when optimizing Proj. */
619       set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
620     } else if (   ((get_irn_op(get_Cond_selector(n)) == op_Eor)
621                    /* || (get_irn_op(get_Cond_selector(a)) == op_Not)*/)
622                && (get_irn_mode(get_Cond_selector(n)) == mode_b)
623                && (tarval_classify(computed_value(get_Eor_right(a))) == 1)) {
624       /* The Eor is a negate.  Generate a new Cond without the negate,
625          simulate the negate by exchanging the results. */
626       set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
627                                  get_Eor_left(a)));
628     }
629   }
630   break;
631
632   case iro_Proj: {
633     a = get_Proj_pred(n);
634
635     if (  (get_irn_op(a) == op_Cond)
636         && get_irn_link(a)
637         && get_irn_op(get_irn_link(a)) == op_Cond) {
638     /* Use the better Cond if the Proj projs from a Cond which get's
639        its result from an Eor/Not. */
640       assert (   ((get_irn_op(get_Cond_selector(a)) == op_Eor)
641                   /* || (get_irn_op(get_Cond_selector(a)) == op_Not)*/)
642               && (get_irn_mode(get_Cond_selector(a)) == mode_b)
643               && (get_irn_op(get_irn_link(a)) == op_Cond)
644               && (get_Cond_selector(get_irn_link(a)) ==
645                   get_Eor_left(get_Cond_selector(a))));
646       set_Proj_pred(n, get_irn_link(a));
647       if (get_Proj_proj(n) == 0)
648         set_Proj_proj(n, 1);
649       else
650         set_Proj_proj(n, 0);
651     } else if (   (get_irn_op(a) == op_Cond)
652                && (get_irn_mode(get_Cond_selector(a)) == mode_I)
653                && value_of(a)) {
654       /* The Cond is a Switch on a Constant */
655       if (get_Proj_proj(n) == tv_val_CHIL(value_of(a))) {
656         /* The always taken branch, reuse the existing Jmp. */
657         if (!get_irn_link(a)) /* well, if it exists ;-> */
658           set_irn_link(a, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
659         assert(get_irn_op(get_irn_link(a)) == op_Jmp);
660         n = get_irn_link(a);
661       } else {
662         /* a never taken branch */
663         n = new_Bad();
664       }
665     }
666   }
667   break;
668   case iro_Eor: {
669     a = get_Eor_left(n);
670     b = get_Eor_right(n);
671
672     if (   (get_irn_mode(n) == mode_b)
673         && (get_irn_op(a) == op_Proj)
674         && (get_irn_mode(a) == mode_b)
675         && (tarval_classify (computed_value (b)) == 1)
676         && (get_irn_op(get_Proj_pred(a)) == iro_Cmp))
677       /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
678       n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
679                      mode_b, get_negated_pnc(get_Proj_proj(a)));
680     else if (   (get_irn_mode(n) == mode_b)
681              && (tarval_classify (computed_value (b)) == 1))
682       /* The Eor is a Not. Replace it by a Not. */
683       /*   ????!!!Extend to bitfield 1111111. */
684       n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b);
685   }
686   break;
687   case iro_Not: {
688     a = get_Not_op(n);
689
690     if (   (get_irn_mode(n) == mode_b)
691         && (get_irn_op(a) == op_Proj)
692         && (get_irn_mode(a) == mode_b)
693         && (get_irn_op(get_Proj_pred(a)) == iro_Cmp))
694       /* We negate a Cmp. The Cmp has the negated result anyways! */
695       n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
696                      mode_b, get_negated_pnc(get_Proj_proj(a)));
697   }
698   break;
699   default: ;
700   }
701 }
702 #endif
703
704 /***************** Common Subexpression Elimination *****************/
705
706 /* Compare function for two nodes in the hash table.   Gets two     */
707 /* nodes as parameters.                                             */
708 /* @@@  a+b != b+a ? */
709 static int
710 vt_cmp (const void *elt, const void *key)
711 {
712   ir_node *a, *b;
713   int i;
714
715   a = (void *)elt;
716   b = (void *)key;
717
718   if (a == b) return 0;
719
720   if ((get_irn_op(a) != get_irn_op(b)) ||
721       (get_irn_mode(a) != get_irn_mode(b))) return 1;
722
723   /* compare if a's in and b's in are equal */
724   /* GL: we optimize only nodes with in arrays of fixed sizes.
725   if (get_irn_arity (a) != -2) {
726     ins = get_irn_arity (a);
727     if (ins != get_irn_arity (b)) return 1;
728     ain = get_irn_in (a);
729     bin = get_irn_in (b);
730   }
731   */
732   if (get_irn_arity (a) != get_irn_arity(b))
733     return 1;
734
735   /* compare a->in[0..ins] with b->in[0..ins], i.e., include the block. */
736   /* do if (*ain++ != *bin++) return 1; while (ins--); */
737   for (i = -1; i < get_irn_arity(a); i++)
738     if (get_irn_n(a, i) != get_irn_n(b, i))
739       return 1;
740
741
742   switch (get_irn_opcode(a)) {
743   case iro_Const:
744     return get_irn_const_attr (a) != get_irn_const_attr (b);
745   case iro_Proj:
746     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
747   case iro_Alloc:
748     return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
749       || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
750   case iro_Free:
751     return (get_irn_free_attr(a) != get_irn_free_attr(b));
752   case iro_SymConst:
753     return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
754       || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
755   case iro_Call:
756     return (get_irn_call_attr(a)->kind != get_irn_call_attr(b)->kind)
757       || (get_irn_call_attr(a)->arity != get_irn_call_attr(b)->arity);
758   case iro_Sel:
759     return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
760       || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
761       || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
762       || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
763       || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type)
764       || (get_irn_sel_attr(a).ltyp != get_irn_sel_attr(b).ltyp);
765   case iro_Phi:
766     return get_irn_phi_attr (a) != get_irn_phi_attr (b);
767   default: ;
768   }
769
770   return 0;
771 }
772
773 static unsigned
774 ir_node_hash (ir_node *node)
775 {
776   unsigned h;
777   int i;
778
779   /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
780   h = get_irn_arity(node);
781
782   /* consider all in nodes... except the block. */
783   for (i = 0;  i < get_irn_arity(node);  i++) {
784     h = 9*h + (unsigned long)get_irn_n(node, i);
785   }
786
787   /* ...mode,... */
788   h = 9*h + (unsigned long) get_irn_mode (node);
789   /* ...and code */
790   h = 9*h + (unsigned long) get_irn_op (node);
791
792   return h;
793 }
794
795 pset *
796 new_identities (void)
797 {
798   return new_pset (vt_cmp, TUNE_NIR_NODES);
799 }
800
801 void
802 del_identities (pset *value_table)
803 {
804   del_pset (value_table);
805 }
806
807 /* Return the canonical node computing the same value as n.
808    Looks up the node in a hash table. */
809 static inline ir_node *
810 identify (pset *value_table, ir_node *n)
811 {
812   ir_node *o = NULL;
813
814   if (!value_table) return n;
815
816   switch (get_irn_opcode (n)) {
817   case iro_Add:
818   case iro_Mul:
819   case iro_Or:
820   case iro_And:
821   case iro_Eor:
822     {
823       /* for commutative operators perform  a OP b == b OP a */
824       if (get_binop_left(n) > get_binop_right(n)) {
825         ir_node *h = get_binop_left(n);
826         set_binop_left(n, get_binop_right(n));
827         set_binop_right(n, h);
828       }
829     }
830   break;
831   default: break;
832   }
833   o = pset_find (value_table, n, ir_node_hash (n));
834   if (!o) return n;
835
836   return o;
837 }
838
839 /* Return the canonical node computing the same value as n.
840    Looks up the node in a hash table, enters it in the table
841    if it isn't there yet. */
842 static ir_node *
843 identify_remember (pset *value_table, ir_node *node)
844 {
845   ir_node *o = NULL;
846
847   if (!value_table) return node;
848
849   /* lookup or insert in hash table with given hash key. */
850   o = pset_insert (value_table, node, ir_node_hash (node));
851
852   if (o == node) return node;
853
854   return o;
855 }
856
857 /* garbage in, garbage out. If a node has a dead input, i.e., the
858    Bad node is input to the node, return the Bad node.  */
859 static inline ir_node *
860 gigo (ir_node *node)
861 {
862   int i;
863   ir_op* op = get_irn_op(node);
864
865   /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
866      blocks predecessors is dead. */
867   if ( op != op_Block && op != op_Phi && op != op_Tuple) {
868     for (i = -1; i < get_irn_arity(node); i++) {
869       if (is_Bad(get_irn_n(node, i))) {
870         node = new_Bad();
871         break;
872       }
873     }
874   }
875   return node;
876 }
877
878
879 /* These optimizations deallocate nodes from the obstack.
880    It can only be called if it is guaranteed that no other nodes
881    reference this one, i.e., right after construction of a node.  */
882 ir_node *
883 optimize (ir_node *n)
884 {
885   tarval *tv;
886   ir_node *old_n = n;
887
888   /* if not optimize return n */
889   if (n == NULL) {
890     printf(" attention: empty node!!! \n");
891     return n;
892   }
893
894   /* constant expression evaluation / constant folding */
895   if (get_opt_constant_folding()) {
896     /* constants can not be evaluated */
897     if  (get_irn_op(n) != op_Const) {
898       /* try to evaluate */
899       tv = computed_value (n);
900       if (tv != NULL) {
901         /* evaluation was succesful -- replace the node. */
902         obstack_free (current_ir_graph->obst, n);
903         return new_Const (get_tv_mode (tv), tv);
904         /* xprintf("* optimize: computed node %I\n", n->op->name); */
905       }
906     }
907   }
908   /* remove unnecessary nodes */
909   if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
910     n = equivalent_node (n);
911
912   /** common subexpression elimination **/
913   /* Checks whether n is already available. */
914   /* The block input is used to distinguish different subexpressions. Right
915      now all nodes are pinned to blocks, i.e., the cse only finds common
916      subexpressions within a block. */
917
918   if (get_opt_cse())
919     n = identify (current_ir_graph->value_table, n);
920
921   /* identify found a cse, so deallocate the old node. */
922   if (n != old_n) {
923     obstack_free (current_ir_graph->obst, old_n);
924     /* The AmRoq fiasco returns n here.  Martin's version doesn't. */
925   }
926
927 #if 0
928   /* Some more constant expression evaluation. */
929   if (get_opt_constant_folding())
930     n = transform_node (n);
931 #endif
932
933   /* Remove nodes with dead (Bad) input. */
934   n = gigo (n);
935   /* Now we can verify the node, as it has no dead inputs any more. */
936   ir_vrfy(n);
937
938   /* Now we have a legal, useful node. Enter it in hash table for cse */
939   if (get_opt_cse()) {
940     /* aborts ??! set/pset can not handle several hash tables??!
941        No, suddenly it works. */
942     n = identify_remember (current_ir_graph->value_table, n);
943   }
944
945 #if 0  /* GL: what's the use of this?? */
946   if ((current_ir_graph->state & irgs_building) && IR_KEEP_ALIVE (n)) {
947     assert (~current_ir_graph->state & irgs_keep_alives_in_arr);
948     pdeq_putr (current_ir_graph->keep.living, n);
949   }
950 #endif
951
952   return n;
953 }
954
955
956 /* These optimizations never deallocate nodes.  This can cause dead
957    nodes lying on the obstack.  Remove these by a dead node elimination,
958    i.e., a copying garbage collection. */
959 ir_node *
960 optimize_in_place (ir_node *n)
961 {
962
963   tarval *tv;
964   ir_node *old_n = n;
965
966   /* if not optimize return n */
967   if (n == NULL) {
968     /* Here this is possible.  Why? */
969     return n;
970   }
971
972   /* constant expression evaluation / constant folding */
973   if (get_opt_constant_folding()) {
974     /* constants can not be evaluated */
975     if  (get_irn_op(n) != op_Const) {
976       /* try to evaluate */
977       tv = computed_value (n);
978       if (tv != NULL) {
979         /* evaluation was succesful -- replace the node. */
980         return new_Const (get_tv_mode (tv), tv);
981         /* xprintf("* optimize: computed node %I\n", n->op->name);*/
982       }
983     }
984   }
985   /* remove unnecessary nodes */
986   if (get_opt_constant_folding() || get_irn_op(n) == op_Phi)
987     n = equivalent_node (n);
988
989   /** common subexpression elimination **/
990   /* Checks whether n is already available. */
991   /* The block input is used to distinguish different subexpressions.  Right
992      now all nodes are pinned to blocks, i.e., the cse only finds common
993      subexpressions within a block. */
994
995   if (get_opt_cse())
996     n = identify (current_ir_graph->value_table, n);
997
998   /* identify found a cse, so deallocate the old node. */
999   if (n != old_n) {
1000     /* The AmRoq fiasco returns n here.  Martin's version doesn't. */
1001   }
1002
1003 #if 0
1004   /* Some more constant expression evaluation. */
1005   if (get_opt_constant_folding())
1006     n = transform_node (n);
1007 #endif
1008
1009   /* Remove nodes with dead (Bad) input. */
1010   n = gigo (n);
1011   /* Now we can verify the node, as it has no dead inputs any more. */
1012   ir_vrfy(n);
1013
1014   /* Now we have a legal, useful node. Enter it in hash table for cse */
1015   if (get_opt_cse()) {
1016     /* aborts ??! set/pset can not handle several hash tables??!
1017        No, suddenly it works. */
1018     n = identify_remember (current_ir_graph->value_table, n);
1019   }
1020
1021   return n;
1022 }