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