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