Converted documentation to doxygen.
[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 /* $Id$ */
10
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
14
15 # include "irnode_t.h"
16 # include "irgraph_t.h"
17 # include "iropt_t.h"
18 # include "ircons.h"
19 # include "irgmod.h"
20 # include "irvrfy.h"
21 # include "tv.h"
22 # include "tune.h"
23 # include "dbginfo_t.h"
24 # include "iropt_dbg.c"
25
26 /* Make types visible to allow most efficient access */
27 # include "entity_t.h"
28
29 /* Trivial INLINEable routine for copy propagation.
30    Does follow Ids, needed to optimize INLINEd code. */
31 static INLINE ir_node *
32 follow_Id (ir_node *n)
33 {
34   while (get_irn_op (n) == op_Id) n = get_Id_pred (n);
35   return n;
36 }
37
38 static INLINE tarval *
39 value_of (ir_node *n)
40 {
41   if ((n != NULL) && (get_irn_op(n) == op_Const))
42     return get_Const_tarval(n); /* might return tarval_bad */
43   else
44     return tarval_bad;
45 }
46
47 /* if n can be computed, return the value, else NULL. Performs
48    constant folding. GL: Only if n is arithmetic operator? */
49 tarval *
50 computed_value (ir_node *n)
51 {
52   tarval *res;
53
54   ir_node *a = NULL, *b = NULL;  /* initialized to shut up gcc */
55   /* initialized to uniformly filter invalid constants */
56   tarval *ta = tarval_bad, *tb = tarval_bad;
57
58   res = tarval_bad;
59
60   /* get the operands we will work on for simple cases. */
61   if (is_binop(n)) {
62     a = get_binop_left(n);
63     b = get_binop_right(n);
64   } else if (is_unop(n)) {
65     a = get_unop_op(n);
66   }
67
68   /* if the operands are constants, get the target value, else set it NULL.
69      (a and b may be NULL if we treat a node that is no computation.) */
70   ta = value_of (a);
71   tb = value_of (b);
72
73   /* Perform the constant evaluation / computation. */
74   switch (get_irn_opcode(n)) {
75   case iro_Const:
76     res = get_Const_tarval(n);
77     break;
78   case iro_SymConst:
79     if ((get_SymConst_kind(n) == size) &&
80         (get_type_state(get_SymConst_type(n))) == layout_fixed)
81       res = new_tarval_from_long (get_type_size(get_SymConst_type(n)), mode_Is);
82     break;
83   case iro_Add:
84     if ((ta != tarval_bad) && (tb != tarval_bad)
85           && (get_irn_mode(a) == get_irn_mode(b))
86           && !(get_mode_sort(get_irn_mode(a)) == reference)) {
87       res = tarval_add (ta, tb);
88     }
89     break;
90   case iro_Sub:
91     if ((ta != tarval_bad) && (tb != tarval_bad)
92           && (get_irn_mode(a) == get_irn_mode(b))
93           && !(get_mode_sort(get_irn_mode(a)) == reference)) {
94       res = tarval_sub (ta, tb);
95     }
96     break;
97   case iro_Minus:
98       if ((ta != tarval_bad) && mode_is_signed(get_irn_mode(a)))
99         res = tarval_neg (ta);
100     break;
101   case iro_Mul:
102     if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
103       res = tarval_mul (ta, tb);
104     } else {
105       /* a*0 = 0 or 0*b = 0:
106          calls computed_value recursive and returns the 0 with proper
107          mode. */
108       tarval *v;
109       if ( ( ((v = computed_value (a)) != tarval_bad)
110                && (v == get_mode_null(get_tarval_mode(v))) )
111         || ( ((v = computed_value (b)) != tarval_bad)
112                && (v == get_mode_null(get_tarval_mode(v))) )) {
113         res = v;
114       }
115     }
116     break;
117   case iro_Quot:
118     /* This was missing in original implementation. Why? */
119     if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
120       if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
121       res = tarval_quo(ta, tb);
122     }
123     break;
124   case iro_Div:
125     /* This was missing in original implementation. Why? */
126     if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
127       if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
128       res = tarval_div(ta, tb);
129     }
130     break;
131   case iro_Mod:
132     /* This was missing in original implementation. Why? */
133     if ((ta != tarval_bad) && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
134       if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
135       res = tarval_mod(ta, tb);
136     }
137     break;
138   /* for iro_DivMod see iro_Proj */
139   case iro_Abs:
140     if (ta != tarval_bad)
141       res = tarval_abs (ta);
142     break;
143   case iro_And:
144     if ((ta != tarval_bad) && (tb != tarval_bad)) {
145       res = tarval_and (ta, tb);
146     } else {
147       tarval *v;
148       if ( ( ((v = computed_value (a)) != tarval_bad)
149                && (v == get_mode_null(get_tarval_mode(v))) )
150         || ( ((v = computed_value (b)) != tarval_bad)
151                && (v == get_mode_null(get_tarval_mode(v))) )) {
152         res = v;
153       }
154     }
155     break;
156   case iro_Or:
157     if ((ta != tarval_bad) && (tb != tarval_bad)) {
158       res = tarval_or (ta, tb);
159     } else {
160       tarval *v;
161       if (   (tarval_classify ((v = computed_value (a))) == -1)
162           || (tarval_classify ((v = computed_value (b))) == -1)) {
163         res = v;
164       }
165     }
166     break;
167   case iro_Eor:
168     if ((ta != tarval_bad) && (tb != tarval_bad)) {
169       res = tarval_eor (ta, tb);
170     }
171     break;
172   case iro_Not:
173     if ((ta != tarval_bad)) {
174       res = tarval_neg (ta);
175     }
176     break;
177   case iro_Shl:
178     if ((ta != tarval_bad) && (tb != tarval_bad)) {
179       res = tarval_shl (ta, tb);
180     }
181     break;
182   case iro_Shr:
183     if ((ta != tarval_bad) && (tb != tarval_bad)) {
184       res = tarval_shr (ta, tb);
185     }
186     break;
187   case iro_Shrs:
188     if ((ta != tarval_bad) && (tb != tarval_bad)) {
189      res = tarval_shrs (ta, tb);
190     }
191     break;
192   case iro_Rot:
193     if ((ta != tarval_bad) && (tb != tarval_bad)) {
194       /*res = tarval_rot (ta, tb)*/;
195     }
196     break;
197   case iro_Conv:
198     if (ta != tarval_bad) {
199       res = tarval_convert_to (ta, get_irn_mode (n));
200     }
201     break;
202   case iro_Proj:  /* iro_Cmp */
203     {
204       ir_node *aa, *ab;
205
206       a = get_Proj_pred(n);
207       /* Optimize Cmp nodes.
208          This performs a first step of unreachable code elimination.
209          Proj can not be computed, but folding a Cmp above the Proj here is
210          not as wasteful as folding a Cmp into a Tuple of 16 Consts of which
211          only 1 is used.
212          There are several case where we can evaluate a Cmp node:
213          1. The nodes compared are both the same.  If we compare for
214             equal, greater equal, ... this will return true, else it
215             will return false.  This step relies on cse.
216          2. The predecessors of Cmp are target values.  We can evaluate
217             the Cmp.
218          3. The predecessors are Allocs or void* constants.  Allocs never
219             return NULL, they raise an exception.   Therefore we can predict
220             the Cmp result. */
221       if (get_irn_op(a) == op_Cmp) {
222         aa = get_Cmp_left(a);
223         ab = get_Cmp_right(a);
224         if (aa == ab) { /* 1.: */
225           /* This is a tric with the bits used for encoding the Cmp
226              Proj numbers, the following statement is not the same:
227           res = new_tarval_from_long ((get_Proj_proj(n) == Eq), mode_b) */
228           res = new_tarval_from_long ((get_Proj_proj(n) & Eq), mode_b);
229         } else {
230           tarval *taa = computed_value (aa);
231           tarval *tab = computed_value (ab);
232           if ((taa != tarval_bad) && (tab != tarval_bad)) { /* 2.: */
233             /* strange checks... */
234             pnc_number flags = tarval_cmp (taa, tab);
235             if (flags != False) {
236               res = new_tarval_from_long (get_Proj_proj(n) & flags, mode_b);
237             }
238           } else {  /* check for 3.: */
239             ir_node *aaa = skip_nop(skip_Proj(aa));
240             ir_node *aba = skip_nop(skip_Proj(ab));
241             if (   (   (/* aa is ProjP and aaa is Alloc */
242                            (get_irn_op(aa) == op_Proj)
243                         && (get_irn_mode(aa) == mode_P)
244                         && (get_irn_op(aaa) == op_Alloc))
245                     && (   (/* ab is constant void */
246                                (get_irn_op(ab) == op_Const)
247                             && (get_irn_mode(ab) == mode_P)
248                             && (get_Const_tarval(ab) == get_mode_null(mode_P)))
249                         || (/* ab is other Alloc */
250                                (get_irn_op(ab) == op_Proj)
251                             && (get_irn_mode(ab) == mode_P)
252                             && (get_irn_op(aba) == op_Alloc)
253                             && (aaa != aba))))
254                 || (/* aa is void and aba is Alloc */
255                        (get_irn_op(aa) == op_Const)
256                     && (get_irn_mode(aa) == mode_P)
257                     && (get_Const_tarval(aa) == get_mode_null(mode_P))
258                     && (get_irn_op(ab) == op_Proj)
259                     && (get_irn_mode(ab) == mode_P)
260                     && (get_irn_op(aba) == op_Alloc)))
261               /* 3.: */
262               res = new_tarval_from_long (get_Proj_proj(n) & Ne, mode_b);
263           }
264         }
265       } else if (get_irn_op(a) == op_DivMod) {
266         ta = value_of(get_DivMod_left(a));
267         tb = value_of(get_DivMod_right(a));
268         if ((ta != tarval_bad)  && (tb != tarval_bad) && (get_irn_mode(a) == get_irn_mode(b))) {
269           if (tb == get_mode_null(get_tarval_mode(tb))) break;  /* div by zero: return tarval_bad */
270           if (get_Proj_proj(n)== 0) /* Div */
271             res = tarval_div(ta, tb);
272           else /* Mod */
273             res = tarval_mod(ta, tb);
274         }
275       }
276     }
277     break;
278   default:  ;
279   }
280
281   return res;
282 }  /* compute node */
283
284
285 #if 0
286 /* returns 1 if the a and b are pointers to different locations. */
287 static bool
288 different_identity (ir_node *a, ir_node *b)
289 {
290   assert (get_irn_mode (a) == mode_P
291           && get_irn_mode (b) == mode_P);
292
293   if (get_irn_op (a) == op_Proj && get_irn_op(b) == op_Proj) {
294     ir_node *a1 = get_Proj_pred (a);
295     ir_node *b1 = get_Proj_pred (b);
296     if (a1 != b1 && get_irn_op (a1) == op_Alloc
297                 && get_irn_op (b1) == op_Alloc)
298       return 1;
299   }
300   return 0;
301 }
302 #endif
303
304 /* equivalent_node returns a node equivalent to N.  It skips all nodes that
305    perform no actual computation, as, e.g., the Id nodes.  It does not create
306    new nodes.  It is therefore safe to free N if the node returned is not N.
307    If a node returns a Tuple we can not just skip it.  If the size of the
308    in array fits, we transform n into a tuple (e.g., Div). */
309 ir_node *
310 equivalent_node (ir_node *n)
311 {
312   int ins;
313   ir_node *a = NULL; /* to shutup gcc */
314   ir_node *b = NULL; /* to shutup gcc */
315   ir_node *c = NULL; /* to shutup gcc */
316   ir_node *oldn = n;
317
318   ins = get_irn_arity (n);
319
320   /* get the operands we will work on */
321   if (is_binop(n)) {
322     a = get_binop_left(n);
323     b = get_binop_right(n);
324   } else if (is_unop(n)) {
325     a = get_unop_op(n);
326   }
327
328   /* skip unnecessary nodes. */
329   switch (get_irn_opcode (n)) {
330   case iro_Block:
331     {
332       /* The Block constructor does not call optimize, but mature_block
333          calls the optimization. */
334       assert(get_Block_matured(n));
335
336       /* Straightening: a single entry Block following a single exit Block
337          can be merged, if it is not the Start block. */
338       /* !!! Beware, all Phi-nodes of n must have been optimized away.
339          This should be true, as the block is matured before optimize is called.
340          But what about Phi-cycles with the Phi0/Id that could not be resolved?
341          Remaining Phi nodes are just Ids. */
342       if ((get_Block_n_cfgpreds(n) == 1) &&
343           (get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) &&
344           (get_opt_control_flow_straightening())) {
345         n = get_nodes_Block(get_Block_cfgpred(n, 0));                     DBG_OPT_STG;
346
347       } else if ((get_Block_n_cfgpreds(n) == 2) &&
348                  (get_opt_control_flow_weak_simplification())) {
349         /* Test whether Cond jumps twice to this block
350            @@@ we could do this also with two loops finding two preds from several ones. */
351         a = get_Block_cfgpred(n, 0);
352         b = get_Block_cfgpred(n, 1);
353         if ((get_irn_op(a) == op_Proj) &&
354             (get_irn_op(b) == op_Proj) &&
355             (get_Proj_pred(a) == get_Proj_pred(b)) &&
356             (get_irn_op(get_Proj_pred(a)) == op_Cond) &&
357             (get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
358           /* Also a single entry Block following a single exit Block.  Phis have
359              twice the same operand and will be optimized away. */
360           n = get_nodes_Block(a);                                         DBG_OPT_IFSIM;
361         }
362       } else if (get_opt_unreachable_code() &&
363                  (n != current_ir_graph->start_block) &&
364                  (n != current_ir_graph->end_block)     ) {
365         int i;
366         /* If all inputs are dead, this block is dead too, except if it is
367            the start or end block.  This is a step of unreachable code
368            elimination */
369         for (i = 0; i < get_Block_n_cfgpreds(n); i++) {
370           if (!is_Bad(get_Block_cfgpred(n, i))) break;
371         }
372         if (i == get_Block_n_cfgpreds(n))
373           n = new_Bad();
374       }
375     }
376     break;
377
378   case iro_Jmp:  /* GL: Why not same for op_Raise?? */
379     /* unreachable code elimination */
380     if (is_Bad(get_nodes_Block(n)))  n = new_Bad();
381     break;
382         /* We do not evaluate Cond here as we replace it by a new node, a Jmp.
383            See cases for iro_Cond and iro_Proj in transform_node. */
384         /** remove stuff as x+0, x*1 x&true ... constant expression evaluation **/
385   case iro_Or:  if (a == b) {n = a; break;}
386   case iro_Add:
387   case iro_Eor: {
388     tarval *tv;
389     ir_node *on;
390     /* After running compute_node there is only one constant predecessor.
391        Find this predecessors value and remember the other node: */
392     if ((tv = computed_value (a))) {
393       on = b;
394     } else if ((tv = computed_value (b))) {
395       on = a;
396     } else break;
397
398     /* If this predecessors constant value is zero, the operation is
399        unnecessary. Remove it: */
400     if (tarval_classify (tv) == 0) {
401       n = on;                                                             DBG_OPT_ALGSIM1;
402     }
403   } break;
404   case iro_Sub:
405   case iro_Shl:
406   case iro_Shr:
407   case iro_Shrs:
408   case iro_Rot:
409     /* these operations are not commutative.  Test only one predecessor. */
410     if (tarval_classify (computed_value (b)) == 0) {
411       n = a;                                                              DBG_OPT_ALGSIM1;
412       /* Test if b > #bits of a ==> return 0 / divide b by #bits
413          --> transform node? */
414     }
415     break;
416   case iro_Not:   /* NotNot x == x */
417   case iro_Minus: /* --x == x */  /* ??? Is this possible or can --x raise an
418                                          out of bounds exception if min =! max? */
419     if (get_irn_op(get_unop_op(n)) == get_irn_op(n)) {
420       n = get_unop_op(get_unop_op(n));                                    DBG_OPT_ALGSIM2;
421     }
422     break;
423   case iro_Mul:
424     /* Mul is commutative and has again an other neutral element. */
425     if (tarval_classify (computed_value (a)) == 1) {
426       n = b;                                                              DBG_OPT_ALGSIM1;
427     } else if (tarval_classify (computed_value (b)) == 1) {
428       n = a;                                                              DBG_OPT_ALGSIM1;
429     }
430     break;
431   case iro_Div:
432     /* Div is not commutative. */
433     if (tarval_classify (computed_value (b)) == 1) { /* div(x, 1) == x */
434       /* Turn Div into a tuple (mem, bad, a) */
435       ir_node *mem = get_Div_mem(n);
436       turn_into_tuple(n, 3);
437       set_Tuple_pred(n, 0, mem);
438       set_Tuple_pred(n, 1, new_Bad());
439       set_Tuple_pred(n, 2, a);
440     }
441     break;
442   /*
443   case iro_Mod, Quot, DivMod
444     DivMod allocates new nodes --> it's treated in transform node.
445     What about Quot, DivMod?
446   */
447   case iro_And:
448     if (a == b) {
449       n = a;    /* And has it's own neutral element */
450     } else if (tarval_classify (computed_value (a)) == -1) {
451       n = b;
452     } else if (tarval_classify (computed_value (b)) == -1) {
453       n = a;
454     }
455     if (n != oldn)                                                        DBG_OPT_ALGSIM1;
456     break;
457   case iro_Conv:
458     if (get_irn_mode(n) == get_irn_mode(a)) { /* No Conv necessary */
459       n = a;                                                              DBG_OPT_ALGSIM3;
460     } else if (get_irn_mode(n) == mode_b) {
461       if (get_irn_op(a) == op_Conv &&
462           get_irn_mode (get_Conv_op(a)) == mode_b) {
463         n = get_Conv_op(a);     /* Convb(Conv*(xxxb(...))) == xxxb(...) */ DBG_OPT_ALGSIM2;
464       }
465     }
466     break;
467
468   case iro_Phi:
469     {
470       /* Several optimizations:
471          - no Phi in start block.
472          - remove Id operators that are inputs to Phi
473          - fold Phi-nodes, iff they have only one predecessor except
474                  themselves.
475       */
476       int i, n_preds;
477
478       ir_node *block = NULL;     /* to shutup gcc */
479       ir_node *first_val = NULL; /* to shutup gcc */
480       ir_node *scnd_val = NULL;  /* to shutup gcc */
481
482       if (!get_opt_normalize()) return n;
483
484       n_preds = get_Phi_n_preds(n);
485
486       block = get_nodes_Block(n);
487       /* @@@ fliegt 'raus, sollte aber doch immer wahr sein!!!
488          assert(get_irn_arity(block) == n_preds && "phi in wrong block!"); */
489       if ((is_Bad(block)) ||                         /* Control dead */
490           (block == current_ir_graph->start_block))  /* There should be no Phi nodes */
491         return new_Bad();                            /* in the Start Block. */
492
493       if (n_preds == 0) break;           /* Phi of dead Region without predecessors. */
494
495 #if 0
496       /* first we test for a special case: */
497       /* Confirm is a special node fixing additional information for a
498          value that is known at a certain point.  This is useful for
499          dataflow analysis. */
500       if (n_preds == 2) {
501         ir_node *a = follow_Id (get_Phi_pred(n, 0));
502         ir_node *b = follow_Id (get_Phi_pred(n, 1));
503         if (   (get_irn_op(a) == op_Confirm)
504             && (get_irn_op(b) == op_Confirm)
505             && (follow_Id (get_irn_n(a, 0)) == follow_Id(get_irn_n(b, 0)))
506             && (get_irn_n(a, 1) == get_irn_n (b, 1))
507             && (a->data.num == (~b->data.num & irpn_True) )) {
508           n = follow_Id (get_irn_n(a, 0));
509           break;
510         }
511       }
512 #endif
513
514       /* Find first non-self-referencing input */
515       for (i = 0;  i < n_preds;  ++i) {
516         first_val = follow_Id(get_Phi_pred(n, i));
517         /* skip Id's */
518         set_Phi_pred(n, i, first_val);
519         if (   (first_val != n)                            /* not self pointer */
520             && (get_irn_op(first_val) != op_Bad)           /* value not dead */
521             && !(is_Bad (get_Block_cfgpred(block, i))) ) { /* not dead control flow */
522           break;                         /* then found first value. */
523         }
524       }
525
526       /* A totally Bad or self-referencing Phi (we didn't break the above loop) */
527       if (i >= n_preds) { n = new_Bad();  break; }
528
529       scnd_val = NULL;
530
531       /* follow_Id () for rest of inputs, determine if any of these
532          are non-self-referencing */
533       while (++i < n_preds) {
534         scnd_val = follow_Id(get_Phi_pred(n, i));
535         /* skip Id's */
536         set_Phi_pred(n, i, scnd_val);
537         if (   (scnd_val != n)
538             && (scnd_val != first_val)
539             && (get_irn_op(scnd_val) != op_Bad)
540             && !(is_Bad (get_Block_cfgpred(block, i))) ) {
541           break;
542         }
543       }
544
545       /* Fold, if no multiple distinct non-self-referencing inputs */
546       if (i >= n_preds) {
547         n = first_val;                                     DBG_OPT_PHI;
548       } else {
549         /* skip the remaining Ids. */
550         while (++i < n_preds) {
551           set_Phi_pred(n, i, follow_Id(get_Phi_pred(n, i)));
552         }
553       }
554     }
555     break;
556
557   case iro_Load:
558     {
559 #if 0  /* Is an illegal transformation: different nodes can
560           represent the same pointer value!! */
561  a = skip_Proj(get_Load_mem(n));
562  b = get_Load_ptr(n);
563
564  if (get_irn_op(a) == op_Store) {
565    if ( different_identity (b, get_Store_ptr(a))) {
566          /* load and store use different pointers, therefore load
567                 needs not take store's memory but the state before. */
568          set_Load_mem (n, get_Store_mem(a));
569    } else if (( 0 /* ???didn't get cryptic test that returns 0 */ )) {
570    }
571  }
572 #endif
573     }
574         break;
575   case iro_Store:
576     /* remove unnecessary store. */
577     {
578       a = skip_Proj(get_Store_mem(n));
579       b = get_Store_ptr(n);
580       c = skip_Proj(get_Store_value(n));
581
582       if (get_irn_op(a) == op_Store
583           && get_Store_ptr(a) == b
584           && skip_Proj(get_Store_value(a)) == c) {
585         /* We have twice exactly the same store -- a write after write. */
586         n = a;                                                         DBG_OPT_WAW;
587       } else if (get_irn_op(c) == op_Load
588                  && (a == c || skip_Proj(get_Load_mem(c)) == a)
589                  && get_Load_ptr(c) == b ) {
590         /* We just loaded the value from the same memory, i.e., the store
591            doesn't change the memory -- a write after read. */
592         a = get_Store_mem(n);
593         turn_into_tuple(n, 2);
594         set_Tuple_pred(n, 0, a);
595         set_Tuple_pred(n, 1, new_Bad());                               DBG_OPT_WAR;
596        }
597     }
598     break;
599
600   case iro_Proj:
601     {
602       a = get_Proj_pred(n);
603
604       if ( get_irn_op(a) == op_Tuple) {
605         /* Remove the Tuple/Proj combination. */
606         if ( get_Proj_proj(n) <= get_Tuple_n_preds(a) ) {
607           n = get_Tuple_pred(a, get_Proj_proj(n));                     DBG_OPT_TUPLE;
608         } else {
609           assert(0); /* This should not happen! */
610           n = new_Bad();
611         }
612       } else if (get_irn_mode(n) == mode_X &&
613                  is_Bad(get_nodes_Block(n))) {
614         /* Remove dead control flow -- early gigo. */
615         n = new_Bad();
616       }
617     }
618     break;
619
620   case iro_Id:
621     n = follow_Id (n);                                                 DBG_OPT_ID;
622     break;
623
624   default: break;
625   }
626
627   return n;
628 } /* end equivalent_node() */
629
630
631 /* tries several [inplace] [optimizing] transformations and returns an
632    equivalent node.  The difference to equivalent_node is that these
633    transformations _do_ generate new nodes, and thus the old node must
634    not be freed even if the equivalent node isn't the old one. */
635 static ir_node *
636 transform_node (ir_node *n)
637 {
638
639   ir_node *a = NULL, *b;
640   tarval *ta, *tb;
641
642   switch (get_irn_opcode(n)) {
643   case iro_Div: {
644     ta = computed_value(n);
645     if (ta != tarval_bad) {
646       /* Turn Div into a tuple (mem, bad, value) */
647       ir_node *mem = get_Div_mem(n);
648       turn_into_tuple(n, 3);
649       set_Tuple_pred(n, 0, mem);
650       set_Tuple_pred(n, 1, new_Bad());
651       set_Tuple_pred(n, 2, new_Const(get_tarval_mode(ta), ta));
652     }
653   } break;
654   case iro_Mod: {
655     ta = computed_value(n);
656     if (ta != tarval_bad) {
657       /* Turn Div into a tuple (mem, bad, value) */
658       ir_node *mem = get_Mod_mem(n);
659       turn_into_tuple(n, 3);
660       set_Tuple_pred(n, 0, mem);
661       set_Tuple_pred(n, 1, new_Bad());
662       set_Tuple_pred(n, 2, new_Const(get_tarval_mode(ta), ta));
663     }
664   } break;
665   case iro_DivMod: {
666
667     int evaluated = 0;
668     ir_mode *mode;
669
670     a = get_DivMod_left(n);
671     b = get_DivMod_right(n);
672     mode = get_irn_mode(a);
673
674     if (!(mode_is_int(get_irn_mode(a)) &&
675           mode_is_int(get_irn_mode(b))))
676       break;
677
678     if (a == b) {
679       a = new_Const (mode, get_mode_one(mode));
680       b = new_Const (mode, get_mode_null(mode));
681       evaluated = 1;
682     } else {
683       ta = value_of(a);
684       tb = value_of(b);
685
686       if (tb != tarval_bad) {
687         if (tb == get_mode_one(get_tarval_mode(tb))) {
688           b = new_Const (mode, get_mode_null(mode));
689           evaluated = 1;
690         } else if (ta != tarval_bad) {
691           tarval *resa, *resb;
692           resa = tarval_div (ta, tb);
693           if (resa == tarval_bad) break; /* Causes exception!!! Model by replacing through
694                                             Jmp for X result!? */
695           resb = tarval_mod (ta, tb);
696           if (resb == tarval_bad) break; /* Causes exception! */
697           a = new_Const (mode, resa);
698           b = new_Const (mode, resb);
699           evaluated = 1;
700         }
701       } else if (ta == get_mode_null(get_tarval_mode(ta))) {
702         b = a;
703         evaluated = 1;
704       }
705     }
706     if (evaluated) { /* replace by tuple */
707       ir_node *mem = get_DivMod_mem(n);
708       turn_into_tuple(n, 4);
709       set_Tuple_pred(n, 0, mem);
710       set_Tuple_pred(n, 1, new_Bad());  /* no exception */
711       set_Tuple_pred(n, 2, a);
712       set_Tuple_pred(n, 3, b);
713       assert(get_nodes_Block(n));
714     }
715   }
716   break;
717
718   case iro_Cond: {
719     /* Replace the Cond by a Jmp if it branches on a constant
720        condition. */
721     ir_node *jmp;
722     a = get_Cond_selector(n);
723     ta = value_of(a);
724
725     if ((ta != tarval_bad) &&
726         (get_irn_mode(a) == mode_b) &&
727         (get_opt_unreachable_code())) {
728       /* It's a boolean Cond, branching on a boolean constant.
729                  Replace it by a tuple (Bad, Jmp) or (Jmp, Bad) */
730       jmp = new_r_Jmp(current_ir_graph, get_nodes_Block(n));
731       turn_into_tuple(n, 2);
732       if (ta == tarval_b_true) {
733                 set_Tuple_pred(n, 0, new_Bad());
734                 set_Tuple_pred(n, 1, jmp);
735       } else {
736                 set_Tuple_pred(n, 0, jmp);
737                 set_Tuple_pred(n, 1, new_Bad());
738       }
739       /* We might generate an endless loop, so keep it alive. */
740       add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
741     } else if ((ta != tarval_bad) &&
742                (get_irn_mode(a) == mode_Iu) &&
743                (get_Cond_kind(n) == dense) &&
744                (get_opt_unreachable_code())) {
745       /* I don't want to allow Tuples smaller than the biggest Proj.
746          Also this tuple might get really big...
747          I generate the Jmp here, and remember it in link.  Link is used
748          when optimizing Proj. */
749       set_irn_link(n, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
750       /* We might generate an endless loop, so keep it alive. */
751       add_End_keepalive(get_irg_end(current_ir_graph), get_nodes_Block(n));
752     } else if ((get_irn_op(get_Cond_selector(n)) == op_Eor)
753                && (get_irn_mode(get_Cond_selector(n)) == mode_b)
754                && (tarval_classify(computed_value(get_Eor_right(a))) == 1)) {
755       /* The Eor is a negate.  Generate a new Cond without the negate,
756          simulate the negate by exchanging the results. */
757       set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
758                                  get_Eor_left(a)));
759     } else if ((get_irn_op(get_Cond_selector(n)) == op_Not)
760                && (get_irn_mode(get_Cond_selector(n)) == mode_b)) {
761       /* A Not before the Cond.  Generate a new Cond without the Not,
762          simulate the Not by exchanging the results. */
763       set_irn_link(n, new_r_Cond(current_ir_graph, get_nodes_Block(n),
764                                  get_Not_op(a)));
765     }
766   }
767   break;
768
769   case iro_Proj: {
770     a = get_Proj_pred(n);
771
772     if ((get_irn_op(a) == op_Cond)
773         && get_irn_link(a)
774         && get_irn_op(get_irn_link(a)) == op_Cond) {
775       /* Use the better Cond if the Proj projs from a Cond which get's
776          its result from an Eor/Not. */
777       assert (((get_irn_op(get_Cond_selector(a)) == op_Eor)
778                || (get_irn_op(get_Cond_selector(a)) == op_Not))
779               && (get_irn_mode(get_Cond_selector(a)) == mode_b)
780               && (get_irn_op(get_irn_link(a)) == op_Cond)
781               && (get_Cond_selector(get_irn_link(a)) == get_Eor_left(get_Cond_selector(a))));
782       set_Proj_pred(n, get_irn_link(a));
783       if (get_Proj_proj(n) == 0)
784         set_Proj_proj(n, 1);
785       else
786         set_Proj_proj(n, 0);
787     } else if ((get_irn_op(a) == op_Cond)
788                && (get_irn_mode(get_Cond_selector(a)) == mode_Iu)
789                && value_of(a)
790                && (get_Cond_kind(a) == dense)
791                && (get_opt_unreachable_code())) {
792       /* The Cond is a Switch on a Constant */
793       if (get_Proj_proj(n) == tarval_to_long(value_of(a))) {
794         /* The always taken branch, reuse the existing Jmp. */
795         if (!get_irn_link(a)) /* well, if it exists ;-> */
796           set_irn_link(a, new_r_Jmp(current_ir_graph, get_nodes_Block(n)));
797         assert(get_irn_op(get_irn_link(a)) == op_Jmp);
798         n = get_irn_link(a);
799       } else {/* Not taken control flow, but be careful with the default! */
800         if (get_Proj_proj(n) < a->attr.c.default_proj){
801           /* a never taken branch */
802           n = new_Bad();
803         } else {
804           a->attr.c.default_proj = get_Proj_proj(n);
805         }
806       }
807     }
808   } break;
809   case iro_Eor: { /* @@@ not tested as boolean Eor not allowed any more. */
810     a = get_Eor_left(n);
811     b = get_Eor_right(n);
812
813     if ((get_irn_mode(n) == mode_b)
814         && (get_irn_op(a) == op_Proj)
815         && (get_irn_mode(a) == mode_b)
816         && (tarval_classify (computed_value (b)) == 1)
817         && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
818       /* The Eor negates a Cmp. The Cmp has the negated result anyways! */
819       n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
820                      mode_b, get_negated_pnc(get_Proj_proj(a)));
821     else if ((get_irn_mode(n) == mode_b)
822              && (tarval_classify (computed_value (b)) == 1))
823       /* The Eor is a Not. Replace it by a Not. */
824       /*   ????!!!Extend to bitfield 1111111. */
825       n = new_r_Not(current_ir_graph, get_nodes_Block(n), a, mode_b);
826   }
827   break;
828   case iro_Not: {
829     a = get_Not_op(n);
830
831     if (   (get_irn_mode(n) == mode_b)
832         && (get_irn_op(a) == op_Proj)
833         && (get_irn_mode(a) == mode_b)
834         && (get_irn_op(get_Proj_pred(a)) == op_Cmp))
835       /* We negate a Cmp. The Cmp has the negated result anyways! */
836       n = new_r_Proj(current_ir_graph, get_nodes_Block(n), get_Proj_pred(a),
837                      mode_b, get_negated_pnc(get_Proj_proj(a)));
838   }
839   break;
840   default: ;
841   }
842   return n;
843 }
844
845 /* **************** Common Subexpression Elimination **************** */
846
847 /* Compare function for two nodes in the hash table.   Gets two       */
848 /* nodes as parameters.  Returns 0 if the nodes are a cse.            */
849 static int
850 vt_cmp (const void *elt, const void *key)
851 {
852   ir_node *a, *b;
853   int i;
854
855   a = (void *)elt;
856   b = (void *)key;
857
858   if (a == b) return 0;
859
860   if ((get_irn_op(a) != get_irn_op(b)) ||
861       (get_irn_mode(a) != get_irn_mode(b))) return 1;
862
863   /* compare if a's in and b's in are equal */
864   if (get_irn_arity (a) != get_irn_arity(b))
865     return 1;
866
867   /* for block-local cse and pinned nodes: */
868   if (!get_opt_global_cse() || (get_op_pinned(get_irn_op(a)) == pinned)) {
869     if (get_irn_n(a, -1) != get_irn_n(b, -1))
870       return 1;
871   }
872
873   /* compare a->in[0..ins] with b->in[0..ins] */
874   for (i = 0; i < get_irn_arity(a); i++)
875     if (get_irn_n(a, i) != get_irn_n(b, i))
876       return 1;
877
878   switch (get_irn_opcode(a)) {
879   case iro_Const:
880     return get_irn_const_attr (a) != get_irn_const_attr (b);
881   case iro_Proj:
882     return get_irn_proj_attr (a) != get_irn_proj_attr (b);
883   case iro_Filter:
884     return get_Filter_proj(a) != get_Filter_proj(b);
885   case iro_Alloc:
886     return (get_irn_alloc_attr(a).where != get_irn_alloc_attr(b).where)
887       || (get_irn_alloc_attr(a).type != get_irn_alloc_attr(b).type);
888   case iro_Free:
889     return (get_irn_free_attr(a) != get_irn_free_attr(b));
890   case iro_SymConst:
891     return (get_irn_symconst_attr(a).num != get_irn_symconst_attr(b).num)
892       || (get_irn_symconst_attr(a).tori.typ != get_irn_symconst_attr(b).tori.typ);
893   case iro_Call:
894     return (get_irn_call_attr(a) != get_irn_call_attr(b));
895   case iro_Sel:
896     return (get_irn_sel_attr(a).ent->kind != get_irn_sel_attr(b).ent->kind)
897       || (get_irn_sel_attr(a).ent->name != get_irn_sel_attr(b).ent->name)
898       || (get_irn_sel_attr(a).ent->owner != get_irn_sel_attr(b).ent->owner)
899       || (get_irn_sel_attr(a).ent->ld_name != get_irn_sel_attr(b).ent->ld_name)
900       || (get_irn_sel_attr(a).ent->type != get_irn_sel_attr(b).ent->type);
901   case iro_Phi:
902     return get_irn_phi_attr (a) != get_irn_phi_attr (b);
903   default: ;
904   }
905
906   return 0;
907 }
908
909 static unsigned
910 ir_node_hash (ir_node *node)
911 {
912   unsigned h;
913   int i;
914
915   /* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
916   h = get_irn_arity(node);
917
918   /* consider all in nodes... except the block. */
919   for (i = 0;  i < get_irn_arity(node);  i++) {
920     h = 9*h + (unsigned long)get_irn_n(node, i);
921   }
922
923   /* ...mode,... */
924   h = 9*h + (unsigned long) get_irn_mode (node);
925   /* ...and code */
926   h = 9*h + (unsigned long) get_irn_op (node);
927
928   return h;
929 }
930
931 pset *
932 new_identities (void)
933 {
934   return new_pset (vt_cmp, TUNE_NIR_NODES);
935 }
936
937 void
938 del_identities (pset *value_table)
939 {
940   del_pset (value_table);
941 }
942
943 /* Return the canonical node computing the same value as n.
944    Looks up the node in a hash table. */
945 static INLINE ir_node *
946 identify (pset *value_table, ir_node *n)
947 {
948   ir_node *o = NULL;
949
950   if (!value_table) return n;
951
952   if (get_opt_reassociation()) {
953     switch (get_irn_opcode (n)) {
954     case iro_Add:
955     case iro_Mul:
956     case iro_Or:
957     case iro_And:
958     case iro_Eor:
959       {
960         /* for commutative operators perform  a OP b == b OP a */
961         if (get_binop_left(n) > get_binop_right(n)) {
962           ir_node *h = get_binop_left(n);
963           set_binop_left(n, get_binop_right(n));
964           set_binop_right(n, h);
965         }
966       }
967       break;
968     default: break;
969     }
970   }
971
972   o = pset_find (value_table, n, ir_node_hash (n));
973   if (!o) return n;
974
975   return o;
976 }
977
978 /* During construction we set the pinned flag in the graph right when the
979    optimizatin is performed.  The flag turning on procedure global cse could
980    be changed between two allocations.  This way we are safe. */
981 static INLINE ir_node *
982 identify_cons (pset *value_table, ir_node *n) {
983   ir_node *old = n;
984   n = identify(value_table, n);
985   if (get_irn_n(old, -1) != get_irn_n(n, -1))
986     set_irg_pinned(current_ir_graph, floats);
987   return n;
988 }
989
990 /* Return the canonical node computing the same value as n.
991    Looks up the node in a hash table, enters it in the table
992    if it isn't there yet. */
993 static ir_node *
994 identify_remember (pset *value_table, ir_node *node)
995 {
996   ir_node *o = NULL;
997
998   if (!value_table) return node;
999
1000   /* lookup or insert in hash table with given hash key. */
1001   o = pset_insert (value_table, node, ir_node_hash (node));
1002
1003   if (o == node) return node;
1004
1005   return o;
1006 }
1007
1008 void
1009 add_identities (pset *value_table, ir_node *node) {
1010   identify_remember (value_table, node);
1011 }
1012
1013 /* garbage in, garbage out. If a node has a dead input, i.e., the
1014    Bad node is input to the node, return the Bad node.  */
1015 static INLINE ir_node *
1016 gigo (ir_node *node)
1017 {
1018   int i;
1019   ir_op* op = get_irn_op(node);
1020
1021   /* Blocks, Phis and Tuples may have dead inputs, e.g., if one of the
1022      blocks predecessors is dead. */
1023   if ( op != op_Block && op != op_Phi && op != op_Tuple) {
1024     for (i = -1; i < get_irn_arity(node); i++) {
1025       if (is_Bad(get_irn_n(node, i))) {
1026         return new_Bad();
1027       }
1028     }
1029   }
1030 #if 0
1031   /* If Block has only Bads as predecessors it's garbage. */
1032   /* If Phi has only Bads as predecessors it's garbage. */
1033   if (op == op_Block || op == op_Phi)  {
1034     for (i = 0; i < get_irn_arity(node); i++) {
1035       if (!is_Bad(get_irn_n(node, i))) break;
1036     }
1037     if (i = get_irn_arity(node)) node = new_Bad();
1038   }
1039 #endif
1040   return node;
1041 }
1042
1043
1044 /* These optimizations deallocate nodes from the obstack.
1045    It can only be called if it is guaranteed that no other nodes
1046    reference this one, i.e., right after construction of a node.  */
1047 ir_node *
1048 optimize_node (ir_node *n)
1049 {
1050   tarval *tv;
1051   ir_node *old_n = n;
1052
1053   /* Allways optimize Phi nodes: part of the construction. */
1054   if ((!get_optimize()) && (get_irn_op(n) != op_Phi)) return n;
1055
1056   /* constant expression evaluation / constant folding */
1057   if (get_opt_constant_folding()) {
1058     /* constants can not be evaluated */
1059     if  (get_irn_op(n) != op_Const) {
1060       /* try to evaluate */
1061       tv = computed_value (n);
1062       if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1063         /* evaluation was succesful -- replace the node. */
1064         obstack_free (current_ir_graph->obst, n);
1065         return new_Const (get_tarval_mode (tv), tv);
1066       }
1067     }
1068   }
1069
1070   /* remove unnecessary nodes */
1071   if (get_opt_constant_folding() ||
1072       (get_irn_op(n) == op_Phi)  ||   /* always optimize these nodes. */
1073       (get_irn_op(n) == op_Id)   ||
1074       (get_irn_op(n) == op_Proj) ||
1075       (get_irn_op(n) == op_Block)  )  /* Flags tested local. */
1076     n = equivalent_node (n);
1077
1078   /** common subexpression elimination **/
1079   /* Checks whether n is already available. */
1080   /* The block input is used to distinguish different subexpressions. Right
1081      now all nodes are pinned to blocks, i.e., the cse only finds common
1082      subexpressions within a block. */
1083   if (get_opt_cse())
1084     n = identify_cons (current_ir_graph->value_table, n);
1085
1086   if (n != old_n) {
1087     /* We found an existing, better node, so we can deallocate the old node. */
1088     obstack_free (current_ir_graph->obst, old_n);
1089   }
1090
1091   /* Some more constant expression evaluation that does not allow to
1092      free the node. */
1093   if (get_opt_constant_folding() ||
1094       (get_irn_op(n) == op_Cond) ||
1095       (get_irn_op(n) == op_Proj))     /* Flags tested local. */
1096     n = transform_node (n);
1097
1098   /* Remove nodes with dead (Bad) input.
1099      Run always for transformation induced Bads. */
1100   n = gigo (n);
1101
1102   /* Now we can verify the node, as it has no dead inputs any more. */
1103   irn_vrfy(n);
1104
1105   /* Now we have a legal, useful node. Enter it in hash table for cse */
1106   if (get_opt_cse() && (get_irn_opcode(n) != iro_Block)) {
1107     n = identify_remember (current_ir_graph->value_table, n);
1108   }
1109
1110   return n;
1111 }
1112
1113
1114 /* These optimizations never deallocate nodes.  This can cause dead
1115    nodes lying on the obstack.  Remove these by a dead node elimination,
1116    i.e., a copying garbage collection. */
1117 ir_node *
1118 optimize_in_place_2 (ir_node *n)
1119 {
1120   tarval *tv;
1121   ir_node *old_n = n;
1122
1123   if (!get_optimize() && (get_irn_op(n) != op_Phi)) return n;
1124
1125   /* if not optimize return n */
1126   if (n == NULL) {
1127     assert(0);
1128     /* Here this is possible.  Why? */
1129     return n;
1130   }
1131
1132
1133   /* constant expression evaluation / constant folding */
1134   if (get_opt_constant_folding()) {
1135     /* constants can not be evaluated */
1136     if  (get_irn_op(n) != op_Const) {
1137       /* try to evaluate */
1138       tv = computed_value (n);
1139       if ((get_irn_mode(n) != mode_T) && (tv != tarval_bad)) {
1140         /* evaluation was succesful -- replace the node. */
1141         n = new_Const (get_tarval_mode (tv), tv);
1142         __dbg_info_merge_pair(n, old_n, dbg_const_eval);
1143         return n;
1144       }
1145     }
1146   }
1147
1148   /* remove unnecessary nodes */
1149   /*if (get_opt_constant_folding()) */
1150   if (get_opt_constant_folding() ||
1151       (get_irn_op(n) == op_Phi)  ||   /* always optimize these nodes. */
1152       (get_irn_op(n) == op_Id)   ||   /* ... */
1153       (get_irn_op(n) == op_Proj) ||   /* ... */
1154       (get_irn_op(n) == op_Block)  )  /* Flags tested local. */
1155     n = equivalent_node (n);
1156
1157   /** common subexpression elimination **/
1158   /* Checks whether n is already available. */
1159   /* The block input is used to distinguish different subexpressions.  Right
1160      now all nodes are pinned to blocks, i.e., the cse only finds common
1161      subexpressions within a block. */
1162   if (get_opt_cse()) {
1163     n = identify (current_ir_graph->value_table, n);
1164   }
1165
1166   /* Some more constant expression evaluation. */
1167   if (get_opt_constant_folding() ||
1168       (get_irn_op(n) == op_Cond) ||
1169       (get_irn_op(n) == op_Proj))     /* Flags tested local. */
1170     n = transform_node (n);
1171
1172   /* Remove nodes with dead (Bad) input.
1173      Run always for transformation induced Bads.  */
1174   n = gigo (n);
1175
1176   /* Now we can verify the node, as it has no dead inputs any more. */
1177   irn_vrfy(n);
1178
1179   /* Now we have a legal, useful node. Enter it in hash table for cse.
1180      Blocks should be unique anyways.  (Except the successor of start:
1181      is cse with the start block!) */
1182   if (get_opt_cse() && (get_irn_opcode(n) != iro_Block))
1183     n = identify_remember (current_ir_graph->value_table, n);
1184
1185   return n;
1186 }
1187
1188 /* Wrapper for external use, set proper status bits after optimization */
1189 ir_node *
1190 optimize_in_place (ir_node *n) {
1191   /* Handle graph state */
1192   assert(get_irg_phase_state(current_ir_graph) != phase_building);
1193   if (get_opt_global_cse())
1194     set_irg_pinned(current_ir_graph, floats);
1195   if (get_irg_outs_state(current_ir_graph) == outs_consistent)
1196     set_irg_outs_inconsistent(current_ir_graph);
1197   /* Maybe we could also test whether optimizing the node can
1198      change the control graph. */
1199   if (get_irg_dom_state(current_ir_graph) == dom_consistent)
1200     set_irg_dom_inconsistent(current_ir_graph);
1201   return optimize_in_place_2 (n);
1202 }