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