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