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