convert opts to use the opt_manage framework
[libfirm] / ir / opt / opt_blocks.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   Combining congruent blocks
23  * @author  Michael Beck
24  * @version $Id$
25  *
26  * This phase find congruent blocks.
27  * Two block are congruent, if they contains only equal calculations.
28  */
29 #include "config.h"
30
31 #include "iroptimize.h"
32 #include "ircons.h"
33 #include "irgmod.h"
34 #include "irgraph_t.h"
35 #include "irnode_t.h"
36 #include "iropt_t.h"
37 #include "array_t.h"
38 #include "trouts.h"
39 #include "irgwalk.h"
40 #include "set.h"
41 #include "irpass.h"
42 #include "debug.h"
43 #include "irtools.h"
44
45 /* define this for general block shaping: congruent blocks
46    are found not only before the end block but anywhere in the graph */
47 #define GENERAL_SHAPE
48
49 typedef struct partition_t     partition_t;
50 typedef struct block_t         block_t;
51 typedef struct node_t          node_t;
52 typedef struct pair_t          pair_t;
53 typedef struct phi_t           phi_t;
54 typedef struct opcode_key_t    opcode_key_t;
55 typedef struct listmap_entry_t listmap_entry_t;
56 typedef struct environment_t   environment_t;
57 typedef struct pred_t          pred_t;
58
59 /** An opcode map key. */
60 struct opcode_key_t {
61         unsigned    code;   /**< The Firm opcode. */
62         ir_mode     *mode;  /**< The mode of all nodes in the partition. */
63         int         arity;  /**< The arity of this opcode (needed for Phi etc. */
64         union {
65                 long            proj;   /**< For Proj nodes, its proj number */
66                 ir_entity       *ent;   /**< For Sel nodes, its entity */
67                 ir_tarval       *tv;    /**< For Const nodes, its tarval */
68                 symconst_symbol sym;    /**< For SymConst nodes, its symbol .*/
69                 void            *addr;  /**< Alias all addresses. */
70                 int             intVal; /**< For Conv/Div nodes: strict/remainderless. */
71         } u;
72 };
73
74 /** A partition contains all congruent blocks. */
75 struct partition_t {
76         list_head part_list;     /**< Double linked list of partitions. */
77         list_head blocks;        /**< List of blocks in this partition. */
78         unsigned  n_blocks;      /**< Number of block in this partition. */
79         ir_node   *meet_block;   /**< The control flow meet block of this partition. */
80 #ifdef DEBUG_libfirm
81         unsigned  nr;            /**< For debugging: number of this partition. */
82 #endif
83 };
84
85 /** A block. */
86 struct block_t {
87         list_head  block_list;   /**< Double linked list of block inside a partition. */
88         list_head  nodes;        /**< Wait-queue of nodes that must be checked for congruence. */
89         block_t    *next;        /**< Next block of a split list. */
90         ir_node    *block;       /**< Pointer to the associated IR-node block. */
91         ir_node    **roots;      /**< An array of all root nodes. */
92         node_t     *cf_root;     /**< The control flow root node of this block. */
93         pair_t     *input_pairs; /**< The list of inputs to this block. */
94         phi_t      *phis;        /**< The list of Phis in this block. */
95         block_t    *all_next;    /**< Links all created blocks. */
96         int        meet_input;   /**< Input number of this block in the meet-block. */
97 };
98
99 /** A node. */
100 struct node_t {
101         list_head  node_list;    /**< Double linked list of block inside a partition. */
102         ir_node    *node;        /**< Pointer to the associated IR-node or NULL for block inputs. */
103         char       is_input;     /**< Set if this node is an input from other block. */
104 };
105
106 /** The environment. */
107 struct environment_t {
108         list_head       partitions;     /**< list of partitions. */
109         list_head       ready;          /**< list of ready partitions. */
110         set             *opcode2id_map; /**< The opcodeMode->id map. */
111         ir_node         **live_outs;    /**< Live out only nodes. */
112         block_t         *all_blocks;    /**< List of all created blocks. */
113         struct obstack  obst;           /** obstack for temporary data */
114 };
115
116 /** A (node, input index) pair. */
117 struct pair_t {
118         pair_t  *next;    /**< Points to the next pair entry. */
119         ir_node *irn;     /**< The IR-node. */
120         int     index;    /**< An input index. */
121         ir_node **ins;    /**< A new in array once allocated. */
122 };
123
124 /** A Phi, inputs pair. */
125 struct phi_t {
126         phi_t   *next;    /**< Points to the next Phi pair entry. */
127         ir_node *phi;     /**< The Phi node. */
128         ir_node **ins;    /**< A new in array once allocated. */
129 };
130
131 /** Describes a predecessor input. */
132 struct pred_t {
133         ir_node *pred;  /**< The predecessor. */
134         int     index;  /**< Its input index. */
135 };
136
137 /**
138  * An entry in the list_map.
139  */
140 struct listmap_entry_t {
141         void            *id;    /**< The id. */
142         block_t         *list;  /**< The associated list for this id. */
143         listmap_entry_t *next;  /**< Link to the next entry in the map. */
144 };
145
146 /** We must map id's to lists. */
147 typedef struct listmap_t {
148         set             *map;    /**< Map id's to listmap_entry_t's */
149         listmap_entry_t *values; /**< List of all values in the map. */
150 } listmap_t;
151
152 #define get_Block_entry(block)  ((block_t *)get_irn_link(block))
153
154 /** The debug module handle. */
155 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
156
157 /** Next partition number. */
158 DEBUG_ONLY(static unsigned part_nr = 0);
159
160 #ifdef DEBUG_libfirm
161 /**
162  * Dump partition to output.
163  */
164 static void dump_partition(const char *msg, const partition_t *part)
165 {
166         const block_t *block;
167         int           first = 1;
168
169         DB((dbg, LEVEL_2, " %s part%u (%u blocks) {\n  ", msg, part->nr, part->n_blocks));
170         list_for_each_entry(block_t, block, &part->blocks, block_list) {
171                 DB((dbg, LEVEL_2, "%s%+F", first ? "" : ", ", block->block));
172                 first = 0;
173         }
174         DB((dbg, LEVEL_2, "\n }\n"));
175 }  /* dump_partition */
176
177 /**
178  * Dumps a list.
179  */
180 static void dump_list(const char *msg, const block_t *block)
181 {
182         const block_t *p;
183         int           first = 1;
184
185         DB((dbg, LEVEL_3, "  %s = {\n   ", msg));
186         for (p = block; p != NULL; p = p->next) {
187                 DB((dbg, LEVEL_3, "%s%+F", first ? "" : ", ", p->block));
188                 first = 0;
189         }
190         DB((dbg, LEVEL_3, "\n  }\n"));
191 }  /* do_dump_list */
192 #else
193 #define dump_partition(msg, part)
194 #define dump_list(msg, block)
195 #endif
196
197 /**
198  * Compare two pointer values of a listmap.
199  */
200 static int listmap_cmp_ptr(const void *elt, const void *key, size_t size)
201 {
202         const listmap_entry_t *e1 = (const listmap_entry_t*)elt;
203         const listmap_entry_t *e2 = (const listmap_entry_t*)key;
204
205         (void) size;
206         return e1->id != e2->id;
207 }  /* listmap_cmp_ptr */
208
209 /**
210  * Initializes a listmap.
211  *
212  * @param map  the listmap
213  */
214 static void listmap_init(listmap_t *map)
215 {
216         map->map    = new_set(listmap_cmp_ptr, 16);
217         map->values = NULL;
218 }  /* listmap_init */
219
220 /**
221  * Terminates a listmap.
222  *
223  * @param map  the listmap
224  */
225 static void listmap_term(listmap_t *map)
226 {
227         del_set(map->map);
228 }  /* listmap_term */
229
230 /**
231  * Return the associated listmap entry for a given id.
232  *
233  * @param map  the listmap
234  * @param id   the id to search for
235  *
236  * @return the associated listmap entry for the given id
237  */
238 static listmap_entry_t *listmap_find(listmap_t *map, void *id)
239 {
240         listmap_entry_t key, *entry;
241
242         key.id   = id;
243         key.list = NULL;
244         key.next = NULL;
245         entry    = (listmap_entry_t*)set_insert(map->map, &key, sizeof(key), HASH_PTR(id));
246
247         if (entry->list == NULL) {
248                 /* a new entry, put into the list */
249                 entry->next = map->values;
250                 map->values = entry;
251         }
252         return entry;
253 }  /* listmap_find */
254
255 /**
256  * Calculate the hash value for an opcode map entry.
257  *
258  * @param entry  an opcode map entry
259  *
260  * @return a hash value for the given opcode map entry
261  */
262 static unsigned opcode_hash(const opcode_key_t *entry)
263 {
264         /* assume long >= int */
265         return (unsigned)(PTR_TO_INT(entry->mode) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.addr) + entry->arity);
266 }  /* opcode_hash */
267
268 /**
269  * Compare two entries in the opcode map.
270  */
271 static int cmp_opcode(const void *elt, const void *key, size_t size)
272 {
273         const opcode_key_t *o1 = (opcode_key_t*)elt;
274         const opcode_key_t *o2 = (opcode_key_t*)key;
275
276         (void) size;
277         return o1->code != o2->code || o1->mode != o2->mode ||
278                o1->arity != o2->arity ||
279                o1->u.proj != o2->u.proj || o1->u.addr != o2->u.addr;
280 }  /* cmp_opcode */
281
282 /**
283  * Creates a new empty partition and put in on the
284  * partitions list.
285  *
286  * @param meet_block  the control flow meet block of this partition
287  * @param env         the environment
288  */
289 static partition_t *create_partition(ir_node *meet_block, environment_t *env)
290 {
291         partition_t *part = OALLOC(&env->obst, partition_t);
292
293         INIT_LIST_HEAD(&part->blocks);
294         part->meet_block = meet_block;
295         part->n_blocks   = 0;
296         DEBUG_ONLY(part->nr = part_nr++);
297         list_add_tail(&part->part_list, &env->partitions);
298         return part;
299 }  /* create_partition */
300
301 /**
302  * Allocate a new block in the given partition.
303  *
304  * @param block      the IR-node
305  * @param meet_input Input number of this block in the meet-block
306  * @param partition  the partition to add to
307  * @param env        the environment
308  */
309 static block_t *create_block(ir_node *block, int meet_input, partition_t *partition, environment_t *env)
310 {
311         block_t *bl = OALLOC(&env->obst, block_t);
312
313         set_irn_link(block, bl);
314
315         INIT_LIST_HEAD(&bl->nodes);
316         bl->next        = NULL;
317         bl->block       = block;
318         bl->roots       = NEW_ARR_F(ir_node *, 0);
319         bl->cf_root     = NULL;
320         bl->input_pairs = NULL;
321         bl->phis        = NULL;
322         bl->meet_input  = meet_input;
323
324         /* put it into the list of partition blocks */
325         list_add_tail(&bl->block_list, &partition->blocks);
326         ++partition->n_blocks;
327
328         /* put in into the list of all blocks */
329         bl->all_next    = env->all_blocks;
330         env->all_blocks = bl;
331
332         return bl;
333 }  /* create_block */
334
335 /**
336  * Allocate a new node and add it to a blocks wait queue.
337  *
338  * @param irn    the IR-node
339  * @param block  the block to add to
340  * @param env    the environment
341  */
342 static node_t *create_node(ir_node *irn, block_t *block, environment_t *env)
343 {
344         node_t *node = OALLOC(&env->obst, node_t);
345
346         node->node     = irn;
347         node->is_input = 0;
348
349         list_add_tail(&node->node_list, &block->nodes);
350
351         return node;
352 }  /* create_node */
353
354 /**
355  * Add an input pair to a block.
356  *
357  * @param block  the block
358  * @param irn    the IR-node that has an block input
359  * @param idx    the index of the block input in node's predecessors
360  * @param env    the environment
361  */
362 static void add_pair(block_t *block, ir_node *irn, int idx, environment_t *env)
363 {
364         pair_t *pair = OALLOC(&env->obst, pair_t);
365
366         pair->next  = block->input_pairs;
367         pair->irn   = irn;
368         pair->index = idx;
369         pair->ins   = NULL;
370
371         block->input_pairs = pair;
372 }  /* add_pair */
373
374 /**
375  * Add a Phi to a block.
376  *
377  * @param block  the block
378  * @param phi    the Phi node
379  * @param env    the environment
380  */
381 static void add_phi(block_t *block, ir_node *phi, environment_t *env)
382 {
383         phi_t *node = OALLOC(&env->obst, phi_t);
384
385         node->next = block->phis;
386         node->phi  = phi;
387         node->ins  = NULL;
388
389         block->phis = node;
390 }  /** add_phi */
391
392 /**
393  * Creates an opcode from a node.
394  */
395 static opcode_key_t *opcode(const node_t *node, environment_t *env)
396 {
397         opcode_key_t key, *entry;
398         ir_node      *irn = node->node;
399
400         if (node->is_input) {
401                 /* Node: as Block nodes are never propagated, it is safe to
402                    use its code for "input" node */
403                 key.code   = iro_Block;
404                 key.arity  = 0;
405         } else {
406                 key.code   = get_irn_opcode(irn);
407                 key.arity  = get_irn_arity(irn);
408         }
409         key.mode   = get_irn_mode(node->node);
410         key.u.proj = 0;
411         key.u.addr = NULL;
412
413         switch (key.code) {
414         case iro_Proj:
415                 key.u.proj = get_Proj_proj(irn);
416                 break;
417         case iro_Sel:
418                 key.u.ent = get_Sel_entity(irn);
419                 break;
420         case iro_SymConst:
421                 key.u.sym = get_SymConst_symbol(irn);
422                 break;
423         case iro_Const:
424                 key.u.tv  = get_Const_tarval(irn);
425                 break;
426         case iro_Conv:
427                 key.u.intVal = get_Conv_strict(irn);
428                 break;
429         case iro_Load:
430                 key.mode = get_Load_mode(irn);
431                 break;
432         case iro_Div:
433                 key.u.intVal = get_Div_no_remainder(irn);
434                 break;
435         case iro_Builtin:
436                 key.u.intVal = get_Builtin_kind(irn);
437                 break;
438         default:
439                 break;
440         }
441
442         entry = (opcode_key_t*)set_insert(env->opcode2id_map, &key, sizeof(key), opcode_hash(&key));
443         return entry;
444 }  /* opcode */
445
446 /**
447  * Split a partition by a local list.
448  *
449  * @param Z    partition to split
450  * @param g    a (non-empty) block list
451  * @param env  the environment
452  *
453  * @return  a new partition containing the nodes of g
454  */
455 static partition_t *split(partition_t *Z, block_t *g, environment_t *env)
456 {
457         partition_t *Z_prime;
458         block_t     *block;
459         unsigned    n = 0;
460
461         dump_partition("Splitting ", Z);
462         dump_list("by list ", g);
463
464         assert(g != NULL);
465
466         /* Remove g from Z. */
467         for (block = g; block != NULL; block = block->next) {
468                 list_del(&block->block_list);
469                 ++n;
470         }
471         assert(n < Z->n_blocks);
472         Z->n_blocks -= n;
473
474         /* Move g to a new partition, Z'. */
475         Z_prime = create_partition(Z->meet_block, env);
476         for (block = g; block != NULL; block = block->next) {
477                 list_add_tail(&block->block_list, &Z_prime->blocks);
478         }
479         Z_prime->n_blocks = n;
480
481         dump_partition("Now ", Z);
482         dump_partition("Created new ", Z_prime);
483         return Z_prime;
484 }  /* split */
485
486 /**
487  * Return non-zero if pred should be tread as a input node.
488  */
489 static int is_input_node(ir_node *pred, ir_node *irn, int index)
490 {
491         /* for now, do NOT turn direct calls into indirect one */
492         if (index != 1)
493                 return 1;
494         if (! is_SymConst_addr_ent(pred))
495                 return 1;
496         if (! is_Call(irn))
497                 return 1;
498         return 0;
499 }  /* is_input_node */
500
501 /**
502  * Propagate nodes on all wait queues of the given partition.
503  *
504  * @param part  the partition
505  * @param env   the environment
506  */
507 static void propagate_blocks(partition_t *part, environment_t *env)
508 {
509         block_t         *ready_blocks = NULL;
510         unsigned        n_ready       = 0;
511         block_t         *bl, *next;
512         listmap_t       map;
513         listmap_entry_t *iter;
514
515         DB((dbg, LEVEL_2, " Propagate blocks on part%u\n", part->nr));
516
517         /* Let map be an empty mapping from the range of Opcodes to (local) list of blocks. */
518         listmap_init(&map);
519         list_for_each_entry_safe(block_t, bl, next, &part->blocks, block_list) {
520                 opcode_key_t    *id;
521                 listmap_entry_t *entry;
522                 node_t          *node;
523
524                 if (list_empty(&bl->nodes)) {
525                         bl->next     = ready_blocks;
526                         ready_blocks = bl;
527                         ++n_ready;
528                         DB((dbg, LEVEL_2, " Block %+F completely processed\n", bl->block));
529                         continue;
530                 }
531
532                 /* get the first node from the wait queue */
533                 node = list_entry(bl->nodes.next, node_t, node_list);
534                 list_del(&node->node_list);
535
536                 /* put all not-visited predecessors to the wait queue */
537                 if (! node->is_input) {
538                         ir_node *irn = node->node;
539                         int     i;
540
541                         DB((dbg, LEVEL_3, "  propagate %+F\n", irn));
542                         ir_normalize_node(node->node);
543                         for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
544                                 ir_node *pred  = get_irn_n(irn, i);
545                                 ir_node *block = get_nodes_block(skip_Proj(pred));
546                                 node_t *p_node;
547
548                                 if (block != bl->block) {
549                                         p_node = create_node(pred, bl, env);
550                                         if (is_input_node(pred, irn, i)) {
551                                                 /* is a block live input */
552                                                 p_node->is_input = 1;
553                                                 if (! is_Phi(irn))
554                                                         add_pair(bl, irn, i, env);
555                                         } else if (is_Phi(pred)) {
556                                                 /* update the Phi list */
557                                                 add_phi(bl, pred, env);
558                                         }
559                                 } else if (! irn_visited_else_mark(pred)) {
560                                         /* not yet visited, ok */
561                                         p_node = create_node(pred, bl, env);
562
563                                         if (is_Phi(pred)) {
564                                                 /* update the Phi list */
565                                                 add_phi(bl, pred, env);
566                                         }
567                                 }
568                         }
569                 } else {
570                         DB((dbg, LEVEL_3, "  propagate Input %+F\n", node->node));
571                 }
572
573                 /* Add bl to map[opcode(n)]. */
574                 id          = opcode(node, env);
575                 entry       = listmap_find(&map, id);
576                 bl->next    = entry->list;
577                 entry->list = bl;
578         }
579
580         /* split out ready blocks */
581         if (n_ready > 0) {
582                 partition_t *Z;
583
584                 if (n_ready < part->n_blocks)
585                         Z = split(part, ready_blocks, env);
586                 else
587                         Z = part;
588                 list_del(&Z->part_list);
589
590                 if (Z->n_blocks > 1) {
591                         DB((dbg, LEVEL_2, " Partition %u is ready\n", Z->nr));
592                         list_add(&Z->part_list, &env->ready);
593                 } else {
594                         DB((dbg, LEVEL_2, " Partition %u contains only one block, killed\n", Z->nr));
595                 }
596         }
597
598         /* for all sets S except one in the range of map do */
599         for (iter = map.values; iter != NULL; iter = iter->next) {
600                 block_t *S;
601
602                 if (iter->next == NULL) {
603                         /* this is the last entry, ignore */
604                         break;
605                 }
606                 S = iter->list;
607
608                 /* Add SPLIT( X, S ) to P. */
609                 split(part, S, env);
610         }
611         listmap_term(&map);
612 }  /* propagate_blocks */
613
614 /**
615  * Propagate nodes on all wait queues.
616  *
617  * @param env    the environment
618  */
619 static void propagate(environment_t *env)
620 {
621         partition_t *part, *next;
622
623         list_for_each_entry_safe(partition_t, part, next, &env->partitions, part_list) {
624                 if (part->n_blocks < 2) {
625                         /* zero or one block left, kill this partition */
626                         list_del(&part->part_list);
627                         DB((dbg, LEVEL_2, " Partition %u contains less than 2 blocks, killed\n", part->nr));
628                 } else
629                         propagate_blocks(part, env);
630         }
631 }  /* propagate */
632
633 /**
634  * Map a block to the phi[block->input] live-trough.
635  */
636 static void *live_throughs(const block_t *bl, const ir_node *phi)
637 {
638         ir_node *input = get_Phi_pred(phi, bl->meet_input);
639
640         /* If this input is inside our block, this
641            is a live-out and not a live trough.
642            Live-outs are tested inside propagate, so map all of
643            them to the "general" value NULL */
644         if (get_nodes_block(input) == bl->block)
645                 return NULL;
646         return input;
647 }  /* live_throughs */
648
649 /**
650  * Split partition by live-outs and live-troughs.
651  *
652  * @param part  the partition
653  * @param env   the environment
654  */
655 static void propagate_blocks_live_troughs(partition_t *part, environment_t *env)
656 {
657         const ir_node   *meet_block = part->meet_block;
658         block_t         *bl, *next;
659         listmap_t       map;
660         listmap_entry_t *iter;
661         const ir_node   *phi;
662
663         DB((dbg, LEVEL_2, " Propagate live-troughs on part%u\n", part->nr));
664
665         for (phi = get_Block_phis(meet_block); phi != NULL; phi = get_Phi_next(phi)) {
666                 /* propagate on all Phis of the meet-block */
667
668                 if (part->n_blocks < 2) {
669                         /* zero or one block left, kill this partition */
670                         list_del(&part->part_list);
671                         DB((dbg, LEVEL_2, " Partition %u contains less than 2 blocks, killed\n", part->nr));
672                         return;
673                 }
674
675                 /* Let map be an empty mapping from the range of live-troughs to (local) list of blocks. */
676                 listmap_init(&map);
677                 list_for_each_entry_safe(block_t, bl, next, &part->blocks, block_list) {
678                         opcode_key_t    *id;
679                         listmap_entry_t *entry;
680
681                         /* Add bl to map[live_trough(bl)]. */
682                         id          = (opcode_key_t*)live_throughs(bl, phi);
683                         entry       = listmap_find(&map, id);
684                         bl->next    = entry->list;
685                         entry->list = bl;
686                 }
687
688                 /* for all sets S except one in the range of map do */
689                 for (iter = map.values; iter != NULL; iter = iter->next) {
690                         block_t *S;
691
692                         if (iter->next == NULL) {
693                                 /* this is the last entry, ignore */
694                                 break;
695                         }
696                         S = iter->list;
697
698                         /* Add SPLIT( X, S ) to P. */
699                         split(part, S, env);
700                 }
701                 listmap_term(&map);
702         }
703 }  /* propagate_blocks_live_troughs */
704
705 /**
706  * Propagate live-troughs on all partitions on the partition list.
707  *
708  * @param env    the environment
709  */
710 static void propagate_live_troughs(environment_t *env)
711 {
712         partition_t *part, *next;
713
714         list_for_each_entry_safe(partition_t, part, next, &env->partitions, part_list) {
715                 propagate_blocks_live_troughs(part, env);
716         }
717 }  /* propagate_live_troughs */
718
719 /**
720  * Apply analysis results by replacing all blocks of a partition
721  * by one representative.
722  *
723  * Route all inputs from all block of the partition to the one
724  * representative.
725  * Enhance all existing Phis by combining them.
726  * Create new Phis for all previous input nodes.
727  *
728  * @param part  the partition to process
729  */
730 static void apply(ir_graph *irg, partition_t *part)
731 {
732         block_t *repr = list_entry(part->blocks.next, block_t, block_list);
733         block_t *bl;
734         ir_node *block, *end, *meet_block, *p, *next;
735         ir_node **ins, **phi_ins;
736         phi_t   *repr_phi, *phi;
737         pair_t  *repr_pair, *pair;
738         int     i, j, k, n, n_phis;
739
740         list_del(&repr->block_list);
741
742         /* prepare new in arrays for the block ... */
743         block = repr->block;
744         n     = get_Block_n_cfgpreds(block);
745         ins   = NEW_ARR_F(ir_node *, n);
746
747         for (i = 0; i < n; ++i) {
748                 ins[i] = get_Block_cfgpred(block, i);
749         }
750
751         /* ... for all existing Phis ... */
752         for (repr_phi = repr->phis; repr_phi != NULL; repr_phi = repr_phi->next) {
753                 repr_phi->ins = NEW_ARR_F(ir_node *, n);
754
755                 for (i = 0; i < n; ++i)
756                         repr_phi->ins[i] = get_Phi_pred(repr_phi->phi, i);
757         }
758
759         /* ... and all newly created Phis */
760         for (repr_pair = repr->input_pairs; repr_pair != NULL; repr_pair = repr_pair->next) {
761                 ir_node *input = get_irn_n(repr_pair->irn, repr_pair->index);
762
763                 repr_pair->ins = NEW_ARR_F(ir_node *, n);
764                 for (i = 0; i < n; ++i)
765                         repr_pair->ins[i] = input;
766         }
767
768         DB((dbg, LEVEL_1, "Replacing "));
769
770         /* collect new in arrays */
771         end = get_irg_end(irg);
772         list_for_each_entry(block_t, bl, &part->blocks, block_list) {
773                 block = bl->block;
774
775                 DB((dbg, LEVEL_1, "%+F, ", block));
776
777                 /* first step: kill any keep-alive from this block */
778                 for (i = get_End_n_keepalives(end) - 1; i >= 0; --i) {
779                         ir_node *ka = get_End_keepalive(end, i);
780
781                         if (is_Block(ka)) {
782                                 if (ka == block)
783                                         remove_End_keepalive(end, ka);
784                         } else {
785                                 if (get_nodes_block(ka) == block)
786                                         remove_End_keepalive(end, ka);
787                         }
788                 }
789
790                 /* second step: update control flow */
791                 n = get_Block_n_cfgpreds(block);
792                 for (i = 0; i < n; ++i) {
793                         ir_node *pred = get_Block_cfgpred(block, i);
794                         ARR_APP1(ir_node *, ins, pred);
795                 }
796
797                 /* third step: update Phis */
798                 for (repr_phi = repr->phis, phi = bl->phis;
799                      repr_phi != NULL;
800                      repr_phi = repr_phi->next, phi = phi->next) {
801                         for (i = 0; i < n; ++i) {
802                                 ir_node *pred = get_Phi_pred(phi->phi, i);
803                                 ARR_APP1(ir_node *, repr_phi->ins, pred);
804                         }
805                 }
806
807                 /* fourth step: update inputs for new Phis */
808                 for (repr_pair = repr->input_pairs, pair = bl->input_pairs;
809                      repr_pair != NULL;
810                      repr_pair = repr_pair->next, pair = pair->next) {
811                         ir_node *input = get_irn_n(pair->irn, pair->index);
812
813                         for (i = 0; i < n; ++i)
814                                 ARR_APP1(ir_node *, repr_pair->ins, input);
815                 }
816         }
817
818         DB((dbg, LEVEL_1, "by %+F\n", repr->block));
819
820         /* rewire block input ... */
821         n = ARR_LEN(ins);
822
823         /*
824          * Some problem here. For:
825          * if (x) y = 1; else y = 2;
826          *
827          * the following code is constructed:
828          *
829          * b0: if (x) goto b1; else goto b1;
830          * b1: y = Phi(1,2)
831          *
832          * However, both predecessors of b1 are b0, making the Phi
833          * "wrong".
834          *
835          * We solve this by fixing critical edges.
836          */
837         for (i = 0; i < n; ++i) {
838                 ir_node     *pred = ins[i];
839                 const ir_op *cfop;
840
841                 if (is_Bad(pred))
842                         continue;
843
844                 cfop = get_irn_op(skip_Proj(pred));
845                 if (is_op_fragile(cfop)) {
846                         /* ignore exception flow */
847                         continue;
848                 }
849                 if (is_op_forking(cfop)) {
850                         /* a critical edge */
851                         ir_node *block = new_r_Block(irg, 1, &ins[i]);
852                         ir_node *jmp   = new_r_Jmp(block);
853                         ins[i] = jmp;
854                 }
855         }
856
857         block = repr->block;
858         set_irn_in(block, n, ins);
859         DEL_ARR_F(ins);
860
861         /* ... existing Phis ... */
862         for (repr_phi = repr->phis; repr_phi != NULL; repr_phi = repr_phi->next) {
863                 set_irn_in(repr_phi->phi, n, repr_phi->ins);
864                 DEL_ARR_F(repr_phi->ins);
865         }
866
867         /* ... and all inputs by creating new Phis ... */
868         for (repr_pair = repr->input_pairs; repr_pair != NULL; repr_pair = repr_pair->next) {
869                 ir_node *input = get_irn_n(repr_pair->irn, repr_pair->index);
870                 ir_mode *mode  = get_irn_mode(input);
871                 ir_node *phi   = new_r_Phi(block, n, repr_pair->ins, mode);
872
873                 set_irn_n(repr_pair->irn, repr_pair->index, phi);
874                 DEL_ARR_F(repr_pair->ins);
875
876                 /* might be optimized away */
877                 if (is_Phi(phi))
878                         add_Block_phi(block, phi);
879         }
880
881         /* ... finally rewire the meet block and fix its Phi-nodes */
882         meet_block = part->meet_block;
883         n         = get_Block_n_cfgpreds(meet_block);
884
885         ins = NEW_ARR_F(ir_node *, n);
886
887         n_phis = 0;
888         for (p = get_Block_phis(meet_block); p != NULL; p = get_Phi_next(p)) {
889                 ++n_phis;
890         }
891
892         phi_ins = NEW_ARR_F(ir_node *, n_phis * n);
893
894         for (i = j = 0; i < n; ++i) {
895                 ir_node *pred = get_Block_cfgpred(meet_block, i);
896
897                 list_for_each_entry(block_t, bl, &part->blocks, block_list) {
898                         if (bl->cf_root->node == pred)
899                                 goto continue_outer;
900                 }
901                 ins[j] = pred;
902
903                 for (k = 0, p = get_Block_phis(meet_block); p != NULL; p = get_Phi_next(p), ++k) {
904                         phi_ins[k * n + j] = get_Phi_pred(p, i);
905                 }
906                 ++j;
907
908 continue_outer:
909                 ;
910         }
911
912         /* fix phis */
913         if (j == 1) {
914                 for (k = 0, p = get_Block_phis(meet_block); p != NULL; p = next, ++k) {
915                         next = get_Phi_next(p);
916
917                         exchange(p, phi_ins[k * n]);
918                 }
919                 /* all Phis killed */
920                 set_Block_phis(meet_block, NULL);
921         } else {
922                 for (k = 0, p = get_Block_phis(meet_block); p != NULL; p = next, ++k) {
923                         next = get_Phi_next(p);
924
925                         set_irn_in(p, j, &phi_ins[k * n]);
926                 }
927         }
928         DEL_ARR_F(phi_ins);
929
930         /* fix inputs of the meet block */
931         set_irn_in(meet_block, j, ins);
932         DEL_ARR_F(ins);
933 }  /* apply */
934
935 /**
936  * Create a partition for a the end block.
937  *
938  * @param end_block  the end block
939  * @param env        the environment
940  */
941 static void partition_for_end_block(ir_node *end_block, environment_t *env)
942 {
943         partition_t *part = create_partition(end_block, env);
944         ir_node     *end;
945         int         i;
946
947         /* collect normal blocks */
948         for (i = get_Block_n_cfgpreds(end_block) - 1; i >= 0; --i) {
949                 ir_node *pred = get_Block_cfgpred(end_block, i);
950                 ir_node *block;
951                 block_t *bl;
952                 node_t  *node;
953
954                 mark_irn_visited(pred);
955
956                 block = get_nodes_block(pred);
957                 bl    = create_block(block, i, part, env);
958                 node  = create_node(pred, bl, env);
959
960                 bl->cf_root = node;
961         }
962
963         /* collect all no-return blocks */
964         end = get_irg_end(get_irn_irg(end_block));
965         for (i = get_End_n_keepalives(end) - 1; i >= 0; --i) {
966                 ir_node *ka    = get_End_keepalive(end, i);
967                 ir_node *block;
968                 block_t *bl;
969                 node_t  *node;
970
971                 if (! is_Call(ka))
972                         continue;
973                 mark_irn_visited(ka);
974
975                 /* found one */
976                 block = get_nodes_block(ka);
977                 bl    = create_block(block, -1, part, env);
978                 node  = create_node(ka, bl, env);
979
980                 bl->cf_root = node;
981         }
982
983         dump_partition("Created", part);
984 }  /* partition_for_end_block */
985
986 #ifdef GENERAL_SHAPE
987 /**
988  * Create a partition for a given meet block.
989  *
990  * @param block    the meet block
991  * @param preds    array of candidate predecessors
992  * @param n_preds  number of elements in preds
993  * @param env      the environment
994  */
995 static void partition_for_block(ir_node *block, pred_t preds[], int n_preds, environment_t *env)
996 {
997         partition_t *part = create_partition(block, env);
998         int         i;
999
1000         for (i = n_preds - 1; i >= 0; --i) {
1001                 ir_node *pred = preds[i].pred;
1002                 ir_node *block;
1003                 block_t *bl;
1004                 node_t  *node;
1005
1006                 mark_irn_visited(pred);
1007
1008                 block = get_nodes_block(pred);
1009                 bl    = create_block(block, preds[i].index, part, env);
1010                 node  = create_node(pred, bl, env);
1011
1012                 bl->cf_root = node;
1013         }
1014
1015         dump_partition("Created", part);
1016 }  /* partition_for_block */
1017
1018 /**
1019  * Walker: clear the links of all block phi lists and normal
1020  * links.
1021  */
1022 static void clear_phi_links(ir_node *irn, void *env)
1023 {
1024         (void) env;
1025         if (is_Block(irn)) {
1026                 set_Block_phis(irn, NULL);
1027                 set_irn_link(irn, NULL);
1028         }
1029 }  /* clear_phi_links */
1030
1031 /**
1032  * Walker, detect live-out nodes.
1033  */
1034 static void find_liveouts(ir_node *irn, void *ctx)
1035 {
1036         environment_t *env        = (environment_t*)ctx;
1037         ir_node       **live_outs = env->live_outs;
1038         ir_node       *this_block;
1039         int           i;
1040
1041         if (is_Block(irn))
1042                 return;
1043
1044         /* ignore Keep-alives */
1045         if (is_End(irn))
1046                 return;
1047
1048         this_block = get_nodes_block(irn);
1049
1050         if (is_Phi(irn)) {
1051                 /* update the Phi list */
1052                 add_Block_phi(this_block, irn);
1053         }
1054
1055         for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
1056                 ir_node *pred_block;
1057                 ir_node *pred = get_irn_n(irn, i);
1058                 int     idx   = get_irn_idx(pred);
1059
1060                 if (live_outs[idx] != NULL) {
1061                         /* already marked as live-out */
1062                         return;
1063                 }
1064
1065                 pred_block = get_nodes_block(pred);
1066                 /* Phi nodes always refer to live-outs */
1067                 if (is_Phi(irn) || this_block != pred_block) {
1068                         /* pred is a live-out */
1069                         live_outs[idx] = pred_block;
1070                 }
1071         }
1072 }  /* find_liveouts */
1073
1074 /**
1075  * Check if the current block is the meet block of its predecessors.
1076  */
1077 static void check_for_cf_meet(ir_node *block, void *ctx)
1078 {
1079         environment_t *env = (environment_t*)ctx;
1080         int           i, k, n;
1081         pred_t        *preds;
1082
1083         if (block == get_irg_end_block(get_irn_irg(block))) {
1084                 /* always create a partition for the end block */
1085                 partition_for_end_block(block, env);
1086                 return;
1087         }
1088
1089         n = get_Block_n_cfgpreds(block);
1090         if (n <= 1) {
1091                 /* Must have at least two predecessors */
1092                 return;
1093         }
1094
1095         NEW_ARR_A(pred_t, preds, n);
1096         k = 0;
1097         for (i = n - 1; i >= 0; --i) {
1098                 ir_node *pred = get_Block_cfgpred(block, i);
1099
1100                 /* pred must be a direct jump to us */
1101                 if (! is_Jmp(pred) && ! is_Raise(pred) && !is_Bad(pred))
1102                         continue;
1103
1104                 preds[k].pred  = pred;
1105                 preds[k].index = i;
1106                 ++k;
1107         }
1108
1109         if (k > 1)
1110                 partition_for_block(block, preds, k, env);
1111 }  /* check_for_cf_meet */
1112
1113 /**
1114  * Compare two nodes for root ordering.
1115  */
1116 static int cmp_nodes(const void *a, const void *b)
1117 {
1118         const ir_node *const *pa = (const ir_node*const*)a;
1119         const ir_node *const *pb = (const ir_node*const*)b;
1120         const ir_node  *irn_a  = *pa;
1121         const ir_node  *irn_b  = *pb;
1122         unsigned       code_a  = get_irn_opcode(irn_a);
1123         unsigned       code_b  = get_irn_opcode(irn_b);
1124         ir_mode        *mode_a, *mode_b;
1125         unsigned       idx_a, idx_b;
1126
1127         /* try opcode first */
1128         if (code_a != code_b)
1129                 return code_a - code_b;
1130
1131         /* try mode */
1132         mode_a = get_irn_mode(irn_a);
1133         mode_b = get_irn_mode(irn_b);
1134
1135         if (mode_a != mode_b)
1136                 return mode_a < mode_b ? -1 : +1;
1137
1138         /* last resort: index */
1139         idx_a = get_irn_idx(irn_a);
1140         idx_b = get_irn_idx(irn_b);
1141
1142         return (idx_a > idx_b) - (idx_a < idx_b);
1143 }  /* cmp_nodes */
1144
1145 /**
1146  * Add the roots to all blocks.
1147  */
1148 static void add_roots(ir_graph *irg, environment_t *env)
1149 {
1150         unsigned idx, n      = get_irg_last_idx(irg);
1151         ir_node  **live_outs = env->live_outs;
1152         block_t  *bl;
1153
1154         for (idx = 0; idx < n; ++idx) {
1155                 ir_node *block = live_outs[idx];
1156
1157                 if (block != NULL && is_Block(block)) {
1158                         block_t *bl = get_Block_entry(block);
1159
1160                         if (bl != NULL) {
1161                                 ir_node *irn = get_idx_irn(irg, idx);
1162
1163                                 if (!irn_visited_else_mark(irn)) {
1164                                         ARR_APP1(ir_node *, bl->roots, irn);
1165                                 }
1166                         }
1167                 }
1168         }
1169         /*
1170          * Now sort the roots to normalize them as good as possible.
1171      * Else, we will split identical blocks if we start which different roots.
1172          */
1173         for (bl = env->all_blocks; bl != NULL; bl = bl->all_next) {
1174                 size_t i, n = ARR_LEN(bl->roots);
1175
1176 #if 1
1177                 /* TODO: is this really needed? The roots are already in
1178                    idx-order by construction, which might be good enough. */
1179                 qsort(bl->roots, n, sizeof(bl->roots[0]), cmp_nodes);
1180 #endif
1181
1182                 DB((dbg, LEVEL_2, " Adding Roots for block %+F\n  ", bl->block));
1183                 /* ok, add them sorted */
1184                 for (i = 0; i < n; ++i) {
1185                         DB((dbg, LEVEL_2, "%+F, ", bl->roots[i]));
1186                         create_node(bl->roots[i], bl, env);
1187                 }
1188                 DB((dbg, LEVEL_2, "\n"));
1189                 DEL_ARR_F(bl->roots);
1190                 bl->roots = NULL;
1191         }
1192 }  /* add_roots */
1193 #endif /* GENERAL_SHAPE */
1194
1195 /* Combines congruent end blocks into one. */
1196 int shape_blocks(ir_graph *irg)
1197 {
1198         environment_t env;
1199         partition_t   *part;
1200         block_t       *bl;
1201         int           res, n;
1202
1203         /* register a debug mask */
1204         FIRM_DBG_REGISTER(dbg, "firm.opt.blocks");
1205
1206         DEBUG_ONLY(part_nr = 0);
1207         DB((dbg, LEVEL_1, "Shaping blocks for %+F\n", irg));
1208
1209         /* works better, when returns are placed at the end of the blocks */
1210         normalize_n_returns(irg);
1211
1212         obstack_init(&env.obst);
1213         INIT_LIST_HEAD(&env.partitions);
1214         INIT_LIST_HEAD(&env.ready);
1215         env.opcode2id_map  = new_set(cmp_opcode, iro_Last * 4);
1216
1217         n             = get_irg_last_idx(irg);
1218         env.live_outs = NEW_ARR_F(ir_node *, n);
1219         memset(env.live_outs, 0, sizeof(*env.live_outs) * n);
1220
1221         env.all_blocks = NULL;
1222
1223         ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
1224
1225 #ifdef GENERAL_SHAPE
1226         /*
1227          * Detect, which nodes are live-out only: these are the roots of our blocks.
1228          * Build phi lists.
1229          */
1230         irg_walk_graph(irg, clear_phi_links, find_liveouts, &env);
1231 #endif
1232
1233         ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
1234
1235         inc_irg_visited(irg);
1236 #ifdef GENERAL_SHAPE
1237         /*
1238          * Detect all control flow meets and create partitions.
1239          */
1240         irg_block_walk_graph(irg, NULL, check_for_cf_meet, &env);
1241
1242         /* add root nodes to the partition blocks */
1243         add_roots(irg, &env);
1244 #else
1245         partition_for_end_block(get_irg_end_block(irg), &env);
1246 #endif
1247
1248         propagate_live_troughs(&env);
1249         while (! list_empty(&env.partitions))
1250                 propagate(&env);
1251
1252         res = !list_empty(&env.ready);
1253         //if (res) dump_ir_block_graph(irg, "-before");
1254
1255
1256         list_for_each_entry(partition_t, part, &env.ready, part_list) {
1257                 dump_partition("Ready Partition", part);
1258                 apply(irg, part);
1259         }
1260         ir_free_resources(irg, IR_RESOURCE_IRN_VISITED | IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);
1261
1262         if (res) {
1263                 /* control flow changed */
1264                 set_irg_extblk_inconsistent(irg);
1265                 set_irg_doms_inconsistent(irg);
1266
1267                 /* Calls might be removed. */
1268                 set_trouts_inconsistent();
1269         }
1270
1271         for (bl = env.all_blocks; bl != NULL; bl = bl->all_next) {
1272                 DEL_ARR_F(bl->roots);
1273         }
1274
1275         DEL_ARR_F(env.live_outs);
1276         del_set(env.opcode2id_map);
1277         obstack_free(&env.obst, NULL);
1278
1279         return res;
1280 }  /* shape_blocks */
1281
1282 ir_graph_pass_t *shape_blocks_pass(const char *name)
1283 {
1284         return def_graph_pass_ret(name ? name : "shape_blocks", shape_blocks);
1285 }  /* shape_blocks_pass */