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