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