- fixed signed/unsigned warning
[libfirm] / ir / opt / combo.c
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Cliff Click's Combined Analysis/Optimization
23  * @author  Michael Beck
24  * @version $Id$
25  *
26  * This is a slightly enhanced version of Cliff Clicks combo algorithm
27  * - support for commutative nodes is added, Add(a,b) and Add(b,a) ARE congruent
28  * - supports all Firm direct (by a data edge) identities except Mux
29  *   (Mux can be a 2-input or 1-input identity, only 2-input is implemented yet)
30  * - supports Confirm nodes (handle them like Copies but do NOT remove them)
31  * - let Cmp nodes calculate Top like all othe data nodes: this would let
32  *   Mux nodes to calculate Unknown instead of taking the true result
33  * - let Cond(Top) always select FALSE/default: This is tricky. Nodes are only reavaluated
34  *   IFF the predecessor changed its type. Because nodes are initialized with Top
35  *   this never happens, let all Proj(Cond) be unreachable.
36  *   We avoid this condition by the same way we work around Phi: whenever a Block
37  *   node is placed on the list, place its Cond nodes (and because they are Tuple
38  *   all its Proj-nodes either on the cprop list)
39  *   Especially, this changes the meaning of Click's example:
40  *
41  *   int main() {
42  *     int x;
43  *
44  *     if (x == 2)
45  *       printf("x == 2\n");
46  *     if (x == 3)
47  *       printf("x == 3\n");
48  *   }
49  *
50  *   Would print:
51  *   x == 2
52  *   x == 3
53  *
54  *   using Click's version while is silent with our.
55  * - support for global congruences is implemented but not tested yet
56  *
57  * Note further that we use the terminology from Click's work here, which is different
58  * in some cases from Firm terminology.  Especially, Click's type is a
59  * Firm tarval/entity, nevertheless we call it type here for "maximum compatibility".
60  */
61 #include "config.h"
62
63 #include <assert.h>
64
65 #include "iroptimize.h"
66 #include "irflag.h"
67 #include "ircons.h"
68 #include "list.h"
69 #include "set.h"
70 #include "pmap.h"
71 #include "obstack.h"
72 #include "irgraph_t.h"
73 #include "irnode_t.h"
74 #include "iropt_t.h"
75 #include "irgwalk.h"
76 #include "irop.h"
77 #include "irouts.h"
78 #include "irgmod.h"
79 #include "iropt_dbg.h"
80 #include "debug.h"
81 #include "array_t.h"
82 #include "error.h"
83 #include "irnodeset.h"
84
85 #include "tv_t.h"
86
87 #include "irprintf.h"
88 #include "irdump.h"
89
90 /* define this to check that all type translations are monotone */
91 #define VERIFY_MONOTONE
92
93 /* define this to check the consistency of partitions */
94 #define CHECK_PARTITIONS
95
96 typedef struct node_t            node_t;
97 typedef struct partition_t       partition_t;
98 typedef struct opcode_key_t      opcode_key_t;
99 typedef struct listmap_entry_t   listmap_entry_t;
100
101 /** The type of the compute function. */
102 typedef void (*compute_func)(node_t *node);
103
104 /**
105  * An opcode map key.
106  */
107 struct opcode_key_t {
108         ir_opcode   code;   /**< The Firm opcode. */
109         ir_mode     *mode;  /**< The mode of all nodes in the partition. */
110         int         arity;  /**< The arity of this opcode (needed for Phi etc. */
111         union {
112                 long      proj;   /**< For Proj nodes, its proj number */
113                 ir_entity *ent;   /**< For Sel Nodes, its entity */
114                 int       intVal; /**< For Conv/Div Nodes: strict/remainderless */
115                 unsigned  uintVal;/**< for Builtin: the kind */
116                 ir_node   *block; /**< for Block: itself */
117                 void      *ptr;   /**< generic pointer for hash/cmp */
118         } u;
119 };
120
121 /**
122  * An entry in the list_map.
123  */
124 struct listmap_entry_t {
125         void            *id;    /**< The id. */
126         node_t          *list;  /**< The associated list for this id. */
127         listmap_entry_t *next;  /**< Link to the next entry in the map. */
128 };
129
130 /** We must map id's to lists. */
131 typedef struct listmap_t {
132         set             *map;    /**< Map id's to listmap_entry_t's */
133         listmap_entry_t *values; /**< List of all values in the map. */
134 } listmap_t;
135
136 /**
137  * A lattice element. Because we handle constants and symbolic constants different, we
138  * have to use this union.
139  */
140 typedef union {
141         tarval          *tv;
142         symconst_symbol sym;
143 } lattice_elem_t;
144
145 /**
146  * A node.
147  */
148 struct node_t {
149         ir_node         *node;          /**< The IR-node itself. */
150         list_head       node_list;      /**< Double-linked list of leader/follower entries. */
151         list_head       cprop_list;     /**< Double-linked partition.cprop list. */
152         partition_t     *part;          /**< points to the partition this node belongs to */
153         node_t          *next;          /**< Next node on local list (partition.touched, fallen). */
154         node_t          *race_next;     /**< Next node on race list. */
155         lattice_elem_t  type;           /**< The associated lattice element "type". */
156         int             max_user_input; /**< Maximum input number of Def-Use edges. */
157         int             next_edge;      /**< Index of the next Def-Use edge to use. */
158         int             n_followers;    /**< Number of Follower in the outs set. */
159         unsigned        on_touched:1;   /**< Set, if this node is on the partition.touched set. */
160         unsigned        on_cprop:1;     /**< Set, if this node is on the partition.cprop list. */
161         unsigned        on_fallen:1;    /**< Set, if this node is on the fallen list. */
162         unsigned        is_follower:1;  /**< Set, if this node is a follower. */
163         unsigned        flagged:2;      /**< 2 Bits, set if this node was visited by race 1 or 2. */
164 };
165
166 /**
167  * A partition containing congruent nodes.
168  */
169 struct partition_t {
170         list_head         Leader;          /**< The head of partition Leader node list. */
171         list_head         Follower;        /**< The head of partition Follower node list. */
172         list_head         cprop;           /**< The head of partition.cprop list. */
173         list_head         cprop_X;         /**< The head of partition.cprop (Cond nodes and its Projs) list. */
174         partition_t       *wl_next;        /**< Next entry in the work list if any. */
175         partition_t       *touched_next;   /**< Points to the next partition in the touched set. */
176         partition_t       *cprop_next;     /**< Points to the next partition in the cprop list. */
177         partition_t       *split_next;     /**< Points to the next partition in the list that must be split by split_by(). */
178         node_t            *touched;        /**< The partition.touched set of this partition. */
179         unsigned          n_leader;        /**< Number of entries in this partition.Leader. */
180         unsigned          n_touched;       /**< Number of entries in the partition.touched. */
181         int               max_user_inputs; /**< Maximum number of user inputs of all entries. */
182         unsigned          on_worklist:1;   /**< Set, if this partition is in the work list. */
183         unsigned          on_touched:1;    /**< Set, if this partition is on the touched set. */
184         unsigned          on_cprop:1;      /**< Set, if this partition is on the cprop list. */
185         unsigned          type_is_T_or_C:1;/**< Set, if all nodes in this partition have type Top or Constant. */
186 #ifdef DEBUG_libfirm
187         partition_t       *dbg_next;       /**< Link all partitions for debugging */
188         unsigned          nr;              /**< A unique number for (what-)mapping, >0. */
189 #endif
190 };
191
192 typedef struct environment_t {
193         struct obstack  obst;           /**< obstack to allocate data structures. */
194         partition_t     *worklist;      /**< The work list. */
195         partition_t     *cprop;         /**< The constant propagation list. */
196         partition_t     *touched;       /**< the touched set. */
197         partition_t     *initial;       /**< The initial partition. */
198         set             *opcode2id_map; /**< The opcodeMode->id map. */
199         pmap            *type2id_map;   /**< The type->id map. */
200         ir_node         **kept_memory;  /**< Array of memory nodes that must be kept. */
201         int             end_idx;        /**< -1 for local and 0 for global congruences. */
202         int             lambda_input;   /**< Captured argument for lambda_partition(). */
203         unsigned        modified:1;     /**< Set, if the graph was modified. */
204         unsigned        unopt_cf:1;     /**< If set, control flow is not optimized due to Unknown. */
205         /* options driving the optimization */
206         unsigned        commutative:1;  /**< Set, if commutation nodes should be handled specially. */
207         unsigned        opt_unknown:1;  /**< Set, if non-strict programs should be optimized. */
208 #ifdef DEBUG_libfirm
209         partition_t     *dbg_list;      /**< List of all partitions. */
210 #endif
211 } environment_t;
212
213 /** Type of the what function. */
214 typedef void *(*what_func)(const node_t *node, environment_t *env);
215
216 #define get_irn_node(irn)         ((node_t *)get_irn_link(irn))
217 #define set_irn_node(irn, node)   set_irn_link(irn, node)
218
219 /* we do NOT use tarval_unreachable here, instead we use Top for this purpose */
220 #undef tarval_unreachable
221 #define tarval_unreachable tarval_top
222
223
224 /** The debug module handle. */
225 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
226
227 /** The what reason. */
228 DEBUG_ONLY(static const char *what_reason;)
229
230 /** Next partition number. */
231 DEBUG_ONLY(static unsigned part_nr = 0);
232
233 /** The tarval returned by Unknown nodes: set to either tarval_bad OR tarval_top. */
234 static tarval *tarval_UNKNOWN;
235
236 /* forward */
237 static node_t *identity(node_t *node);
238
239 #ifdef CHECK_PARTITIONS
240 /**
241  * Check a partition.
242  */
243 static void check_partition(const partition_t *T) {
244         node_t   *node;
245         unsigned n = 0;
246
247         list_for_each_entry(node_t, node, &T->Leader, node_list) {
248                 assert(node->is_follower == 0);
249                 assert(node->flagged == 0);
250                 assert(node->part == T);
251                 ++n;
252         }
253         assert(n == T->n_leader);
254
255         list_for_each_entry(node_t, node, &T->Follower, node_list) {
256                 assert(node->is_follower == 1);
257                 assert(node->flagged == 0);
258                 assert(node->part == T);
259         }
260 }  /* check_partition */
261
262 /**
263  * check that all leader nodes in the partition have the same opcode.
264  */
265 static void check_opcode(const partition_t *Z) {
266         node_t       *node;
267         opcode_key_t key;
268         int          first = 1;
269
270         list_for_each_entry(node_t, node, &Z->Leader, node_list) {
271                 ir_node *irn = node->node;
272
273                 if (first) {
274                         key.code   = get_irn_opcode(irn);
275                         key.mode   = get_irn_mode(irn);
276                         key.arity  = get_irn_arity(irn);
277                         key.u.proj = 0;
278                         key.u.ent  = NULL;
279
280                         switch (get_irn_opcode(irn)) {
281                         case iro_Proj:
282                                 key.u.proj = get_Proj_proj(irn);
283                                 break;
284                         case iro_Sel:
285                                 key.u.ent = get_Sel_entity(irn);
286                                 break;
287                         case iro_Conv:
288                                 key.u.intVal = get_Conv_strict(irn);
289                                 break;
290                         case iro_Div:
291                                 key.u.intVal = is_Div_remainderless(irn);
292                                 break;
293                         case iro_Block:
294                                 key.u.block = irn;
295                                 break;
296                         case iro_Load:
297                                 key.mode = get_Load_mode(irn);
298                                 break;
299                         case iro_Builtin:
300                                 key.u.intVal = get_Builtin_kind(irn);
301                                 break;
302                         default:
303                                 break;
304                         }
305                         first = 0;
306                 } else {
307                         assert((unsigned)key.code  == get_irn_opcode(irn));
308                         assert(key.mode  == get_irn_mode(irn));
309                         assert(key.arity == get_irn_arity(irn));
310
311                         switch (get_irn_opcode(irn)) {
312                         case iro_Proj:
313                                 assert(key.u.proj == get_Proj_proj(irn));
314                                 break;
315                         case iro_Sel:
316                                 assert(key.u.ent == get_Sel_entity(irn));
317                                 break;
318                         case iro_Conv:
319                                 assert(key.u.intVal == get_Conv_strict(irn));
320                                 break;
321                         case iro_Div:
322                                 assert(key.u.intVal == is_Div_remainderless(irn));
323                                 break;
324                         case iro_Block:
325                                 assert(key.u.block == irn);
326                                 break;
327                         case iro_Load:
328                                 assert(key.mode == get_Load_mode(irn));
329                                 break;
330                         case iro_Builtin:
331                                 assert(key.u.intVal == get_Builtin_kind(irn));
332                                 break;
333                         default:
334                                 break;
335                         }
336                 }
337         }
338 }  /* check_opcode */
339
340 static void check_all_partitions(environment_t *env) {
341 #ifdef DEBUG_libfirm
342         partition_t *P;
343         node_t      *node;
344
345         for (P = env->dbg_list; P != NULL; P = P->dbg_next) {
346                 check_partition(P);
347                 if (! P->type_is_T_or_C)
348                         check_opcode(P);
349                 list_for_each_entry(node_t, node, &P->Follower, node_list) {
350                         node_t *leader = identity(node);
351
352                         assert(leader != node && leader->part == node->part);
353                 }
354         }
355 #endif
356 }
357
358 /**
359  * Check list.
360  */
361 static void do_check_list(const node_t *list, int ofs, const partition_t *Z) {
362         const node_t *e;
363
364 #define NEXT(e)  *((const node_t **)((char *)(e) + (ofs)))
365         for (e = list; e != NULL; e = NEXT(e)) {
366                 assert(e->part == Z);
367         }
368 #undef NEXT
369 }  /* ido_check_list */
370
371 /**
372  * Check a local list.
373  */
374 static void check_list(const node_t *list, const partition_t *Z) {
375         do_check_list(list, offsetof(node_t, next), Z);
376 }  /* check_list */
377
378 #else
379 #define check_partition(T)
380 #define check_list(list, Z)
381 #define check_all_partitions(env)
382 #endif /* CHECK_PARTITIONS */
383
384 #ifdef DEBUG_libfirm
385 static inline lattice_elem_t get_partition_type(const partition_t *X);
386
387 /**
388  * Dump partition to output.
389  */
390 static void dump_partition(const char *msg, const partition_t *part) {
391         const node_t   *node;
392         int            first = 1;
393         lattice_elem_t type = get_partition_type(part);
394
395         DB((dbg, LEVEL_2, "%s part%u%s (%u, %+F) {\n  ",
396                 msg, part->nr, part->type_is_T_or_C ? "*" : "",
397                 part->n_leader, type));
398         list_for_each_entry(node_t, node, &part->Leader, node_list) {
399                 DB((dbg, LEVEL_2, "%s%+F", first ? "" : ", ", node->node));
400                 first = 0;
401         }
402         if (! list_empty(&part->Follower)) {
403                 DB((dbg, LEVEL_2, "\n---\n  "));
404                 first = 1;
405                 list_for_each_entry(node_t, node, &part->Follower, node_list) {
406                         DB((dbg, LEVEL_2, "%s%+F", first ? "" : ", ", node->node));
407                         first = 0;
408                 }
409         }
410         DB((dbg, LEVEL_2, "\n}\n"));
411 }  /* dump_partition */
412
413 /**
414  * Dumps a list.
415  */
416 static void do_dump_list(const char *msg, const node_t *node, int ofs) {
417         const node_t *p;
418         int          first = 1;
419
420 #define GET_LINK(p, ofs)  *((const node_t **)((char *)(p) + (ofs)))
421
422         DB((dbg, LEVEL_3, "%s = {\n  ", msg));
423         for (p = node; p != NULL; p = GET_LINK(p, ofs)) {
424                 DB((dbg, LEVEL_3, "%s%+F", first ? "" : ", ", p->node));
425                 first = 0;
426         }
427         DB((dbg, LEVEL_3, "\n}\n"));
428
429 #undef GET_LINK
430 }  /* do_dump_list */
431
432 /**
433  * Dumps a race list.
434  */
435 static void dump_race_list(const char *msg, const node_t *list) {
436         do_dump_list(msg, list, offsetof(node_t, race_next));
437 }  /* dump_race_list */
438
439 /**
440  * Dumps a local list.
441  */
442 static void dump_list(const char *msg, const node_t *list) {
443         do_dump_list(msg, list, offsetof(node_t, next));
444 }  /* dump_list */
445
446 /**
447  * Dump all partitions.
448  */
449 static void dump_all_partitions(const environment_t *env) {
450         const partition_t *P;
451
452         DB((dbg, LEVEL_2, "All partitions\n===============\n"));
453         for (P = env->dbg_list; P != NULL; P = P->dbg_next)
454                 dump_partition("", P);
455 }  /* dump_all_partitions */
456
457 /**
458  * Sump a split list.
459  */
460 static void dump_split_list(const partition_t *list) {
461         const partition_t *p;
462
463         DB((dbg, LEVEL_2, "Split by %s produced = {\n", what_reason));
464         for (p = list; p != NULL; p = p->split_next)
465                 DB((dbg, LEVEL_2, "part%u, ", p->nr));
466         DB((dbg, LEVEL_2, "\n}\n"));
467 }  /* dump_split_list */
468
469 /**
470  * Dump partition and type for a node.
471  */
472 static int dump_partition_hook(FILE *F, ir_node *n, ir_node *local) {
473         ir_node *irn = local != NULL ? local : n;
474         node_t *node = get_irn_node(irn);
475
476         ir_fprintf(F, "info2 : \"partition %u type %+F\"\n", node->part->nr, node->type);
477         return 1;
478 }  /* dump_partition_hook */
479
480 #else
481 #define dump_partition(msg, part)
482 #define dump_race_list(msg, list)
483 #define dump_list(msg, list)
484 #define dump_all_partitions(env)
485 #define dump_split_list(list)
486 #endif
487
488 #if defined(VERIFY_MONOTONE) && defined (DEBUG_libfirm)
489 /**
490  * Verify that a type transition is monotone
491  */
492 static void verify_type(const lattice_elem_t old_type, node_t *node) {
493         if (old_type.tv == node->type.tv) {
494                 /* no change */
495                 return;
496         }
497         if (old_type.tv == tarval_top) {
498                 /* from Top down-to is always allowed */
499                 return;
500         }
501         if (node->type.tv == tarval_bottom || node->type.tv == tarval_reachable) {
502                 /* bottom reached */
503                 return;
504         }
505         panic("combo: wrong translation from %+F to %+F on node %+F", old_type, node->type, node->node);
506 }  /* verify_type */
507
508 #else
509 #define verify_type(old_type, node)
510 #endif
511
512 /**
513  * Compare two pointer values of a listmap.
514  */
515 static int listmap_cmp_ptr(const void *elt, const void *key, size_t size) {
516         const listmap_entry_t *e1 = elt;
517         const listmap_entry_t *e2 = key;
518
519         (void) size;
520         return e1->id != e2->id;
521 }  /* listmap_cmp_ptr */
522
523 /**
524  * Initializes a listmap.
525  *
526  * @param map  the listmap
527  */
528 static void listmap_init(listmap_t *map) {
529         map->map    = new_set(listmap_cmp_ptr, 16);
530         map->values = NULL;
531 }  /* listmap_init */
532
533 /**
534  * Terminates a listmap.
535  *
536  * @param map  the listmap
537  */
538 static void listmap_term(listmap_t *map) {
539         del_set(map->map);
540 }  /* listmap_term */
541
542 /**
543  * Return the associated listmap entry for a given id.
544  *
545  * @param map  the listmap
546  * @param id   the id to search for
547  *
548  * @return the associated listmap entry for the given id
549  */
550 static listmap_entry_t *listmap_find(listmap_t *map, void *id) {
551         listmap_entry_t key, *entry;
552
553         key.id   = id;
554         key.list = NULL;
555         key.next = NULL;
556         entry = set_insert(map->map, &key, sizeof(key), HASH_PTR(id));
557
558         if (entry->list == NULL) {
559                 /* a new entry, put into the list */
560                 entry->next = map->values;
561                 map->values = entry;
562         }
563         return entry;
564 }  /* listmap_find */
565
566 /**
567  * Calculate the hash value for an opcode map entry.
568  *
569  * @param entry  an opcode map entry
570  *
571  * @return a hash value for the given opcode map entry
572  */
573 static unsigned opcode_hash(const opcode_key_t *entry) {
574         return (entry->mode - (ir_mode *)0) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.ptr) + entry->arity;
575 }  /* opcode_hash */
576
577 /**
578  * Compare two entries in the opcode map.
579  */
580 static int cmp_opcode(const void *elt, const void *key, size_t size) {
581         const opcode_key_t *o1 = elt;
582         const opcode_key_t *o2 = key;
583
584         (void) size;
585         return o1->code != o2->code || o1->mode != o2->mode ||
586                o1->arity != o2->arity ||
587                o1->u.proj != o2->u.proj ||
588                o1->u.intVal != o2->u.intVal || /* this already checks uIntVal */
589                o1->u.ptr != o2->u.ptr;
590 }  /* cmp_opcode */
591
592 /**
593  * Compare two Def-Use edges for input position.
594  */
595 static int cmp_def_use_edge(const void *a, const void *b) {
596         const ir_def_use_edge *ea = a;
597         const ir_def_use_edge *eb = b;
598
599         /* no overrun, because range is [-1, MAXINT] */
600         return ea->pos - eb->pos;
601 }  /* cmp_def_use_edge */
602
603 /**
604  * We need the Def-Use edges sorted.
605  */
606 static void sort_irn_outs(node_t *node) {
607         ir_node *irn = node->node;
608         int n_outs = get_irn_n_outs(irn);
609
610         if (n_outs > 1) {
611                 qsort(&irn->out[1], n_outs, sizeof(irn->out[0]), cmp_def_use_edge);
612         }
613         node->max_user_input = irn->out[n_outs].pos;
614 }  /* sort_irn_outs */
615
616 /**
617  * Return the type of a node.
618  *
619  * @param irn  an IR-node
620  *
621  * @return the associated type of this node
622  */
623 static inline lattice_elem_t get_node_type(const ir_node *irn) {
624         return get_irn_node(irn)->type;
625 }  /* get_node_type */
626
627 /**
628  * Return the tarval of a node.
629  *
630  * @param irn  an IR-node
631  *
632  * @return the associated type of this node
633  */
634 static inline tarval *get_node_tarval(const ir_node *irn) {
635         lattice_elem_t type = get_node_type(irn);
636
637         if (is_tarval(type.tv))
638                 return type.tv;
639         return tarval_bottom;
640 }  /* get_node_type */
641
642 /**
643  * Add a partition to the worklist.
644  */
645 static inline void add_to_worklist(partition_t *X, environment_t *env) {
646         assert(X->on_worklist == 0);
647         DB((dbg, LEVEL_2, "Adding part%d to worklist\n", X->nr));
648         X->wl_next     = env->worklist;
649         X->on_worklist = 1;
650         env->worklist  = X;
651 }  /* add_to_worklist */
652
653 /**
654  * Create a new empty partition.
655  *
656  * @param env   the environment
657  *
658  * @return a newly allocated partition
659  */
660 static inline partition_t *new_partition(environment_t *env) {
661         partition_t *part = obstack_alloc(&env->obst, sizeof(*part));
662
663         INIT_LIST_HEAD(&part->Leader);
664         INIT_LIST_HEAD(&part->Follower);
665         INIT_LIST_HEAD(&part->cprop);
666         INIT_LIST_HEAD(&part->cprop_X);
667         part->wl_next         = NULL;
668         part->touched_next    = NULL;
669         part->cprop_next      = NULL;
670         part->split_next      = NULL;
671         part->touched         = NULL;
672         part->n_leader        = 0;
673         part->n_touched       = 0;
674         part->max_user_inputs = 0;
675         part->on_worklist     = 0;
676         part->on_touched      = 0;
677         part->on_cprop        = 0;
678         part->type_is_T_or_C  = 0;
679 #ifdef DEBUG_libfirm
680         part->dbg_next        = env->dbg_list;
681         env->dbg_list         = part;
682         part->nr              = part_nr++;
683 #endif
684
685         return part;
686 }  /* new_partition */
687
688 /**
689  * Get the first node from a partition.
690  */
691 static inline node_t *get_first_node(const partition_t *X) {
692         return list_entry(X->Leader.next, node_t, node_list);
693 }  /* get_first_node */
694
695 /**
696  * Return the type of a partition (assuming partition is non-empty and
697  * all elements have the same type).
698  *
699  * @param X  a partition
700  *
701  * @return the type of the first element of the partition
702  */
703 static inline lattice_elem_t get_partition_type(const partition_t *X) {
704         const node_t *first = get_first_node(X);
705         return first->type;
706 }  /* get_partition_type */
707
708 /**
709  * Creates a partition node for the given IR-node and place it
710  * into the given partition.
711  *
712  * @param irn   an IR-node
713  * @param part  a partition to place the node in
714  * @param env   the environment
715  *
716  * @return the created node
717  */
718 static node_t *create_partition_node(ir_node *irn, partition_t *part, environment_t *env) {
719         /* create a partition node and place it in the partition */
720         node_t *node = obstack_alloc(&env->obst, sizeof(*node));
721
722         INIT_LIST_HEAD(&node->node_list);
723         INIT_LIST_HEAD(&node->cprop_list);
724         node->node           = irn;
725         node->part           = part;
726         node->next           = NULL;
727         node->race_next      = NULL;
728         node->type.tv        = tarval_top;
729         node->max_user_input = 0;
730         node->next_edge      = 0;
731         node->n_followers    = 0;
732         node->on_touched     = 0;
733         node->on_cprop       = 0;
734         node->on_fallen      = 0;
735         node->is_follower    = 0;
736         node->flagged        = 0;
737         set_irn_node(irn, node);
738
739         list_add_tail(&node->node_list, &part->Leader);
740         ++part->n_leader;
741
742         return node;
743 }  /* create_partition_node */
744
745 /**
746  * Pre-Walker, initialize all Nodes' type to U or top and place
747  * all nodes into the TOP partition.
748  */
749 static void create_initial_partitions(ir_node *irn, void *ctx) {
750         environment_t *env  = ctx;
751         partition_t   *part = env->initial;
752         node_t        *node;
753
754         node = create_partition_node(irn, part, env);
755         sort_irn_outs(node);
756         if (node->max_user_input > part->max_user_inputs)
757                 part->max_user_inputs = node->max_user_input;
758
759         if (is_Block(irn)) {
760                 set_Block_phis(irn, NULL);
761         }
762 }  /* create_initial_partitions */
763
764 /**
765  * Post-Walker, collect  all Block-Phi lists, set Cond.
766  */
767 static void init_block_phis(ir_node *irn, void *ctx) {
768         (void) ctx;
769
770         if (is_Phi(irn)) {
771                 add_Block_phi(get_nodes_block(irn), irn);
772         }
773 }  /* init_block_phis */
774
775 /**
776  * Add a node to the entry.partition.touched set and
777  * node->partition to the touched set if not already there.
778  *
779  * @param y    a node
780  * @param env  the environment
781  */
782 static inline void add_to_touched(node_t *y, environment_t *env) {
783         if (y->on_touched == 0) {
784                 partition_t *part = y->part;
785
786                 y->next       = part->touched;
787                 part->touched = y;
788                 y->on_touched = 1;
789                 ++part->n_touched;
790
791                 if (part->on_touched == 0) {
792                         part->touched_next = env->touched;
793                         env->touched       = part;
794                         part->on_touched   = 1;
795                 }
796
797                 check_list(part->touched, part);
798         }
799 }  /* add_to_touched */
800
801 /**
802  * Place a node on the cprop list.
803  *
804  * @param y    the node
805  * @param env  the environment
806  */
807 static void add_to_cprop(node_t *y, environment_t *env) {
808         ir_node *irn;
809
810         /* Add y to y.partition.cprop. */
811         if (y->on_cprop == 0) {
812                 partition_t *Y = y->part;
813                 ir_node *irn   = y->node;
814
815                 /* place Conds and all its Projs on the cprop_X list */
816                 if (is_Cond(skip_Proj(irn)))
817                         list_add_tail(&y->cprop_list, &Y->cprop_X);
818                 else
819                         list_add_tail(&y->cprop_list, &Y->cprop);
820                 y->on_cprop   = 1;
821
822                 DB((dbg, LEVEL_3, "Add %+F to part%u.cprop\n", y->node, Y->nr));
823
824                 /* place its partition on the cprop list */
825                 if (Y->on_cprop == 0) {
826                         Y->cprop_next = env->cprop;
827                         env->cprop    = Y;
828                         Y->on_cprop   = 1;
829                 }
830         }
831         irn = y->node;
832         if (get_irn_mode(irn) == mode_T) {
833                 /* mode_T nodes always produce tarval_bottom, so we must explicitly
834                    add it's Proj's to get constant evaluation to work */
835                 int i;
836
837                 for (i = get_irn_n_outs(irn) - 1; i >= 0; --i) {
838                         node_t *proj = get_irn_node(get_irn_out(irn, i));
839
840                         add_to_cprop(proj, env);
841                 }
842         } else if (is_Block(irn)) {
843                 /* Due to the way we handle Phi's, we must place all Phis of a block on the list
844                  * if someone placed the block. The Block is only placed if the reachability
845                  * changes, and this must be re-evaluated in compute_Phi(). */
846                 ir_node *phi;
847                 for (phi = get_Block_phis(irn); phi != NULL; phi = get_Phi_next(phi)) {
848                         node_t *p = get_irn_node(phi);
849                         add_to_cprop(p, env);
850                 }
851         }
852 }  /* add_to_cprop */
853
854 /**
855  * Update the worklist: If Z is on worklist then add Z' to worklist.
856  * Else add the smaller of Z and Z' to worklist.
857  *
858  * @param Z        the Z partition
859  * @param Z_prime  the Z' partition, a previous part of Z
860  * @param env      the environment
861  */
862 static void update_worklist(partition_t *Z, partition_t *Z_prime, environment_t *env) {
863         if (Z->on_worklist || Z_prime->n_leader < Z->n_leader) {
864                 add_to_worklist(Z_prime, env);
865         } else {
866                 add_to_worklist(Z, env);
867         }
868 }  /* update_worklist */
869
870 /**
871  * Make all inputs to x no longer be F.def_use edges.
872  *
873  * @param x  the node
874  */
875 static void move_edges_to_leader(node_t *x) {
876         ir_node     *irn = x->node;
877         int         i, j, k;
878
879         for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
880                 node_t  *pred = get_irn_node(get_irn_n(irn, i));
881                 ir_node *p;
882                 int     n;
883
884                 p = pred->node;
885                 n = get_irn_n_outs(p);
886                 for (j = 1; j <= pred->n_followers; ++j) {
887                         if (p->out[j].pos == i && p->out[j].use == irn) {
888                                 /* found a follower edge to x, move it to the Leader */
889                                 ir_def_use_edge edge = p->out[j];
890
891                                 /* remove this edge from the Follower set */
892                                 p->out[j] = p->out[pred->n_followers];
893                                 --pred->n_followers;
894
895                                 /* sort it into the leader set */
896                                 for (k = pred->n_followers + 2; k <= n; ++k) {
897                                         if (p->out[k].pos >= edge.pos)
898                                                 break;
899                                         p->out[k - 1] = p->out[k];
900                                 }
901                                 /* place the new edge here */
902                                 p->out[k - 1] = edge;
903
904                                 /* edge found and moved */
905                                 break;
906                         }
907                 }
908         }
909 }  /* move_edges_to_leader */
910
911 /**
912  * Split a partition that has NO followers by a local list.
913  *
914  * @param Z    partition to split
915  * @param g    a (non-empty) node list
916  * @param env  the environment
917  *
918  * @return  a new partition containing the nodes of g
919  */
920 static partition_t *split_no_followers(partition_t *Z, node_t *g, environment_t *env) {
921         partition_t *Z_prime;
922         node_t      *node;
923         unsigned    n = 0;
924         int         max_input;
925
926         dump_partition("Splitting ", Z);
927         dump_list("by list ", g);
928
929         assert(g != NULL);
930
931         /* Remove g from Z. */
932         for (node = g; node != NULL; node = node->next) {
933                 assert(node->part == Z);
934                 list_del(&node->node_list);
935                 ++n;
936         }
937         assert(n < Z->n_leader);
938         Z->n_leader -= n;
939
940         /* Move g to a new partition, Z'. */
941         Z_prime = new_partition(env);
942         max_input = 0;
943         for (node = g; node != NULL; node = node->next) {
944                 list_add_tail(&node->node_list, &Z_prime->Leader);
945                 node->part = Z_prime;
946                 if (node->max_user_input > max_input)
947                         max_input = node->max_user_input;
948         }
949         Z_prime->max_user_inputs = max_input;
950         Z_prime->n_leader        = n;
951
952         check_partition(Z);
953         check_partition(Z_prime);
954
955         /* for now, copy the type info tag, it will be adjusted in split_by(). */
956         Z_prime->type_is_T_or_C = Z->type_is_T_or_C;
957
958         update_worklist(Z, Z_prime, env);
959
960         dump_partition("Now ", Z);
961         dump_partition("Created new ", Z_prime);
962         return Z_prime;
963 }  /* split_no_followers */
964
965 /**
966  * Make the Follower -> Leader transition for a node.
967  *
968  * @param n  the node
969  */
970 static void follower_to_leader(node_t *n) {
971         assert(n->is_follower == 1);
972
973         DB((dbg, LEVEL_2, "%+F make the follower -> leader transition\n", n->node));
974         n->is_follower = 0;
975         move_edges_to_leader(n);
976         list_del(&n->node_list);
977         list_add_tail(&n->node_list, &n->part->Leader);
978         ++n->part->n_leader;
979 }  /* follower_to_leader */
980
981 /**
982  * The environment for one race step.
983  */
984 typedef struct step_env {
985         node_t   *initial;    /**< The initial node list. */
986         node_t   *unwalked;   /**< The unwalked node list. */
987         node_t   *walked;     /**< The walked node list. */
988         int      index;       /**< Next index of Follower use_def edge. */
989         unsigned side;        /**< side number. */
990 } step_env;
991
992 /**
993  * Return non-zero, if a input is a real follower
994  *
995  * @param irn    the node to check
996  * @param input  number of the input
997  */
998 static int is_real_follower(const ir_node *irn, int input) {
999         node_t *pred;
1000
1001         switch (get_irn_opcode(irn)) {
1002         case iro_Confirm:
1003                 if (input == 1) {
1004                         /* ignore the Confirm bound input */
1005                         return 0;
1006                 }
1007                 break;
1008         case iro_Mux:
1009                 if (input == 0) {
1010                         /* ignore the Mux sel input */
1011                         return 0;
1012                 }
1013                 break;
1014         case iro_Phi: {
1015                 /* dead inputs are not follower edges */
1016                 ir_node *block = get_nodes_block(irn);
1017                 node_t  *pred  = get_irn_node(get_Block_cfgpred(block, input));
1018
1019                 if (pred->type.tv == tarval_unreachable)
1020                         return 0;
1021                 break;
1022         }
1023         case iro_Sub:
1024         case iro_Shr:
1025         case iro_Shl:
1026         case iro_Shrs:
1027         case iro_Rotl:
1028                 if (input == 1) {
1029                         /* only a Sub x,0 / Shift x,0 might be a follower */
1030                         return 0;
1031                 }
1032                 break;
1033         case iro_Add:
1034         case iro_Or:
1035         case iro_Eor:
1036                 pred = get_irn_node(get_irn_n(irn, input));
1037                 if (is_tarval(pred->type.tv) && tarval_is_null(pred->type.tv))
1038                         return 0;
1039                 break;
1040         case iro_Mul:
1041                 pred = get_irn_node(get_irn_n(irn, input));
1042                 if (is_tarval(pred->type.tv) && tarval_is_one(pred->type.tv))
1043                         return 0;
1044                 break;
1045         case iro_And:
1046                 pred = get_irn_node(get_irn_n(irn, input));
1047                 if (is_tarval(pred->type.tv) && tarval_is_all_one(pred->type.tv))
1048                         return 0;
1049                 break;
1050         default:
1051                 assert(!"opcode not implemented yet");
1052                 break;
1053         }
1054         return 1;
1055 }  /* is_real_follower */
1056
1057 /**
1058  * Do one step in the race.
1059  */
1060 static int step(step_env *env) {
1061         node_t *n;
1062
1063         if (env->initial != NULL) {
1064                 /* Move node from initial to unwalked */
1065                 n             = env->initial;
1066                 env->initial  = n->race_next;
1067
1068                 n->race_next  = env->unwalked;
1069                 env->unwalked = n;
1070
1071                 return 0;
1072         }
1073
1074         while (env->unwalked != NULL) {
1075                 /* let n be the first node in unwalked */
1076                 n = env->unwalked;
1077                 while (env->index < n->n_followers) {
1078                         const ir_def_use_edge *edge = &n->node->out[1 + env->index];
1079
1080                         /* let m be n.F.def_use[index] */
1081                         node_t *m = get_irn_node(edge->use);
1082
1083                         assert(m->is_follower);
1084                         /*
1085                          * Some inputs, like the get_Confirm_bound are NOT
1086                          * real followers, sort them out.
1087                          */
1088                         if (! is_real_follower(m->node, edge->pos)) {
1089                                 ++env->index;
1090                                 continue;
1091                         }
1092                         ++env->index;
1093
1094                         /* only followers from our partition */
1095                         if (m->part != n->part)
1096                                 continue;
1097
1098                         if ((m->flagged & env->side) == 0) {
1099                                 m->flagged |= env->side;
1100
1101                                 if (m->flagged != 3) {
1102                                         /* visited the first time */
1103                                         /* add m to unwalked not as first node (we might still need to
1104                                            check for more follower node */
1105                                         m->race_next = n->race_next;
1106                                         n->race_next = m;
1107                                         return 0;
1108                                 }
1109                                 /* else already visited by the other side and on the other list */
1110                         }
1111                 }
1112                 /* move n to walked */
1113                 env->unwalked = n->race_next;
1114                 n->race_next  = env->walked;
1115                 env->walked   = n;
1116                 env->index    = 0;
1117         }
1118         return 1;
1119 }  /* step */
1120
1121 /**
1122  * Clear the flags from a list and check for
1123  * nodes that where touched from both sides.
1124  *
1125  * @param list  the list
1126  */
1127 static int clear_flags(node_t *list) {
1128         int    res = 0;
1129         node_t *n;
1130
1131         for (n = list; n != NULL; n = n->race_next) {
1132                 if (n->flagged == 3) {
1133                         /* we reach a follower from both sides, this will split congruent
1134                          * inputs and make it a leader. */
1135                         follower_to_leader(n);
1136                         res = 1;
1137                 }
1138                 n->flagged = 0;
1139         }
1140         return res;
1141 }  /* clear_flags */
1142
1143 /**
1144  * Split a partition by a local list using the race.
1145  *
1146  * @param pX   pointer to the partition to split, might be changed!
1147  * @param gg   a (non-empty) node list
1148  * @param env  the environment
1149  *
1150  * @return  a new partition containing the nodes of gg
1151  */
1152 static partition_t *split(partition_t **pX, node_t *gg, environment_t *env) {
1153         partition_t *X = *pX;
1154         partition_t *X_prime;
1155         list_head   tmp;
1156         step_env    senv[2];
1157         node_t      *g, *h, *node, *t;
1158         int         max_input, transitions, winner, shf;
1159         unsigned    n;
1160         DEBUG_ONLY(static int run = 0;)
1161
1162         DB((dbg, LEVEL_2, "Run %d ", run++));
1163         if (list_empty(&X->Follower)) {
1164                 /* if the partition has NO follower, we can use the fast
1165                    splitting algorithm. */
1166                 return split_no_followers(X, gg, env);
1167         }
1168         /* else do the race */
1169
1170         dump_partition("Splitting ", X);
1171         dump_list("by list ", gg);
1172
1173         INIT_LIST_HEAD(&tmp);
1174
1175         /* Remove gg from X.Leader and put into g */
1176         g = NULL;
1177         for (node = gg; node != NULL; node = node->next) {
1178                 assert(node->part == X);
1179                 assert(node->is_follower == 0);
1180
1181                 list_del(&node->node_list);
1182                 list_add_tail(&node->node_list, &tmp);
1183                 node->race_next = g;
1184                 g               = node;
1185         }
1186         /* produce h */
1187         h = NULL;
1188         list_for_each_entry(node_t, node, &X->Leader, node_list) {
1189                 node->race_next = h;
1190                 h               = node;
1191         }
1192         /* restore X.Leader */
1193         list_splice(&tmp, &X->Leader);
1194
1195         senv[0].initial   = g;
1196         senv[0].unwalked  = NULL;
1197         senv[0].walked    = NULL;
1198         senv[0].index     = 0;
1199         senv[0].side      = 1;
1200
1201         senv[1].initial   = h;
1202         senv[1].unwalked  = NULL;
1203         senv[1].walked    = NULL;
1204         senv[1].index     = 0;
1205         senv[1].side      = 2;
1206
1207         /*
1208          * Some informations on the race that are not stated clearly in Click's
1209          * thesis.
1210          * 1) A follower stays on the side that reach him first.
1211          * 2) If the other side reches a follower, if will be converted to
1212          *    a leader. /This must be done after the race is over, else the
1213          *    edges we are iterating on are renumbered./
1214          * 3) /New leader might end up on both sides./
1215          * 4) /If one side ends up with new Leaders, we must ensure that
1216          *    they can split out by opcode, hence we have to put _every_
1217          *    partition with new Leader nodes on the cprop list, as
1218          *    opcode splitting is done by split_by() at the end of
1219          *    constant propagation./
1220          */
1221         for (;;) {
1222                 if (step(&senv[0])) {
1223                         winner = 0;
1224                         break;
1225                 }
1226                 if (step(&senv[1])) {
1227                         winner = 1;
1228                         break;
1229                 }
1230         }
1231         assert(senv[winner].initial == NULL);
1232         assert(senv[winner].unwalked == NULL);
1233
1234         /* clear flags from walked/unwalked */
1235         shf = winner;
1236         transitions  = clear_flags(senv[0].unwalked) << shf;
1237         transitions |= clear_flags(senv[0].walked)   << shf;
1238         shf ^= 1;
1239         transitions |= clear_flags(senv[1].unwalked) << shf;
1240         transitions |= clear_flags(senv[1].walked)   << shf;
1241
1242         dump_race_list("winner ", senv[winner].walked);
1243
1244         /* Move walked_{winner} to a new partition, X'. */
1245         X_prime   = new_partition(env);
1246         max_input = 0;
1247         n         = 0;
1248         for (node = senv[winner].walked; node != NULL; node = node->race_next) {
1249                 list_del(&node->node_list);
1250                 node->part = X_prime;
1251                 if (node->is_follower) {
1252                         list_add_tail(&node->node_list, &X_prime->Follower);
1253                 } else {
1254                         list_add_tail(&node->node_list, &X_prime->Leader);
1255                         ++n;
1256                 }
1257                 if (node->max_user_input > max_input)
1258                         max_input = node->max_user_input;
1259         }
1260         X_prime->n_leader        = n;
1261         X_prime->max_user_inputs = max_input;
1262         X->n_leader             -= X_prime->n_leader;
1263
1264         /* for now, copy the type info tag, it will be adjusted in split_by(). */
1265         X_prime->type_is_T_or_C = X->type_is_T_or_C;
1266
1267         /*
1268          * Even if a follower was not checked by both sides, it might have
1269          * loose its congruence, so we need to check this case for all follower.
1270          */
1271         list_for_each_entry_safe(node_t, node, t, &X_prime->Follower, node_list) {
1272                 if (identity(node) == node) {
1273                         follower_to_leader(node);
1274                         transitions |= 1;
1275                 }
1276         }
1277
1278         check_partition(X);
1279         check_partition(X_prime);
1280
1281         /* X' is the smaller part */
1282         add_to_worklist(X_prime, env);
1283
1284         /*
1285          * If there where follower to leader transitions, ensure that the nodes
1286          * can be split out if necessary.
1287          */
1288         if (transitions & 1) {
1289                 /* place winner partition on the cprop list */
1290                 if (X_prime->on_cprop == 0) {
1291                         X_prime->cprop_next = env->cprop;
1292                         env->cprop          = X_prime;
1293                         X_prime->on_cprop   = 1;
1294                 }
1295         }
1296         if (transitions & 2) {
1297                 /* place other partition on the cprop list */
1298                 if (X->on_cprop == 0) {
1299                         X->cprop_next = env->cprop;
1300                         env->cprop    = X;
1301                         X->on_cprop   = 1;
1302                 }
1303         }
1304
1305         dump_partition("Now ", X);
1306         dump_partition("Created new ", X_prime);
1307
1308         /* we have to ensure that the partition containing g is returned */
1309         if (winner != 0) {
1310                 *pX = X_prime;
1311                 return X;
1312         }
1313
1314         return X_prime;
1315 }  /* split */
1316
1317 /**
1318  * Returns non-zero if the i'th input of a Phi node is live.
1319  *
1320  * @param phi  a Phi-node
1321  * @param i    an input number
1322  *
1323  * @return non-zero if the i'th input of the given Phi node is live
1324  */
1325 static int is_live_input(ir_node *phi, int i) {
1326         if (i >= 0) {
1327                 ir_node        *block = get_nodes_block(phi);
1328                 ir_node        *pred  = get_Block_cfgpred(block, i);
1329                 lattice_elem_t type   = get_node_type(pred);
1330
1331                 return type.tv != tarval_unreachable;
1332         }
1333         /* else it's the control input, always live */
1334         return 1;
1335 }  /* is_live_input */
1336
1337 /**
1338  * Return non-zero if a type is a constant.
1339  */
1340 static int is_constant_type(lattice_elem_t type) {
1341         if (type.tv != tarval_bottom && type.tv != tarval_top)
1342                 return 1;
1343         return 0;
1344 }  /* is_constant_type */
1345
1346 /**
1347  * Check whether a type is neither Top or a constant.
1348  * Note: U is handled like Top here, R is a constant.
1349  *
1350  * @param type  the type to check
1351  */
1352 static int type_is_neither_top_nor_const(const lattice_elem_t type) {
1353         if (is_tarval(type.tv)) {
1354                 if (type.tv == tarval_top)
1355                         return 0;
1356                 if (tarval_is_constant(type.tv))
1357                         return 0;
1358         } else {
1359                 /* is a symconst */
1360                 return 0;
1361         }
1362         return 1;
1363 }  /* type_is_neither_top_nor_const */
1364
1365 /**
1366  * Collect nodes to the touched list.
1367  *
1368  * @param list  the list which contains the nodes that must be evaluated
1369  * @param idx   the index of the def_use edge to evaluate
1370  * @param env   the environment
1371  */
1372 static void collect_touched(list_head *list, int idx, environment_t *env) {
1373         node_t  *x, *y;
1374         int     end_idx = env->end_idx;
1375
1376         list_for_each_entry(node_t, x, list, node_list) {
1377                 int num_edges;
1378
1379                 if (idx == -1) {
1380                         /* leader edges start AFTER follower edges */
1381                         x->next_edge = x->n_followers + 1;
1382                 }
1383                 num_edges = get_irn_n_outs(x->node);
1384
1385                 /* for all edges in x.L.def_use_{idx} */
1386                 while (x->next_edge <= num_edges) {
1387                         const ir_def_use_edge *edge = &x->node->out[x->next_edge];
1388                         ir_node               *succ;
1389
1390                         /* check if we have necessary edges */
1391                         if (edge->pos > idx)
1392                                 break;
1393
1394                         ++x->next_edge;
1395
1396                         succ = edge->use;
1397
1398                         /* only non-commutative nodes */
1399                         if (env->commutative &&
1400                             (idx == 0 || idx == 1) && is_op_commutative(get_irn_op(succ)))
1401                                 continue;
1402
1403                         /* ignore the "control input" for non-pinned nodes
1404                         if we are running in GCSE mode */
1405                         if (idx < end_idx && get_irn_pinned(succ) != op_pin_state_pinned)
1406                                 continue;
1407
1408                         y = get_irn_node(succ);
1409                         assert(get_irn_n(succ, idx) == x->node);
1410
1411                         /* ignore block edges touching followers */
1412                         if (idx == -1 && y->is_follower)
1413                                 continue;
1414
1415                         if (is_constant_type(y->type)) {
1416                                 ir_opcode code = get_irn_opcode(succ);
1417                                 if (code == iro_Sub || code == iro_Cmp)
1418                                         add_to_cprop(y, env);
1419                         }
1420
1421                         /* Partitions of constants should not be split simply because their Nodes have unequal
1422                            functions or incongruent inputs. */
1423                         if (type_is_neither_top_nor_const(y->type) &&
1424                                 (! is_Phi(y->node) || is_live_input(y->node, idx))) {
1425                                         add_to_touched(y, env);
1426                         }
1427                 }
1428         }
1429 }  /* collect_touched */
1430
1431 /**
1432  * Collect commutative nodes to the touched list.
1433  *
1434  * @param X     the partition of the list
1435  * @param list  the list which contains the nodes that must be evaluated
1436  * @param env   the environment
1437  */
1438 static void collect_commutative_touched(partition_t *X, list_head *list, environment_t *env) {
1439         int     first      = 1;
1440         int     both_input = 0;
1441         node_t  *x, *y;
1442
1443         list_for_each_entry(node_t, x, list, node_list) {
1444                 int num_edges;
1445
1446                 num_edges = get_irn_n_outs(x->node);
1447
1448                 x->next_edge = x->n_followers + 1;
1449
1450                 /* for all edges in x.L.def_use_{idx} */
1451                 while (x->next_edge <= num_edges) {
1452                         const ir_def_use_edge *edge = &x->node->out[x->next_edge];
1453                         ir_node               *succ;
1454
1455                         /* check if we have necessary edges */
1456                         if (edge->pos > 1)
1457                                 break;
1458
1459                         ++x->next_edge;
1460                         if (edge->pos < 0)
1461                                 continue;
1462
1463                         succ = edge->use;
1464
1465                         /* only commutative nodes */
1466                         if (!is_op_commutative(get_irn_op(succ)))
1467                                 continue;
1468
1469                         y = get_irn_node(succ);
1470                         if (is_constant_type(y->type)) {
1471                                 ir_opcode code = get_irn_opcode(succ);
1472                                 if (code == iro_Eor)
1473                                         add_to_cprop(y, env);
1474                         }
1475
1476                         /* Partitions of constants should not be split simply because their Nodes have unequal
1477                            functions or incongruent inputs. */
1478                         if (type_is_neither_top_nor_const(y->type)) {
1479                                 int    other_idx = edge->pos ^ 1;
1480                                 node_t *other    = get_irn_node(get_irn_n(succ, other_idx));
1481                                 int    equal     = X == other->part;
1482
1483                                 /*
1484                                  * Note: op(a, a) is NOT congruent to op(a, b).
1485                                  * So, either all touch nodes must have both inputs congruent,
1486                                  * or not. We decide this by the first occurred node.
1487                                  */
1488                                 if (first) {
1489                                         first      = 0;
1490                                         both_input = equal;
1491                                 }
1492                                 if (both_input == equal)
1493                                         add_to_touched(y, env);
1494                         }
1495                 }
1496         }
1497 }  /* collect_commutative_touched */
1498
1499 /**
1500  * Split the partitions if caused by the first entry on the worklist.
1501  *
1502  * @param env  the environment
1503  */
1504 static void cause_splits(environment_t *env) {
1505         partition_t *X, *Z, *N;
1506         int         idx;
1507
1508         /* remove the first partition from the worklist */
1509         X = env->worklist;
1510         env->worklist  = X->wl_next;
1511         X->on_worklist = 0;
1512
1513         dump_partition("Cause_split: ", X);
1514
1515         if (env->commutative) {
1516                 /* handle commutative nodes first */
1517
1518                 /* empty the touched set: already done, just clear the list */
1519                 env->touched = NULL;
1520
1521                 collect_commutative_touched(X, &X->Leader, env);
1522                 collect_commutative_touched(X, &X->Follower, env);
1523
1524                 for (Z = env->touched; Z != NULL; Z = N) {
1525                         node_t   *e;
1526                         node_t   *touched  = Z->touched;
1527                         unsigned n_touched = Z->n_touched;
1528
1529                         assert(Z->touched != NULL);
1530
1531                         /* beware, split might change Z */
1532                         N = Z->touched_next;
1533
1534                         /* remove it from the touched set */
1535                         Z->on_touched = 0;
1536
1537                         /* Empty local Z.touched. */
1538                         for (e = touched; e != NULL; e = e->next) {
1539                                 assert(e->is_follower == 0);
1540                                 e->on_touched = 0;
1541                         }
1542                         Z->touched   = NULL;
1543                         Z->n_touched = 0;
1544
1545                         if (0 < n_touched && n_touched < Z->n_leader) {
1546                                 DB((dbg, LEVEL_2, "Split part%d by touched\n", Z->nr));
1547                                 split(&Z, touched, env);
1548                         } else
1549                                 assert(n_touched <= Z->n_leader);
1550                 }
1551         }
1552
1553         /* combine temporary leader and follower list */
1554         for (idx = -1; idx <= X->max_user_inputs; ++idx) {
1555                 /* empty the touched set: already done, just clear the list */
1556                 env->touched = NULL;
1557
1558                 collect_touched(&X->Leader, idx, env);
1559                 collect_touched(&X->Follower, idx, env);
1560
1561                 for (Z = env->touched; Z != NULL; Z = N) {
1562                         node_t   *e;
1563                         node_t   *touched  = Z->touched;
1564                         unsigned n_touched = Z->n_touched;
1565
1566                         assert(Z->touched != NULL);
1567
1568                         /* beware, split might change Z */
1569                         N = Z->touched_next;
1570
1571                         /* remove it from the touched set */
1572                         Z->on_touched = 0;
1573
1574                         /* Empty local Z.touched. */
1575                         for (e = touched; e != NULL; e = e->next) {
1576                                 assert(e->is_follower == 0);
1577                                 e->on_touched = 0;
1578                         }
1579                         Z->touched   = NULL;
1580                         Z->n_touched = 0;
1581
1582                         if (0 < n_touched && n_touched < Z->n_leader) {
1583                                 DB((dbg, LEVEL_2, "Split part%d by touched\n", Z->nr));
1584                                 split(&Z, touched, env);
1585                         } else
1586                                 assert(n_touched <= Z->n_leader);
1587                 }
1588         }
1589 }  /* cause_splits */
1590
1591 /**
1592  * Implements split_by_what(): Split a partition by characteristics given
1593  * by the what function.
1594  *
1595  * @param X     the partition to split
1596  * @param What  a function returning an Id for every node of the partition X
1597  * @param P     a list to store the result partitions
1598  * @param env   the environment
1599  *
1600  * @return *P
1601  */
1602 static partition_t *split_by_what(partition_t *X, what_func What,
1603                                   partition_t **P, environment_t *env) {
1604         node_t          *x, *S;
1605         listmap_t       map;
1606         listmap_entry_t *iter;
1607         partition_t     *R;
1608
1609         /* Let map be an empty mapping from the range of What to (local) list of Nodes. */
1610         listmap_init(&map);
1611         list_for_each_entry(node_t, x, &X->Leader, node_list) {
1612                 void            *id = What(x, env);
1613                 listmap_entry_t *entry;
1614
1615                 if (id == NULL) {
1616                         /* input not allowed, ignore */
1617                         continue;
1618                 }
1619                 /* Add x to map[What(x)]. */
1620                 entry = listmap_find(&map, id);
1621                 x->next     = entry->list;
1622                 entry->list = x;
1623         }
1624         /* Let P be a set of Partitions. */
1625
1626         /* for all sets S except one in the range of map do */
1627         for (iter = map.values; iter != NULL; iter = iter->next) {
1628                 if (iter->next == NULL) {
1629                         /* this is the last entry, ignore */
1630                         break;
1631                 }
1632                 S = iter->list;
1633
1634                 /* Add SPLIT( X, S ) to P. */
1635                 DB((dbg, LEVEL_2, "Split part%d by WHAT = %s\n", X->nr, what_reason));
1636                 R = split(&X, S, env);
1637                 R->split_next = *P;
1638                 *P            = R;
1639         }
1640         /* Add X to P. */
1641         X->split_next = *P;
1642         *P            = X;
1643
1644         listmap_term(&map);
1645         return *P;
1646 }  /* split_by_what */
1647
1648 /** lambda n.(n.type) */
1649 static void *lambda_type(const node_t *node, environment_t *env) {
1650         (void)env;
1651         return node->type.tv;
1652 }  /* lambda_type */
1653
1654 /** lambda n.(n.opcode) */
1655 static void *lambda_opcode(const node_t *node, environment_t *env) {
1656         opcode_key_t key, *entry;
1657         ir_node      *irn = node->node;
1658
1659         key.code   = get_irn_opcode(irn);
1660         key.mode   = get_irn_mode(irn);
1661         key.arity  = get_irn_arity(irn);
1662         key.u.proj = 0;
1663         key.u.ent  = NULL;
1664
1665         switch (get_irn_opcode(irn)) {
1666         case iro_Proj:
1667                 key.u.proj = get_Proj_proj(irn);
1668                 break;
1669         case iro_Sel:
1670                 key.u.ent = get_Sel_entity(irn);
1671                 break;
1672         case iro_Conv:
1673                 key.u.intVal = get_Conv_strict(irn);
1674                 break;
1675         case iro_Div:
1676                 key.u.intVal = is_Div_remainderless(irn);
1677                 break;
1678         case iro_Block:
1679                 /*
1680                  * Some ugliness here: Two Blocks having the same
1681                  * IJmp predecessor would be congruent, which of course is wrong.
1682                  * We fix it by never letting blocks be congruent
1683                  * which cannot be detected by combo either.
1684                  */
1685                 key.u.block = irn;
1686                 break;
1687         case iro_Load:
1688                 key.mode = get_Load_mode(irn);
1689                 break;
1690         case iro_Builtin:
1691                 key.u.intVal = get_Builtin_kind(irn);
1692                 break;
1693         default:
1694                 break;
1695         }
1696
1697         entry = set_insert(env->opcode2id_map, &key, sizeof(key), opcode_hash(&key));
1698         return entry;
1699 }  /* lambda_opcode */
1700
1701 /** lambda n.(n[i].partition) */
1702 static void *lambda_partition(const node_t *node, environment_t *env) {
1703         ir_node *skipped = skip_Proj(node->node);
1704         ir_node *pred;
1705         node_t  *p;
1706         int     i = env->lambda_input;
1707
1708         if (i >= get_irn_arity(node->node)) {
1709                 /*
1710                  * We are outside the allowed range: This can happen even
1711                  * if we have split by opcode first: doing so might move Followers
1712                  * to Leaders and those will have a different opcode!
1713                  * Note that in this case the partition is on the cprop list and will be
1714                  * split again.
1715                  */
1716                 return NULL;
1717         }
1718
1719         /* ignore the "control input" for non-pinned nodes
1720            if we are running in GCSE mode */
1721         if (i < env->end_idx && get_irn_pinned(skipped) != op_pin_state_pinned)
1722                 return NULL;
1723
1724         pred = i == -1 ? get_irn_n(skipped, i) : get_irn_n(node->node, i);
1725         p    = get_irn_node(pred);
1726         return p->part;
1727 }  /* lambda_partition */
1728
1729 /** lambda n.(n[i].partition) for commutative nodes */
1730 static void *lambda_commutative_partition(const node_t *node, environment_t *env) {
1731         ir_node     *irn     = node->node;
1732         ir_node     *skipped = skip_Proj(irn);
1733         ir_node     *pred, *left, *right;
1734         node_t      *p;
1735         partition_t *pl, *pr;
1736         int         i = env->lambda_input;
1737
1738         if (i >= get_irn_arity(node->node)) {
1739                 /*
1740                  * We are outside the allowed range: This can happen even
1741                  * if we have split by opcode first: doing so might move Followers
1742                  * to Leaders and those will have a different opcode!
1743                  * Note that in this case the partition is on the cprop list and will be
1744                  * split again.
1745                  */
1746                 return NULL;
1747         }
1748
1749         /* ignore the "control input" for non-pinned nodes
1750            if we are running in GCSE mode */
1751         if (i < env->end_idx && get_irn_pinned(skipped) != op_pin_state_pinned)
1752                 return NULL;
1753
1754         if (i == -1) {
1755                 pred = get_irn_n(skipped, i);
1756                 p    = get_irn_node(pred);
1757                 return p->part;
1758         }
1759
1760         if (is_op_commutative(get_irn_op(irn))) {
1761                 /* normalize partition order by returning the "smaller" on input 0,
1762                    the "bigger" on input 1. */
1763                 left  = get_binop_left(irn);
1764                 pl    = get_irn_node(left)->part;
1765                 right = get_binop_right(irn);
1766                 pr    = get_irn_node(right)->part;
1767
1768                 if (i == 0)
1769                         return pl < pr ? pl : pr;
1770                 else
1771                 return pl > pr ? pl : pr;
1772         } else {
1773                 /* a not split out Follower */
1774                 pred = get_irn_n(irn, i);
1775                 p    = get_irn_node(pred);
1776
1777                 return p->part;
1778         }
1779 }  /* lambda_commutative_partition */
1780
1781 /**
1782  * Returns true if a type is a constant (and NOT Top
1783  * or Bottom).
1784  */
1785 static int is_con(const lattice_elem_t type) {
1786         /* be conservative */
1787         if (is_tarval(type.tv))
1788                 return tarval_is_constant(type.tv);
1789         return is_entity(type.sym.entity_p);
1790 }  /* is_con */
1791
1792 /**
1793  * Implements split_by().
1794  *
1795  * @param X    the partition to split
1796  * @param env  the environment
1797  */
1798 static void split_by(partition_t *X, environment_t *env) {
1799         partition_t *I, *P = NULL;
1800         int         input;
1801
1802         dump_partition("split_by", X);
1803
1804         if (X->n_leader == 1) {
1805                 /* we have only one leader, no need to split, just check it's type */
1806                 node_t *x = get_first_node(X);
1807                 X->type_is_T_or_C = x->type.tv == tarval_top || is_con(x->type);
1808                 return;
1809         }
1810
1811         DEBUG_ONLY(what_reason = "lambda n.(n.type)";)
1812         P = split_by_what(X, lambda_type, &P, env);
1813         dump_split_list(P);
1814
1815         /* adjust the type tags, we have split partitions by type */
1816         for (I = P; I != NULL; I = I->split_next) {
1817                 node_t *x = get_first_node(I);
1818                 I->type_is_T_or_C = x->type.tv == tarval_top || is_con(x->type);
1819         }
1820
1821         do {
1822                 partition_t *Y = P;
1823
1824                 P = P->split_next;
1825                 if (Y->n_leader > 1) {
1826                         /* we do not want split the TOP or constant partitions */
1827                         if (! Y->type_is_T_or_C) {
1828                                 partition_t *Q = NULL;
1829
1830                                 DEBUG_ONLY(what_reason = "lambda n.(n.opcode)";)
1831                                 Q = split_by_what(Y, lambda_opcode, &Q, env);
1832                                 dump_split_list(Q);
1833
1834                                 do {
1835                                         partition_t *Z = Q;
1836
1837                                         Q = Q->split_next;
1838                                         if (Z->n_leader > 1) {
1839                                                 const node_t *first = get_first_node(Z);
1840                                                 int          arity  = get_irn_arity(first->node);
1841                                                 partition_t  *R, *S;
1842                                                 what_func    what = lambda_partition;
1843                                                 DEBUG_ONLY(char buf[64];)
1844
1845                                                 if (env->commutative && is_op_commutative(get_irn_op(first->node)))
1846                                                         what = lambda_commutative_partition;
1847
1848                                                 /*
1849                                                  * BEWARE: during splitting by input 2 for instance we might
1850                                                  * create new partitions which are different by input 1, so collect
1851                                                  * them and split further.
1852                                                  */
1853                                                 Z->split_next = NULL;
1854                                                 R             = Z;
1855                                                 S             = NULL;
1856                                                 for (input = arity - 1; input >= -1; --input) {
1857                                                         do {
1858                                                                 partition_t *Z_prime = R;
1859
1860                                                                 R = R->split_next;
1861                                                                 if (Z_prime->n_leader > 1) {
1862                                                                         env->lambda_input = input;
1863                                                                         DEBUG_ONLY(snprintf(buf, sizeof(buf), "lambda n.(n[%d].partition)", input);)
1864                                                                         DEBUG_ONLY(what_reason = buf;)
1865                                                                         S = split_by_what(Z_prime, what, &S, env);
1866                                                                         dump_split_list(S);
1867                                                                 } else {
1868                                                                         Z_prime->split_next = S;
1869                                                                         S                   = Z_prime;
1870                                                                 }
1871                                                         } while (R != NULL);
1872                                                         R = S;
1873                                                         S = NULL;
1874                                                 }
1875                                         }
1876                                 } while (Q != NULL);
1877                         }
1878                 }
1879         } while (P != NULL);
1880 }  /* split_by */
1881
1882 /**
1883  * (Re-)compute the type for a given node.
1884  *
1885  * @param node  the node
1886  */
1887 static void default_compute(node_t *node) {
1888         int     i;
1889         ir_node *irn = node->node;
1890
1891         /* if any of the data inputs have type top, the result is type top */
1892         for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
1893                 ir_node *pred = get_irn_n(irn, i);
1894                 node_t  *p    = get_irn_node(pred);
1895
1896                 if (p->type.tv == tarval_top) {
1897                         node->type.tv = tarval_top;
1898                         return;
1899                 }
1900         }
1901
1902         if (get_irn_mode(node->node) == mode_X)
1903                 node->type.tv = tarval_reachable;
1904         else
1905                 node->type.tv = computed_value(irn);
1906 }  /* default_compute */
1907
1908 /**
1909  * (Re-)compute the type for a Block node.
1910  *
1911  * @param node  the node
1912  */
1913 static void compute_Block(node_t *node) {
1914         int     i;
1915         ir_node *block = node->node;
1916
1917         if (block == get_irg_start_block(current_ir_graph) || has_Block_label(block)) {
1918                 /* start block and labelled blocks are always reachable */
1919                 node->type.tv = tarval_reachable;
1920                 return;
1921         }
1922
1923         for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
1924                 node_t *pred = get_irn_node(get_Block_cfgpred(block, i));
1925
1926                 if (pred->type.tv == tarval_reachable) {
1927                         /* A block is reachable, if at least of predecessor is reachable. */
1928                         node->type.tv = tarval_reachable;
1929                         return;
1930                 }
1931         }
1932         node->type.tv = tarval_top;
1933 }  /* compute_Block */
1934
1935 /**
1936  * (Re-)compute the type for a Bad node.
1937  *
1938  * @param node  the node
1939  */
1940 static void compute_Bad(node_t *node) {
1941         /* Bad nodes ALWAYS compute Top */
1942         node->type.tv = tarval_top;
1943 }  /* compute_Bad */
1944
1945 /**
1946  * (Re-)compute the type for an Unknown node.
1947  *
1948  * @param node  the node
1949  */
1950 static void compute_Unknown(node_t *node) {
1951         /* While Unknown nodes should compute Top this is dangerous:
1952          * a Top input to a Cond would lead to BOTH control flows unreachable.
1953          * While this is correct in the given semantics, it would destroy the Firm
1954          * graph.
1955          *
1956          * It would be safe to compute Top IF it can be assured, that only Cmp
1957          * nodes are inputs to Conds. We check that first.
1958          * This is the way Frontends typically build Firm, but some optimizations
1959          * (cond_eval for instance) might replace them by Phib's...
1960          */
1961         node->type.tv = tarval_UNKNOWN;
1962 }  /* compute_Unknown */
1963
1964 /**
1965  * (Re-)compute the type for a Jmp node.
1966  *
1967  * @param node  the node
1968  */
1969 static void compute_Jmp(node_t *node) {
1970         node_t *block = get_irn_node(get_nodes_block(node->node));
1971
1972         node->type = block->type;
1973 }  /* compute_Jmp */
1974
1975 /**
1976  * (Re-)compute the type for the Return node.
1977  *
1978  * @param node  the node
1979  */
1980 static void compute_Return(node_t *node) {
1981         /* The Return node is NOT dead if it is in a reachable block.
1982          * This is already checked in compute(). so we can return
1983          * Reachable here. */
1984         node->type.tv = tarval_reachable;
1985 }  /* compute_Return */
1986
1987 /**
1988  * (Re-)compute the type for the End node.
1989  *
1990  * @param node  the node
1991  */
1992 static void compute_End(node_t *node) {
1993         /* the End node is NOT dead of course */
1994         node->type.tv = tarval_reachable;
1995 }  /* compute_End */
1996
1997 /**
1998  * (Re-)compute the type for a Call.
1999  *
2000  * @param node  the node
2001  */
2002 static void compute_Call(node_t *node) {
2003         /*
2004          * A Call computes always bottom, even if it has Unknown
2005          * predecessors.
2006          */
2007         node->type.tv = tarval_bottom;
2008 }  /* compute_Call */
2009
2010 /**
2011  * (Re-)compute the type for a SymConst node.
2012  *
2013  * @param node  the node
2014  */
2015 static void compute_SymConst(node_t *node) {
2016         ir_node *irn = node->node;
2017         node_t  *block = get_irn_node(get_nodes_block(irn));
2018
2019         if (block->type.tv == tarval_unreachable) {
2020                 node->type.tv = tarval_top;
2021                 return;
2022         }
2023         switch (get_SymConst_kind(irn)) {
2024         case symconst_addr_ent:
2025         /* case symconst_addr_name: cannot handle this yet */
2026                 node->type.sym = get_SymConst_symbol(irn);
2027                 break;
2028         default:
2029                 node->type.tv = computed_value(irn);
2030         }
2031 }  /* compute_SymConst */
2032
2033 /**
2034  * (Re-)compute the type for a Phi node.
2035  *
2036  * @param node  the node
2037  */
2038 static void compute_Phi(node_t *node) {
2039         int            i;
2040         ir_node        *phi = node->node;
2041         lattice_elem_t type;
2042
2043         /* if a Phi is in a unreachable block, its type is TOP */
2044         node_t *block = get_irn_node(get_nodes_block(phi));
2045
2046         if (block->type.tv == tarval_unreachable) {
2047                 node->type.tv = tarval_top;
2048                 return;
2049         }
2050
2051         /* Phi implements the Meet operation */
2052         type.tv = tarval_top;
2053         for (i = get_Phi_n_preds(phi) - 1; i >= 0; --i) {
2054                 node_t *pred   = get_irn_node(get_Phi_pred(phi, i));
2055                 node_t *pred_X = get_irn_node(get_Block_cfgpred(block->node, i));
2056
2057                 if (pred_X->type.tv == tarval_unreachable || pred->type.tv == tarval_top) {
2058                         /* ignore TOP inputs: We must check here for unreachable blocks,
2059                            because Firm constants live in the Start Block are NEVER Top.
2060                            Else, a Phi (1,2) will produce Bottom, even if the 2 for instance
2061                            comes from a unreachable input. */
2062                         continue;
2063                 }
2064                 if (pred->type.tv == tarval_bottom) {
2065                         node->type.tv = tarval_bottom;
2066                         return;
2067                 } else if (type.tv == tarval_top) {
2068                         /* first constant found */
2069                         type = pred->type;
2070                 } else if (type.tv != pred->type.tv) {
2071                         /* different constants or tarval_bottom */
2072                         node->type.tv = tarval_bottom;
2073                         return;
2074                 }
2075                 /* else nothing, constants are the same */
2076         }
2077         node->type = type;
2078 }  /* compute_Phi */
2079
2080 /**
2081  * (Re-)compute the type for an Add. Special case: one nodes is a Zero Const.
2082  *
2083  * @param node  the node
2084  */
2085 static void compute_Add(node_t *node) {
2086         ir_node        *sub = node->node;
2087         node_t         *l   = get_irn_node(get_Add_left(sub));
2088         node_t         *r   = get_irn_node(get_Add_right(sub));
2089         lattice_elem_t a    = l->type;
2090         lattice_elem_t b    = r->type;
2091         ir_mode        *mode;
2092
2093         if (a.tv == tarval_top || b.tv == tarval_top) {
2094                 node->type.tv = tarval_top;
2095         } else if (a.tv == tarval_bottom || b.tv == tarval_bottom) {
2096                 node->type.tv = tarval_bottom;
2097         } else {
2098                 /* x + 0 = 0 + x = x, but beware of floating point +0 + -0, so we
2099                    must call tarval_add() first to handle this case! */
2100                 if (is_tarval(a.tv)) {
2101                         if (is_tarval(b.tv)) {
2102                                 node->type.tv = tarval_add(a.tv, b.tv);
2103                                 return;
2104                         }
2105                         mode = get_tarval_mode(a.tv);
2106                         if (a.tv == get_mode_null(mode)) {
2107                                 node->type = b;
2108                                 return;
2109                         }
2110                 } else if (is_tarval(b.tv)) {
2111                         mode = get_tarval_mode(b.tv);
2112                         if (b.tv == get_mode_null(mode)) {
2113                                 node->type = a;
2114                                 return;
2115                         }
2116                 }
2117                 node->type.tv = tarval_bottom;
2118         }
2119 }  /* compute_Add */
2120
2121 /**
2122  * (Re-)compute the type for a Sub. Special case: both nodes are congruent.
2123  *
2124  * @param node  the node
2125  */
2126 static void compute_Sub(node_t *node) {
2127         ir_node        *sub = node->node;
2128         node_t         *l   = get_irn_node(get_Sub_left(sub));
2129         node_t         *r   = get_irn_node(get_Sub_right(sub));
2130         lattice_elem_t a    = l->type;
2131         lattice_elem_t b    = r->type;
2132         tarval         *tv;
2133
2134         if (a.tv == tarval_top || b.tv == tarval_top) {
2135                 node->type.tv = tarval_top;
2136         } else if (is_con(a) && is_con(b)) {
2137                 if (is_tarval(a.tv) && is_tarval(b.tv)) {
2138                         node->type.tv = tarval_sub(a.tv, b.tv, get_irn_mode(sub));
2139                 } else if (is_tarval(a.tv) && tarval_is_null(a.tv)) {
2140                         node->type = b;
2141                 } else if (is_tarval(b.tv) && tarval_is_null(b.tv)) {
2142                         node->type = a;
2143                 } else {
2144                         node->type.tv = tarval_bottom;
2145                 }
2146         } else if (r->part == l->part &&
2147                    (!mode_is_float(get_irn_mode(l->node)))) {
2148                 /*
2149                  * BEWARE: a - a is NOT always 0 for floating Point values, as
2150                  * NaN op NaN = NaN, so we must check this here.
2151                  */
2152                 ir_mode *mode = get_irn_mode(sub);
2153                 tv = get_mode_null(mode);
2154
2155                 /* if the node was ONCE evaluated by all constants, but now
2156                    this breaks AND we get from the argument partitions a different
2157                    result, switch to bottom.
2158                    This happens because initially all nodes are in the same partition ... */
2159                 if (node->type.tv != tv)
2160                         tv = tarval_bottom;
2161                 node->type.tv = tv;
2162         } else {
2163                 node->type.tv = tarval_bottom;
2164         }
2165 }  /* compute_Sub */
2166
2167 /**
2168  * (Re-)compute the type for an Eor. Special case: both nodes are congruent.
2169  *
2170  * @param node  the node
2171  */
2172 static void compute_Eor(node_t *node) {
2173         ir_node        *eor = node->node;
2174         node_t         *l   = get_irn_node(get_Eor_left(eor));
2175         node_t         *r   = get_irn_node(get_Eor_right(eor));
2176         lattice_elem_t a    = l->type;
2177         lattice_elem_t b    = r->type;
2178         tarval         *tv;
2179
2180         if (a.tv == tarval_top || b.tv == tarval_top) {
2181                 node->type.tv = tarval_top;
2182         } else if (is_con(a) && is_con(b)) {
2183                 if (is_tarval(a.tv) && is_tarval(b.tv)) {
2184                         node->type.tv = tarval_eor(a.tv, b.tv);
2185                 } else if (is_tarval(a.tv) && tarval_is_null(a.tv)) {
2186                         node->type = b;
2187                 } else if (is_tarval(b.tv) && tarval_is_null(b.tv)) {
2188                         node->type = a;
2189                 } else {
2190                         node->type.tv = tarval_bottom;
2191                 }
2192         } else if (r->part == l->part) {
2193                 ir_mode *mode = get_irn_mode(eor);
2194                 tv = get_mode_null(mode);
2195
2196                 /* if the node was ONCE evaluated by all constants, but now
2197                    this breaks AND we get from the argument partitions a different
2198                    result, switch to bottom.
2199                    This happens because initially all nodes are in the same partition ... */
2200                 if (node->type.tv != tv)
2201                         tv = tarval_bottom;
2202                 node->type.tv = tv;
2203         } else {
2204                 node->type.tv = tarval_bottom;
2205         }
2206 }  /* compute_Eor */
2207
2208 /**
2209  * (Re-)compute the type for Cmp.
2210  *
2211  * @param node  the node
2212  */
2213 static void compute_Cmp(node_t *node) {
2214         ir_node        *cmp  = node->node;
2215         node_t         *l    = get_irn_node(get_Cmp_left(cmp));
2216         node_t         *r    = get_irn_node(get_Cmp_right(cmp));
2217         lattice_elem_t a     = l->type;
2218         lattice_elem_t b     = r->type;
2219
2220         if (a.tv == tarval_top || b.tv == tarval_top) {
2221                 node->type.tv = tarval_top;
2222         } else if (r->part == l->part) {
2223                 /* both nodes congruent, we can probably do something */
2224                 node->type.tv = tarval_b_true;
2225         } else if (is_con(a) && is_con(b)) {
2226                 /* both nodes are constants, we can probably do something */
2227                 node->type.tv = tarval_b_true;
2228         } else {
2229                 node->type.tv = tarval_bottom;
2230         }
2231 }  /* compute_Cmp */
2232
2233 /**
2234  * (Re-)compute the type for a Proj(Cmp).
2235  *
2236  * @param node  the node
2237  * @param cond  the predecessor Cmp node
2238  */
2239 static void compute_Proj_Cmp(node_t *node, ir_node *cmp) {
2240         ir_node        *proj = node->node;
2241         node_t         *l    = get_irn_node(get_Cmp_left(cmp));
2242         node_t         *r    = get_irn_node(get_Cmp_right(cmp));
2243         lattice_elem_t a     = l->type;
2244         lattice_elem_t b     = r->type;
2245         pn_Cmp         pnc   = get_Proj_proj(proj);
2246         tarval         *tv;
2247
2248         if (a.tv == tarval_top || b.tv == tarval_top) {
2249                 node->type.tv = tarval_undefined;
2250         } else if (is_con(a) && is_con(b)) {
2251                 default_compute(node);
2252         } else if (r->part == l->part &&
2253                    (!mode_is_float(get_irn_mode(l->node)) || pnc == pn_Cmp_Lt || pnc == pn_Cmp_Gt)) {
2254                 /*
2255                  * BEWARE: a == a is NOT always True for floating Point values, as
2256                  * NaN != NaN is defined, so we must check this here.
2257                  */
2258                 tv = pnc & pn_Cmp_Eq ? tarval_b_true: tarval_b_false;
2259
2260                 /* if the node was ONCE evaluated by all constants, but now
2261                    this breaks AND we get from the argument partitions a different
2262                    result, switch to bottom.
2263                    This happens because initially all nodes are in the same partition ... */
2264                 if (node->type.tv != tv)
2265                         tv = tarval_bottom;
2266                 node->type.tv = tv;
2267         } else {
2268                 node->type.tv = tarval_bottom;
2269         }
2270 }  /* compute_Proj_Cmp */
2271
2272 /**
2273  * (Re-)compute the type for a Proj(Cond).
2274  *
2275  * @param node  the node
2276  * @param cond  the predecessor Cond node
2277  */
2278 static void compute_Proj_Cond(node_t *node, ir_node *cond) {
2279         ir_node *proj     = node->node;
2280         long    pnc       = get_Proj_proj(proj);
2281         ir_node *sel      = get_Cond_selector(cond);
2282         node_t  *selector = get_irn_node(sel);
2283
2284         /*
2285          * Note: it is crucial for the monotony that the Proj(Cond)
2286          * are evaluates after all predecessors of the Cond selector are
2287          * processed.
2288          * Example
2289          *
2290          * if (x != 0)
2291          *
2292          * Due to the fact that 0 is a const, the Cmp gets immediately
2293          * on the cprop list. It will be evaluated before x is evaluated,
2294          * might leaving x as Top. When later x is evaluated, the Cmp
2295          * might change its value.
2296          * BUT if the Cond is evaluated before this happens, Proj(Cond, FALSE)
2297          * gets R, and later changed to F if Cmp is evaluated to True!
2298          *
2299          * We prevent this by putting Conds in an extra cprop_X queue, which
2300          * gets evaluated after the cprop queue is empty.
2301          *
2302          * Note that this even happens with Click's original algorithm, if
2303          * Cmp(x, 0) is evaluated to True first and later changed to False
2304          * if x was Top first and later changed to a Const ...
2305          * It is unclear how Click solved that problem ...
2306          *
2307          * However, in rare cases even this does not help, if a Top reaches
2308          * a compare  through a Phi, than Proj(Cond) is evaluated changing
2309          * the type of the Phi to something other.
2310          * So, we take the last resort and bind the type to R once
2311          * it is calculated.
2312          *
2313          * (This might be even the way Click works around the whole problem).
2314          *
2315          * Finally, we may miss some optimization possibilities due to this:
2316          *
2317          * x = phi(Top, y)
2318          * if (x == 0)
2319          *
2320          * If Top reaches the if first, than we decide for != here.
2321          * If y later is evaluated to 0, we cannot revert this decision
2322          * and must live with both outputs enabled. If this happens,
2323          * we get an unresolved if (true) in the code ...
2324          *
2325          * In Click's version where this decision is done at the Cmp,
2326          * the Cmp is NOT optimized away than (if y evaluated to 1
2327          * for instance) and we get a if (1 == 0) here ...
2328          *
2329          * Both solutions are suboptimal.
2330          * At least, we could easily detect this problem and run
2331          * cf_opt() (or even combo) again :-(
2332          */
2333         if (node->type.tv == tarval_reachable)
2334                 return;
2335
2336         if (get_irn_mode(sel) == mode_b) {
2337                 /* an IF */
2338                 if (pnc == pn_Cond_true) {
2339                         if (selector->type.tv == tarval_b_false) {
2340                                 node->type.tv = tarval_unreachable;
2341                         } else if (selector->type.tv == tarval_b_true) {
2342                                 node->type.tv = tarval_reachable;
2343                         } else if (selector->type.tv == tarval_bottom) {
2344                                 node->type.tv = tarval_reachable;
2345                         } else {
2346                                 assert(selector->type.tv == tarval_top);
2347                                 if (tarval_UNKNOWN == tarval_top) {
2348                                         /* any condition based on Top is "!=" */
2349                                         node->type.tv = tarval_unreachable;
2350                                 } else {
2351                                         node->type.tv = tarval_unreachable;
2352                                 }
2353                         }
2354                 } else {
2355                         assert(pnc == pn_Cond_false);
2356
2357                         if (selector->type.tv == tarval_b_false) {
2358                                 node->type.tv = tarval_reachable;
2359                         } else if (selector->type.tv == tarval_b_true) {
2360                                 node->type.tv = tarval_unreachable;
2361                         } else if (selector->type.tv == tarval_bottom) {
2362                                 node->type.tv = tarval_reachable;
2363                         } else {
2364                                 assert(selector->type.tv == tarval_top);
2365                                 if (tarval_UNKNOWN == tarval_top) {
2366                                         /* any condition based on Top is "!=" */
2367                                         node->type.tv = tarval_reachable;
2368                                 } else {
2369                                         node->type.tv = tarval_unreachable;
2370                                 }
2371                         }
2372                 }
2373         } else {
2374                 /* an SWITCH */
2375                 if (selector->type.tv == tarval_bottom) {
2376                         node->type.tv = tarval_reachable;
2377                 } else if (selector->type.tv == tarval_top) {
2378                         if (tarval_UNKNOWN == tarval_top &&
2379                             pnc == get_Cond_defaultProj(cond)) {
2380                                 /* a switch based of Top is always "default" */
2381                                 node->type.tv = tarval_reachable;
2382                         } else {
2383                                 node->type.tv = tarval_unreachable;
2384                         }
2385                 } else {
2386                         long value = get_tarval_long(selector->type.tv);
2387                         if (pnc == get_Cond_defaultProj(cond)) {
2388                                 /* default switch, have to check ALL other cases */
2389                                 int i;
2390
2391                                 for (i = get_irn_n_outs(cond) - 1; i >= 0; --i) {
2392                                         ir_node *succ = get_irn_out(cond, i);
2393
2394                                         if (succ == proj)
2395                                                 continue;
2396                                         if (value == get_Proj_proj(succ)) {
2397                                                 /* we found a match, will NOT take the default case */
2398                                                 node->type.tv = tarval_unreachable;
2399                                                 return;
2400                                         }
2401                                 }
2402                                 /* all cases checked, no match, will take default case */
2403                                 node->type.tv = tarval_reachable;
2404                         } else {
2405                                 /* normal case */
2406                                 node->type.tv = value == pnc ? tarval_reachable : tarval_unreachable;
2407                         }
2408                 }
2409         }
2410 }  /* compute_Proj_Cond */
2411
2412 /**
2413  * (Re-)compute the type for a Proj-Node.
2414  *
2415  * @param node  the node
2416  */
2417 static void compute_Proj(node_t *node) {
2418         ir_node *proj = node->node;
2419         ir_mode *mode = get_irn_mode(proj);
2420         node_t  *block = get_irn_node(get_nodes_block(skip_Proj(proj)));
2421         ir_node *pred  = get_Proj_pred(proj);
2422
2423         if (block->type.tv == tarval_unreachable) {
2424                 /* a Proj in a unreachable Block stay Top */
2425                 node->type.tv = tarval_top;
2426                 return;
2427         }
2428         if (get_irn_node(pred)->type.tv == tarval_top && !is_Cond(pred)) {
2429                 /* if the predecessor is Top, its Proj follow */
2430                 node->type.tv = tarval_top;
2431                 return;
2432         }
2433
2434         if (mode == mode_M) {
2435                 /* mode M is always bottom */
2436                 node->type.tv = tarval_bottom;
2437                 return;
2438         }
2439         if (mode != mode_X) {
2440                 if (is_Cmp(pred))
2441                         compute_Proj_Cmp(node, pred);
2442                 else
2443                         default_compute(node);
2444                 return;
2445         }
2446         /* handle mode_X nodes */
2447
2448         switch (get_irn_opcode(pred)) {
2449         case iro_Start:
2450                 /* the Proj_X from the Start is always reachable.
2451                    However this is already handled at the top. */
2452                 node->type.tv = tarval_reachable;
2453                 break;
2454         case iro_Cond:
2455                 compute_Proj_Cond(node, pred);
2456                 break;
2457         default:
2458                 default_compute(node);
2459         }
2460 }  /* compute_Proj */
2461
2462 /**
2463  * (Re-)compute the type for a Confirm.
2464  *
2465  * @param node  the node
2466  */
2467 static void compute_Confirm(node_t *node) {
2468         ir_node *confirm = node->node;
2469         node_t  *pred = get_irn_node(get_Confirm_value(confirm));
2470
2471         if (get_Confirm_cmp(confirm) == pn_Cmp_Eq) {
2472                 node_t *bound = get_irn_node(get_Confirm_bound(confirm));
2473
2474                 if (is_con(bound->type)) {
2475                         /* is equal to a constant */
2476                         node->type = bound->type;
2477                         return;
2478                 }
2479         }
2480         /* a Confirm is a copy OR a Const */
2481         node->type = pred->type;
2482 }  /* compute_Confirm */
2483
2484 /**
2485  * (Re-)compute the type for a given node.
2486  *
2487  * @param node  the node
2488  */
2489 static void compute(node_t *node) {
2490         ir_node *irn = node->node;
2491         compute_func func;
2492
2493 #ifndef VERIFY_MONOTONE
2494         /*
2495          * Once a node reaches bottom, the type cannot fall further
2496          * in the lattice and we can stop computation.
2497          * Do not take this exit if the monotony verifier is
2498          * enabled to catch errors.
2499          */
2500         if (node->type.tv == tarval_bottom)
2501                 return;
2502 #endif
2503
2504         if (is_no_Block(irn)) {
2505                 /* for pinned nodes, check its control input */
2506                 if (get_irn_pinned(skip_Proj(irn)) == op_pin_state_pinned) {
2507                         node_t *block = get_irn_node(get_nodes_block(irn));
2508
2509                         if (block->type.tv == tarval_unreachable) {
2510                                 node->type.tv = tarval_top;
2511                                 return;
2512                         }
2513                 }
2514         }
2515
2516         func = (compute_func)node->node->op->ops.generic;
2517         if (func != NULL)
2518                 func(node);
2519 }  /* compute */
2520
2521 /*
2522  * Identity functions: Note that one might thing that identity() is just a
2523  * synonym for equivalent_node(). While this is true, we cannot use it for the algorithm
2524  * here, because it expects that the identity node is one of the inputs, which is NOT
2525  * always true for equivalent_node() which can handle (and does sometimes) DAGs.
2526  * So, we have our own implementation, which copies some parts of equivalent_node()
2527  */
2528
2529 /**
2530  * Calculates the Identity for Phi nodes
2531  */
2532 static node_t *identity_Phi(node_t *node) {
2533         ir_node *phi    = node->node;
2534         ir_node *block  = get_nodes_block(phi);
2535         node_t  *n_part = NULL;
2536         int     i;
2537
2538         for (i = get_Phi_n_preds(phi) - 1; i >= 0; --i) {
2539                 node_t *pred_X = get_irn_node(get_Block_cfgpred(block, i));
2540
2541                 if (pred_X->type.tv == tarval_reachable) {
2542                         node_t *pred = get_irn_node(get_Phi_pred(phi, i));
2543
2544                         if (n_part == NULL)
2545                                 n_part = pred;
2546                         else if (n_part->part != pred->part) {
2547                                 /* incongruent inputs, not a follower */
2548                                 return node;
2549                         }
2550                 }
2551         }
2552         /* if n_part is NULL here, all inputs path are dead, the Phi computes
2553          * tarval_top, is in the TOP partition and should NOT being split! */
2554         assert(n_part != NULL);
2555         return n_part;
2556 }  /* identity_Phi */
2557
2558 /**
2559  * Calculates the Identity for commutative 0 neutral nodes.
2560  */
2561 static node_t *identity_comm_zero_binop(node_t *node) {
2562         ir_node *op   = node->node;
2563         node_t  *a    = get_irn_node(get_binop_left(op));
2564         node_t  *b    = get_irn_node(get_binop_right(op));
2565         ir_mode *mode = get_irn_mode(op);
2566         tarval  *zero;
2567
2568         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2569         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
2570                 return node;
2571
2572         /* node: no input should be tarval_top, else the binop would be also
2573          * Top and not being split. */
2574         zero = get_mode_null(mode);
2575         if (a->type.tv == zero)
2576                 return b;
2577         if (b->type.tv == zero)
2578                 return a;
2579         return node;
2580 }  /* identity_comm_zero_binop */
2581
2582 /**
2583  * Calculates the Identity for Shift nodes.
2584  */
2585 static node_t *identity_shift(node_t *node) {
2586         ir_node *op   = node->node;
2587         node_t  *b    = get_irn_node(get_binop_right(op));
2588         ir_mode *mode = get_irn_mode(b->node);
2589         tarval  *zero;
2590
2591         /* node: no input should be tarval_top, else the binop would be also
2592          * Top and not being split. */
2593         zero = get_mode_null(mode);
2594         if (b->type.tv == zero)
2595                 return get_irn_node(get_binop_left(op));
2596         return node;
2597 }  /* identity_shift */
2598
2599 /**
2600  * Calculates the Identity for Mul nodes.
2601  */
2602 static node_t *identity_Mul(node_t *node) {
2603         ir_node *op   = node->node;
2604         node_t  *a    = get_irn_node(get_Mul_left(op));
2605         node_t  *b    = get_irn_node(get_Mul_right(op));
2606         ir_mode *mode = get_irn_mode(op);
2607         tarval  *one;
2608
2609         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2610         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
2611                 return node;
2612
2613         /* node: no input should be tarval_top, else the binop would be also
2614          * Top and not being split. */
2615         one = get_mode_one(mode);
2616         if (a->type.tv == one)
2617                 return b;
2618         if (b->type.tv == one)
2619                 return a;
2620         return node;
2621 }  /* identity_Mul */
2622
2623 /**
2624  * Calculates the Identity for Sub nodes.
2625  */
2626 static node_t *identity_Sub(node_t *node) {
2627         ir_node *sub  = node->node;
2628         node_t  *b    = get_irn_node(get_Sub_right(sub));
2629         ir_mode *mode = get_irn_mode(sub);
2630
2631         /* for FP these optimizations are only allowed if fp_strict_algebraic is disabled */
2632         if (mode_is_float(mode) && (get_irg_fp_model(current_ir_graph) & fp_strict_algebraic))
2633                 return node;
2634
2635         /* node: no input should be tarval_top, else the binop would be also
2636          * Top and not being split. */
2637         if (b->type.tv == get_mode_null(mode))
2638                 return get_irn_node(get_Sub_left(sub));
2639         return node;
2640 }  /* identity_Sub */
2641
2642 /**
2643  * Calculates the Identity for And nodes.
2644  */
2645 static node_t *identity_And(node_t *node) {
2646         ir_node *and = node->node;
2647         node_t  *a   = get_irn_node(get_And_left(and));
2648         node_t  *b   = get_irn_node(get_And_right(and));
2649         tarval  *neutral = get_mode_all_one(get_irn_mode(and));
2650
2651         /* node: no input should be tarval_top, else the And would be also
2652          * Top and not being split. */
2653         if (a->type.tv == neutral)
2654                 return b;
2655         if (b->type.tv == neutral)
2656                 return a;
2657         return node;
2658 }  /* identity_And */
2659
2660 /**
2661  * Calculates the Identity for Confirm nodes.
2662  */
2663 static node_t *identity_Confirm(node_t *node) {
2664         ir_node *confirm = node->node;
2665
2666         /* a Confirm is always a Copy */
2667         return get_irn_node(get_Confirm_value(confirm));
2668 }  /* identity_Confirm */
2669
2670 /**
2671  * Calculates the Identity for Mux nodes.
2672  */
2673 static node_t *identity_Mux(node_t *node) {
2674         ir_node *mux = node->node;
2675         node_t  *t   = get_irn_node(get_Mux_true(mux));
2676         node_t  *f   = get_irn_node(get_Mux_false(mux));
2677         /*node_t  *sel; */
2678
2679         if (t->part == f->part)
2680                 return t;
2681
2682         /* for now, the 1-input identity is not supported */
2683 #if 0
2684         sel = get_irn_node(get_Mux_sel(mux));
2685
2686         /* Mux sel input is mode_b, so it is always a tarval */
2687         if (sel->type.tv == tarval_b_true)
2688                 return t;
2689         if (sel->type.tv == tarval_b_false)
2690                 return f;
2691 #endif
2692         return node;
2693 }  /* identity_Mux */
2694
2695 /**
2696  * Calculates the Identity for nodes.
2697  */
2698 static node_t *identity(node_t *node) {
2699         ir_node *irn = node->node;
2700
2701         switch (get_irn_opcode(irn)) {
2702         case iro_Phi:
2703                 return identity_Phi(node);
2704         case iro_Mul:
2705                 return identity_Mul(node);
2706         case iro_Add:
2707         case iro_Or:
2708         case iro_Eor:
2709                 return identity_comm_zero_binop(node);
2710         case iro_Shr:
2711         case iro_Shl:
2712         case iro_Shrs:
2713         case iro_Rotl:
2714                 return identity_shift(node);
2715         case iro_And:
2716                 return identity_And(node);
2717         case iro_Sub:
2718                 return identity_Sub(node);
2719         case iro_Confirm:
2720                 return identity_Confirm(node);
2721         case iro_Mux:
2722                 return identity_Mux(node);
2723         default:
2724                 return node;
2725         }
2726 }  /* identity */
2727
2728 /**
2729  * Node follower is a (new) follower of leader, segregate Leader
2730  * out edges.
2731  */
2732 static void segregate_def_use_chain_1(const ir_node *follower, node_t *leader) {
2733         ir_node *l   = leader->node;
2734         int     j, i, n = get_irn_n_outs(l);
2735
2736         DB((dbg, LEVEL_2, "%+F is a follower of %+F\n", follower, leader->node));
2737         /* The leader edges must remain sorted, but follower edges can
2738            be unsorted. */
2739         for (i = leader->n_followers + 1; i <= n; ++i) {
2740                 if (l->out[i].use == follower) {
2741                         ir_def_use_edge t = l->out[i];
2742
2743                         for (j = i - 1; j >= leader->n_followers + 1; --j)
2744                                 l->out[j + 1] = l->out[j];
2745                         ++leader->n_followers;
2746                         l->out[leader->n_followers] = t;
2747                         break;
2748                 }
2749         }
2750 }  /* segregate_def_use_chain_1 */
2751
2752 /**
2753  * Node follower is a (new) follower segregate its Leader
2754  * out edges.
2755  *
2756  * @param follower  the follower IR node
2757  */
2758 static void segregate_def_use_chain(const ir_node *follower) {
2759         int i;
2760
2761         for (i = get_irn_arity(follower) - 1; i >= 0; --i) {
2762                 node_t *pred = get_irn_node(get_irn_n(follower, i));
2763
2764                 segregate_def_use_chain_1(follower, pred);
2765         }
2766 }  /* segregate_def_use_chain */
2767
2768 /**
2769  * Propagate constant evaluation.
2770  *
2771  * @param env  the environment
2772  */
2773 static void propagate(environment_t *env) {
2774         partition_t    *X, *Y;
2775         node_t         *x;
2776         lattice_elem_t old_type;
2777         node_t         *fallen;
2778         unsigned       n_fallen, old_type_was_T_or_C;
2779         int            i;
2780
2781         while (env->cprop != NULL) {
2782                 void *oldopcode = NULL;
2783
2784                 /* remove the first partition X from cprop */
2785                 X           = env->cprop;
2786                 X->on_cprop = 0;
2787                 env->cprop  = X->cprop_next;
2788
2789                 old_type_was_T_or_C = X->type_is_T_or_C;
2790
2791                 DB((dbg, LEVEL_2, "Propagate type on part%d\n", X->nr));
2792                 fallen   = NULL;
2793                 n_fallen = 0;
2794                 for (;;) {
2795                         int cprop_empty   = list_empty(&X->cprop);
2796                         int cprop_X_empty = list_empty(&X->cprop_X);
2797
2798                         if (cprop_empty && cprop_X_empty) {
2799                                 /* both cprop lists are empty */
2800                                 break;
2801                         }
2802
2803                         /* remove the first Node x from X.cprop */
2804                         if (cprop_empty) {
2805                                 /* Get a node from the cprop_X list only if
2806                                  * all data nodes are processed.
2807                                  * This ensures, that all inputs of the Cond
2808                                  * predecessor are processed if its type is still Top.
2809                                  */
2810                                 x = list_entry(X->cprop_X.next, node_t, cprop_list);
2811                         } else {
2812                                 x = list_entry(X->cprop.next, node_t, cprop_list);
2813                         }
2814
2815                         //assert(x->part == X);
2816                         list_del(&x->cprop_list);
2817                         x->on_cprop = 0;
2818
2819                         if (x->is_follower && identity(x) == x) {
2820                                 /* check the opcode first */
2821                                 if (oldopcode == NULL) {
2822                                         oldopcode = lambda_opcode(get_first_node(X), env);
2823                                 }
2824                                 if (oldopcode != lambda_opcode(x, env)) {
2825                                         if (x->on_fallen == 0) {
2826                                                 /* different opcode -> x falls out of this partition */
2827                                                 x->next      = fallen;
2828                                                 x->on_fallen = 1;
2829                                                 fallen       = x;
2830                                                 ++n_fallen;
2831                                                 DB((dbg, LEVEL_2, "Add node %+F to fallen\n", x->node));
2832                                         }
2833                                 }
2834
2835                                 /* x will make the follower -> leader transition */
2836                                 follower_to_leader(x);
2837                         }
2838
2839                         /* compute a new type for x */
2840                         old_type = x->type;
2841                         DB((dbg, LEVEL_3, "computing type of %+F\n", x->node));
2842                         compute(x);
2843                         if (x->type.tv != old_type.tv) {
2844                                 DB((dbg, LEVEL_2, "node %+F has changed type from %+F to %+F\n", x->node, old_type, x->type));
2845                                 verify_type(old_type, x);
2846
2847                                 if (x->on_fallen == 0) {
2848                                         /* Add x to fallen. Nodes might fall from T -> const -> _|_, so check that they are
2849                                            not already on the list. */
2850                                         x->next      = fallen;
2851                                         x->on_fallen = 1;
2852                                         fallen       = x;
2853                                         ++n_fallen;
2854                                         DB((dbg, LEVEL_2, "Add node %+F to fallen\n", x->node));
2855                                 }
2856                                 for (i = get_irn_n_outs(x->node) - 1; i >= 0; --i) {
2857                                         ir_node *succ = get_irn_out(x->node, i);
2858                                         node_t  *y    = get_irn_node(succ);
2859
2860                                         /* Add y to y.partition.cprop. */
2861                                         add_to_cprop(y, env);
2862                                 }
2863                         }
2864                 }
2865
2866                 if (n_fallen > 0 && n_fallen != X->n_leader) {
2867                         DB((dbg, LEVEL_2, "Splitting part%d by fallen\n", X->nr));
2868                         Y = split(&X, fallen, env);
2869                         /*
2870                          * We have split out fallen node. The type of the result
2871                          * partition is NOT set yet.
2872                          */
2873                         Y->type_is_T_or_C = 0;
2874                 } else {
2875                         Y = X;
2876                 }
2877                 /* remove the flags from the fallen list */
2878                 for (x = fallen; x != NULL; x = x->next)
2879                         x->on_fallen = 0;
2880
2881                 if (old_type_was_T_or_C) {
2882                         node_t *y, *tmp;
2883
2884                         /* check if some nodes will make the leader -> follower transition */
2885                         list_for_each_entry_safe(node_t, y, tmp, &Y->Leader, node_list) {
2886                                 if (y->type.tv != tarval_top && ! is_con(y->type)) {
2887                                         node_t *eq_node = identity(y);
2888
2889                                         if (eq_node != y && eq_node->part == y->part) {
2890                                                 DB((dbg, LEVEL_2, "Node %+F is a follower of %+F\n", y->node, eq_node->node));
2891                                                 /* move to Follower */
2892                                                 y->is_follower = 1;
2893                                                 list_del(&y->node_list);
2894                                                 list_add_tail(&y->node_list, &Y->Follower);
2895                                                 --Y->n_leader;
2896
2897                                                 segregate_def_use_chain(y->node);
2898                                         }
2899                                 }
2900                         }
2901                 }
2902                 split_by(Y, env);
2903         }
2904 }  /* propagate */
2905
2906 /**
2907  * Get the leader for a given node from its congruence class.
2908  *
2909  * @param irn  the node
2910  */
2911 static ir_node *get_leader(node_t *node) {
2912         partition_t *part = node->part;
2913
2914         if (part->n_leader > 1 || node->is_follower) {
2915                 if (node->is_follower) {
2916                         DB((dbg, LEVEL_2, "Replacing follower %+F\n", node->node));
2917                 }
2918                 else
2919                         DB((dbg, LEVEL_2, "Found congruence class for %+F\n", node->node));
2920
2921                 return get_first_node(part)->node;
2922         }
2923         return node->node;
2924 }  /* get_leader */
2925
2926 /**
2927  * Returns non-zero if a mode_T node has only one reachable output.
2928  */
2929 static int only_one_reachable_proj(ir_node *n) {
2930         int i, k = 0;
2931
2932         for (i = get_irn_n_outs(n) - 1; i >= 0; --i) {
2933                 ir_node *proj = get_irn_out(n, i);
2934                 node_t  *node;
2935
2936                 /* skip non-control flow Proj's */
2937                 if (get_irn_mode(proj) != mode_X)
2938                         continue;
2939
2940                 node = get_irn_node(proj);
2941                 if (node->type.tv == tarval_reachable) {
2942                         if (++k > 1)
2943                                 return 0;
2944                 }
2945         }
2946         return 1;
2947 }  /* only_one_reachable_proj */
2948
2949 /**
2950  * Return non-zero if the control flow predecessor node pred
2951  * is the only reachable control flow exit of its block.
2952  *
2953  * @param pred   the control flow exit
2954  * @param block  the destination block
2955  */
2956 static int can_exchange(ir_node *pred, ir_node *block) {
2957         if (is_Start(pred) || has_Block_label(block))
2958                 return 0;
2959         else if (is_Jmp(pred))
2960                 return 1;
2961         else if (get_irn_mode(pred) == mode_T) {
2962                 /* if the predecessor block has more than one
2963                    reachable outputs we cannot remove the block */
2964                 return only_one_reachable_proj(pred);
2965         }
2966         return 0;
2967 }  /* can_exchange */
2968
2969 /**
2970  * Block Post-Walker, apply the analysis results on control flow by
2971  * shortening Phi's and Block inputs.
2972  */
2973 static void apply_cf(ir_node *block, void *ctx) {
2974         environment_t *env = ctx;
2975         node_t        *node = get_irn_node(block);
2976         int           i, j, k, n;
2977         ir_node       **ins, **in_X;
2978         ir_node       *phi, *next;
2979
2980         n = get_Block_n_cfgpreds(block);
2981
2982         if (node->type.tv == tarval_unreachable) {
2983                 env->modified = 1;
2984
2985                 for (i = n - 1; i >= 0; --i) {
2986                         ir_node *pred = get_Block_cfgpred(block, i);
2987
2988                         if (! is_Bad(pred)) {
2989                                 node_t *pred_bl = get_irn_node(get_nodes_block(skip_Proj(pred)));
2990
2991                                 if (pred_bl->flagged == 0) {
2992                                         pred_bl->flagged = 3;
2993
2994                                         if (pred_bl->type.tv == tarval_reachable) {
2995                                                 /*
2996                                                  * We will remove an edge from block to its pred.
2997                                                  * This might leave the pred block as an endless loop
2998                                                  */
2999                                                 if (! is_backedge(block, i))
3000                                                         keep_alive(pred_bl->node);
3001                                         }
3002                                 }
3003                         }
3004                 }
3005
3006                 /* the EndBlock is always reachable even if the analysis
3007                    finds out the opposite :-) */
3008                 if (block != get_irg_end_block(current_ir_graph)) {
3009                         /* mark dead blocks */
3010                         set_Block_dead(block);
3011                         DB((dbg, LEVEL_1, "Removing dead %+F\n", block));
3012                 } else {
3013                         /* the endblock is unreachable */
3014                         set_irn_in(block, 0, NULL);
3015                 }
3016                 return;
3017         }
3018
3019         if (n == 1) {
3020                 /* only one predecessor combine */
3021                 ir_node *pred = skip_Proj(get_Block_cfgpred(block, 0));
3022
3023                 if (can_exchange(pred, block)) {
3024                         ir_node *new_block = get_nodes_block(pred);
3025                         DB((dbg, LEVEL_1, "Fuse %+F with %+F\n", block, new_block));
3026                         DBG_OPT_COMBO(block, new_block, FS_OPT_COMBO_CF);
3027                         exchange(block, new_block);
3028                         node->node = new_block;
3029                         env->modified = 1;
3030                 }
3031                 return;
3032         }
3033
3034         NEW_ARR_A(ir_node *, in_X, n);
3035         k = 0;
3036         for (i = 0; i < n; ++i) {
3037                 ir_node *pred = get_Block_cfgpred(block, i);
3038                 node_t  *node = get_irn_node(pred);
3039
3040                 if (node->type.tv == tarval_reachable) {
3041                         in_X[k++] = pred;
3042                 } else {
3043                         DB((dbg, LEVEL_1, "Removing dead input %d from %+F (%+F)\n", i, block, pred));
3044                         if (! is_Bad(pred)) {
3045                                 node_t *pred_bl = get_irn_node(get_nodes_block(skip_Proj(pred)));
3046
3047                                 if (pred_bl->flagged == 0) {
3048                                         pred_bl->flagged = 3;
3049
3050                                         if (pred_bl->type.tv == tarval_reachable) {
3051                                                 /*
3052                                                  * We will remove an edge from block to its pred.
3053                                                  * This might leave the pred block as an endless loop
3054                                                  */
3055                                                 if (! is_backedge(block, i))
3056                                                         keep_alive(pred_bl->node);
3057                                         }
3058                                 }
3059                         }
3060                 }
3061         }
3062         if (k >= n)
3063                 return;
3064
3065         /* fix Phi's */
3066         NEW_ARR_A(ir_node *, ins, n);
3067         for (phi = get_Block_phis(block); phi != NULL; phi = next) {
3068                 node_t *node = get_irn_node(phi);
3069
3070                 next = get_Phi_next(phi);
3071                 if (is_tarval(node->type.tv) && tarval_is_constant(node->type.tv)) {
3072                         /* this Phi is replaced by a constant */
3073                         tarval  *tv = node->type.tv;
3074                         ir_node *c  = new_Const(tv);
3075
3076                         set_irn_node(c, node);
3077                         node->node = c;
3078                         DB((dbg, LEVEL_1, "%+F is replaced by %+F\n", phi, c));
3079                         DBG_OPT_COMBO(phi, c, FS_OPT_COMBO_CONST);
3080                         exchange(phi, c);
3081                         env->modified = 1;
3082                 } else {
3083                         j = 0;
3084                         for (i = 0; i < n; ++i) {
3085                                 node_t *pred = get_irn_node(get_Block_cfgpred(block, i));
3086
3087                                 if (pred->type.tv == tarval_reachable) {
3088                                         ins[j++] = get_Phi_pred(phi, i);
3089                                 }
3090                         }
3091                         if (j == 1) {
3092                                 /* this Phi is replaced by a single predecessor */
3093                                 ir_node *s = ins[0];
3094                                 node_t *phi_node = get_irn_node(phi);
3095
3096                                 node->node = s;
3097                                 DB((dbg, LEVEL_1, "%+F is replaced by %+F because of cf change\n", phi, s));
3098                                 DBG_OPT_COMBO(phi, s, FS_OPT_COMBO_FOLLOWER);
3099                                 exchange(phi, s);
3100                                 phi_node->node = s;
3101                                 env->modified = 1;
3102                         } else {
3103                                 set_irn_in(phi, j, ins);
3104                                 env->modified = 1;
3105                         }
3106                 }
3107         }
3108
3109         /* fix block */
3110         if (k == 1) {
3111                 /* this Block has only one live predecessor */
3112                 ir_node *pred = skip_Proj(in_X[0]);
3113
3114                 if (can_exchange(pred, block)) {
3115                         ir_node *new_block = get_nodes_block(pred);
3116                         DBG_OPT_COMBO(block, new_block, FS_OPT_COMBO_CF);
3117                         exchange(block, new_block);
3118                         node->node = new_block;
3119                         env->modified = 1;
3120                         return;
3121                 }
3122         }
3123         set_irn_in(block, k, in_X);
3124         env->modified = 1;
3125 }  /* apply_cf */
3126
3127 /**
3128  * Exchange a node by its leader.
3129  * Beware: in rare cases the mode might be wrong here, for instance
3130  * AddP(x, NULL) is a follower of x, but with different mode.
3131  * Fix it here.
3132  */
3133 static void exchange_leader(ir_node *irn, ir_node *leader) {
3134         ir_mode *mode = get_irn_mode(irn);
3135         if (mode != get_irn_mode(leader)) {
3136                 /* The conv is a no-op, so we are free to place it
3137                  * either in the block of the leader OR in irn's block.
3138                  * Probably placing it into leaders block might reduce
3139                  * the number of Conv due to CSE. */
3140                 ir_node  *block = get_nodes_block(leader);
3141                 dbg_info *dbg   = get_irn_dbg_info(irn);
3142
3143                 leader = new_rd_Conv(dbg, current_ir_graph, block, leader, mode);
3144         }
3145         exchange(irn, leader);
3146 }  /* exchange_leader */
3147
3148 /**
3149  * Check, if all users of a mode_M node are dead. Use
3150  * the Def-Use edges for this purpose, as they still
3151  * reflect the situation.
3152  */
3153 static int all_users_are_dead(const ir_node *irn) {
3154         int i, n = get_irn_n_outs(irn);
3155
3156         for (i = 1; i <= n; ++i) {
3157                 const ir_node *succ  = irn->out[i].use;
3158                 const node_t  *block = get_irn_node(get_nodes_block(succ));
3159                 const node_t  *node;
3160
3161                 if (block->type.tv == tarval_unreachable) {
3162                         /* block is unreachable */
3163                         continue;
3164                 }
3165                 node = get_irn_node(succ);
3166                 if (node->type.tv != tarval_top) {
3167                         /* found a reachable user */
3168                         return 0;
3169                 }
3170         }
3171         /* all users are unreachable */
3172         return 1;
3173 }  /* all_user_are_dead */
3174
3175 /**
3176  * Walker: Find reachable mode_M nodes that have only
3177  * unreachable users. These nodes must be kept later.
3178  */
3179 static void find_kept_memory(ir_node *irn, void *ctx) {
3180         environment_t *env = ctx;
3181         node_t        *node, *block;
3182
3183         if (get_irn_mode(irn) != mode_M)
3184                 return;
3185
3186         block = get_irn_node(get_nodes_block(irn));
3187         if (block->type.tv == tarval_unreachable)
3188                 return;
3189
3190         node = get_irn_node(irn);
3191         if (node->type.tv == tarval_top)
3192                 return;
3193
3194         /* ok, we found a live memory node. */
3195         if (all_users_are_dead(irn)) {
3196                 DB((dbg, LEVEL_1, "%+F must be kept\n", irn));
3197                 ARR_APP1(ir_node *, env->kept_memory, irn);
3198         }
3199 }  /* find_kept_memory */
3200
3201 /**
3202  * Post-Walker, apply the analysis results;
3203  */
3204 static void apply_result(ir_node *irn, void *ctx) {
3205         environment_t *env = ctx;
3206         node_t        *node = get_irn_node(irn);
3207
3208         if (is_Block(irn) || is_End(irn) || is_Bad(irn)) {
3209                 /* blocks already handled, do not touch the End node */
3210         } else {
3211                 node_t *block = get_irn_node(get_nodes_block(irn));
3212
3213                 if (block->type.tv == tarval_unreachable) {
3214                         ir_node *bad = get_irg_bad(current_ir_graph);
3215
3216                         /* here, bad might already have a node, but this can be safely ignored
3217                            as long as bad has at least ONE valid node */
3218                         set_irn_node(bad, node);
3219                         node->node = bad;
3220                         DB((dbg, LEVEL_1, "%+F is unreachable\n", irn));
3221                         exchange(irn, bad);
3222                         env->modified = 1;
3223                 } else if (node->type.tv == tarval_top) {
3224                         ir_mode *mode = get_irn_mode(irn);
3225
3226                         if (mode == mode_M) {
3227                                 /* never kill a mode_M node */
3228                                 if (is_Proj(irn)) {
3229                                         ir_node *pred  = get_Proj_pred(irn);
3230                                         node_t  *pnode = get_irn_node(pred);
3231
3232                                         if (pnode->type.tv == tarval_top) {
3233                                                 /* skip the predecessor */
3234                                                 ir_node *mem = get_memop_mem(pred);
3235                                                 node->node = mem;
3236                                                 DB((dbg, LEVEL_1, "%+F computes Top, replaced by %+F\n", irn, mem));
3237                                                 exchange(irn, mem);
3238                                                 env->modified = 1;
3239                                         }
3240                                 }
3241                                 /* leave other nodes, especially PhiM */
3242                         } else if (mode == mode_T) {
3243                                 /* Do not kill mode_T nodes, kill their Projs */
3244                         } else if (! is_Unknown(irn)) {
3245                                 /* don't kick away Unknown's, they might be still needed */
3246                                 ir_node *unk = new_r_Unknown(current_ir_graph, mode);
3247
3248                                 /* control flow should already be handled at apply_cf() */
3249                                 assert(mode != mode_X);
3250
3251                                 /* see comment above */
3252                                 set_irn_node(unk, node);
3253                                 node->node = unk;
3254                                 DB((dbg, LEVEL_1, "%+F computes Top\n", irn));
3255                                 exchange(irn, unk);
3256                                 env->modified = 1;
3257                         }
3258                 }
3259                 else if (get_irn_mode(irn) == mode_X) {
3260                         if (is_Proj(irn)) {
3261                                 /* leave or Jmp */
3262                                 ir_node *cond = get_Proj_pred(irn);
3263
3264                                 if (is_Cond(cond)) {
3265                                         if (only_one_reachable_proj(cond)) {
3266                                                 ir_node *jmp = new_r_Jmp(current_ir_graph, block->node);
3267                                                 set_irn_node(jmp, node);
3268                                                 node->node = jmp;
3269                                                 DB((dbg, LEVEL_1, "%+F is replaced by %+F\n", irn, jmp));
3270                                                 DBG_OPT_COMBO(irn, jmp, FS_OPT_COMBO_CF);
3271                                                 exchange(irn, jmp);
3272                                                 env->modified = 1;
3273                                         } else {
3274                                                 node_t *sel = get_irn_node(get_Cond_selector(cond));
3275                                                 tarval *tv  = sel->type.tv;
3276
3277                                                 if (is_tarval(tv) && tarval_is_constant(tv)) {
3278                                                         /* The selector is a constant, but more
3279                                                          * than one output is active: An unoptimized
3280                                                          * case found. */
3281                                                         env->unopt_cf = 1;
3282                                                 }
3283                                         }
3284                                 }
3285                         }
3286                 } else {
3287                         /* normal data node */
3288                         if (is_tarval(node->type.tv) && tarval_is_constant(node->type.tv)) {
3289                                 tarval *tv = node->type.tv;
3290
3291                                 /*
3292                                  * Beware: never replace mode_T nodes by constants. Currently we must mark
3293                                  * mode_T nodes with constants, but do NOT replace them.
3294                                  */
3295                                 if (! is_Const(irn) && get_irn_mode(irn) != mode_T) {
3296                                         /* can be replaced by a constant */
3297                                         ir_node *c = new_Const(tv);
3298                                         set_irn_node(c, node);
3299                                         node->node = c;
3300                                         DB((dbg, LEVEL_1, "%+F is replaced by %+F\n", irn, c));
3301                                         DBG_OPT_COMBO(irn, c, FS_OPT_COMBO_CONST);
3302                                         exchange_leader(irn, c);
3303                                         env->modified = 1;
3304                                 }
3305                         } else if (is_entity(node->type.sym.entity_p)) {
3306                                 if (! is_SymConst(irn)) {
3307                                         /* can be replaced by a SymConst */
3308                                         ir_node *symc = new_r_SymConst(current_ir_graph, block->node, get_irn_mode(irn), node->type.sym, symconst_addr_ent);
3309                                         set_irn_node(symc, node);
3310                                         node->node = symc;
3311
3312                                         DB((dbg, LEVEL_1, "%+F is replaced by %+F\n", irn, symc));
3313                                         DBG_OPT_COMBO(irn, symc, FS_OPT_COMBO_CONST);
3314                                         exchange_leader(irn, symc);
3315                                         env->modified = 1;
3316                                 }
3317                         } else if (is_Confirm(irn)) {
3318                                 /* Confirms are always follower, but do not kill them here */
3319                         } else {
3320                                 ir_node *leader = get_leader(node);
3321
3322                                 if (leader != irn) {
3323                                         int non_strict_phi = 0;
3324
3325                                         /*
3326                                          * Beware: Do not remove Phi(Unknown, ..., x, ..., Unknown)
3327                                          * as this might create non-strict programs.
3328                                          */
3329                                         if (node->is_follower && is_Phi(irn) && !is_Unknown(leader)) {
3330                                                 int i;
3331
3332                                                 for (i = get_Phi_n_preds(irn) - 1; i >= 0; --i) {
3333                                                         ir_node *pred = get_Phi_pred(irn, i);
3334
3335                                                         if (is_Unknown(pred)) {
3336                                                                 non_strict_phi = 1;
3337                                                                 break;
3338                                                         }
3339                                                 }
3340                                         }
3341                                         if (! non_strict_phi) {
3342                                                 DB((dbg, LEVEL_1, "%+F from part%d is replaced by %+F\n", irn, node->part->nr, leader));
3343                                                 if (node->is_follower)
3344                                                         DBG_OPT_COMBO(irn, leader, FS_OPT_COMBO_FOLLOWER);
3345                                                 else
3346                                                         DBG_OPT_COMBO(irn, leader, FS_OPT_COMBO_CONGRUENT);
3347                                                 exchange_leader(irn, leader);
3348                                                 env->modified = 1;
3349                                         }
3350                                 }
3351                         }
3352                 }
3353         }
3354 }  /* apply_result */
3355
3356 /**
3357  * Fix the keep-alives by deleting unreachable ones.
3358  */
3359 static void apply_end(ir_node *end, environment_t *env) {
3360         int i, j,  n = get_End_n_keepalives(end);
3361         ir_node **in;
3362
3363         if (n > 0)
3364                 NEW_ARR_A(ir_node *, in, n);
3365
3366         /* fix the keep alive */
3367         for (i = j = 0; i < n; i++) {
3368                 ir_node *ka   = get_End_keepalive(end, i);
3369                 node_t  *node = get_irn_node(ka);
3370
3371                 if (! is_Block(ka))
3372                         node = get_irn_node(get_nodes_block(ka));
3373
3374                 if (node->type.tv != tarval_unreachable && !is_Bad(ka))
3375                         in[j++] = ka;
3376         }
3377         if (j != n) {
3378                 set_End_keepalives(end, j, in);
3379                 env->modified = 1;
3380         }
3381 }  /* apply_end */
3382
3383 #define SET(code) op_##code->ops.generic = (op_func)compute_##code
3384
3385 /**
3386  * sets the generic functions to compute.
3387  */
3388 static void set_compute_functions(void) {
3389         int i;
3390
3391         /* set the default compute function */
3392         for (i = get_irp_n_opcodes() - 1; i >= 0; --i) {
3393                 ir_op *op = get_irp_opcode(i);
3394                 op->ops.generic = (op_func)default_compute;
3395         }
3396
3397         /* set specific functions */
3398         SET(Block);
3399         SET(Unknown);
3400         SET(Bad);
3401         SET(Jmp);
3402         SET(Phi);
3403         SET(Add);
3404         SET(Sub);
3405         SET(Eor);
3406         SET(SymConst);
3407         SET(Cmp);
3408         SET(Proj);
3409         SET(Confirm);
3410         SET(Return);
3411         SET(End);
3412         SET(Call);
3413 }  /* set_compute_functions */
3414
3415 /**
3416  * Add memory keeps.
3417  */
3418 static void add_memory_keeps(ir_node **kept_memory, int len) {
3419         ir_node      *end = get_irg_end(current_ir_graph);
3420         int          i;
3421         ir_nodeset_t set;
3422
3423         ir_nodeset_init(&set);
3424
3425         /* check, if those nodes are already kept */
3426         for (i = get_End_n_keepalives(end) - 1; i >= 0; --i)
3427                 ir_nodeset_insert(&set, get_End_keepalive(end, i));
3428
3429         for (i = len - 1; i >= 0; --i) {
3430                 ir_node *ka = kept_memory[i];
3431
3432                 if (! ir_nodeset_contains(&set, ka)) {
3433                         add_End_keepalive(end, ka);
3434                 }
3435         }
3436         ir_nodeset_destroy(&set);
3437 }  /* add_memory_keeps */
3438
3439 void combo(ir_graph *irg) {
3440         environment_t env;
3441         ir_node       *initial_bl;
3442         node_t        *start;
3443         ir_graph      *rem = current_ir_graph;
3444         int           len;
3445
3446         current_ir_graph = irg;
3447
3448         /* register a debug mask */
3449         FIRM_DBG_REGISTER(dbg, "firm.opt.combo");
3450
3451         DB((dbg, LEVEL_1, "Doing COMBO for %+F\n", irg));
3452
3453         obstack_init(&env.obst);
3454         env.worklist       = NULL;
3455         env.cprop          = NULL;
3456         env.touched        = NULL;
3457         env.initial        = NULL;
3458 #ifdef DEBUG_libfirm
3459         env.dbg_list       = NULL;
3460 #endif
3461         env.opcode2id_map  = new_set(cmp_opcode, iro_Last * 4);
3462         env.type2id_map    = pmap_create();
3463         env.kept_memory    = NEW_ARR_F(ir_node *, 0);
3464         env.end_idx        = get_opt_global_cse() ? 0 : -1;
3465         env.lambda_input   = 0;
3466         env.modified       = 0;
3467         env.unopt_cf       = 0;
3468         /* options driving the optimization */
3469         env.commutative    = 1;
3470         env.opt_unknown    = 1;
3471
3472         assure_irg_outs(irg);
3473         assure_cf_loop(irg);
3474
3475         /* we have our own value_of function */
3476         set_value_of_func(get_node_tarval);
3477
3478         set_compute_functions();
3479         DEBUG_ONLY(part_nr = 0);
3480
3481         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
3482
3483         if (env.opt_unknown)
3484                 tarval_UNKNOWN = tarval_top;
3485         else
3486                 tarval_UNKNOWN = tarval_bad;
3487
3488         /* create the initial partition and place it on the work list */
3489         env.initial = new_partition(&env);
3490         add_to_worklist(env.initial, &env);
3491         irg_walk_graph(irg, create_initial_partitions, init_block_phis, &env);
3492
3493         /* set the hook: from now, every node has a partition and a type */
3494         DEBUG_ONLY(set_dump_node_vcgattr_hook(dump_partition_hook));
3495
3496         /* all nodes on the initial partition have type Top */
3497         env.initial->type_is_T_or_C = 1;
3498
3499         /* Place the START Node's partition on cprop.
3500            Place the START Node on its local worklist. */
3501         initial_bl = get_irg_start_block(irg);
3502         start      = get_irn_node(initial_bl);
3503         add_to_cprop(start, &env);
3504
3505         do {
3506                 propagate(&env);
3507                 if (env.worklist != NULL)
3508                         cause_splits(&env);
3509         } while (env.cprop != NULL || env.worklist != NULL);
3510
3511         dump_all_partitions(&env);
3512         check_all_partitions(&env);
3513
3514 #if 0
3515         dump_ir_block_graph(irg, "-partition");
3516 #endif
3517
3518         /* apply the result */
3519
3520         /* check, which nodes must be kept */
3521         irg_walk_graph(irg, NULL, find_kept_memory, &env);
3522
3523         /* kill unreachable control flow */
3524         irg_block_walk_graph(irg, NULL, apply_cf, &env);
3525         /* Kill keep-alives of dead blocks: this speeds up apply_result()
3526          * and fixes assertion because dead cf to dead blocks is NOT removed by
3527          * apply_cf(). */
3528         apply_end(get_irg_end(irg), &env);
3529         irg_walk_graph(irg, NULL, apply_result, &env);
3530
3531         len = ARR_LEN(env.kept_memory);
3532         if (len > 0)
3533                 add_memory_keeps(env.kept_memory, len);
3534
3535         if (env.unopt_cf) {
3536                 DB((dbg, LEVEL_1, "Unoptimized Control Flow left"));
3537         }
3538
3539         if (env.modified) {
3540                 /* control flow might changed */
3541                 set_irg_outs_inconsistent(irg);
3542                 set_irg_extblk_inconsistent(irg);
3543                 set_irg_doms_inconsistent(irg);
3544                 set_irg_loopinfo_inconsistent(irg);
3545         }
3546
3547         ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
3548
3549         /* remove the partition hook */
3550         DEBUG_ONLY(set_dump_node_vcgattr_hook(NULL));
3551
3552         DEL_ARR_F(env.kept_memory);
3553         pmap_destroy(env.type2id_map);
3554         del_set(env.opcode2id_map);
3555         obstack_free(&env.obst, NULL);
3556
3557         /* restore value_of() default behavior */
3558         set_value_of_func(NULL);
3559         current_ir_graph = rem;
3560 }  /* combo */