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