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