a5e4edc6fcfc81d5cff9d32b5702187aed9326b5
[libfirm] / ir / be / beirgmod.c
1 /**
2  * This file contains the following IRG modifications for be routines:
3  * - backend dominance information
4  * - SSA construction for a set of nodes
5  * - insertion of Perm nodes
6  * - empty block elimination
7  * - a simple dead node elimination (set inputs of unreachable nodes to BAD)
8  *
9  * Author:      Sebastian Hack, Daniel Grund, Matthias Braun, Christian Wuerdig
10  * Date:        04.05.2005
11  * Copyright:   (c) Universitaet Karlsruhe
12  * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
13  * CVS-Id:      $Id$
14  */
15 #ifdef HAVE_CONFIG_H
16 #include "config.h"
17 #endif
18
19 #include <stdlib.h>
20
21 #ifdef HAVE_MALLOC_H
22  #include <malloc.h>
23 #endif
24 #ifdef HAVE_ALLOCA_H
25  #include <alloca.h>
26 #endif
27
28 #include "hashptr.h"
29 #include "pdeq.h"
30 #include "pset.h"
31 #include "pmap.h"
32 #include "util.h"
33 #include "debug.h"
34
35 #include "irflag_t.h"
36 #include "ircons_t.h"
37 #include "irnode_t.h"
38 #include "ircons_t.h"
39 #include "irmode_t.h"
40 #include "irdom_t.h"
41 #include "iredges_t.h"
42 #include "irgopt.h"
43 #include "irprintf_t.h"
44 #include "irgwalk.h"
45
46 #include "be_t.h"
47 #include "bechordal_t.h"
48 #include "bearch.h"
49 #include "besched_t.h"
50 #include "belive_t.h"
51 #include "benode_t.h"
52 #include "beutil.h"
53 #include "beinsn_t.h"
54
55 #include "beirgmod.h"
56
57 #define DBG_MODULE "firm.be.irgmod"
58 #define DBG_LEVEL SET_LEVEL_0
59
60 /*
61   ____                  _
62  |  _ \  ___  _ __ ___ (_)_ __   __ _ _ __   ___ ___
63  | | | |/ _ \| '_ ` _ \| | '_ \ / _` | '_ \ / __/ _ \
64  | |_| | (_) | | | | | | | | | | (_| | | | | (_|  __/
65  |____/ \___/|_| |_| |_|_|_| |_|\__,_|_| |_|\___\___|
66  |  ___| __ ___  _ __ | |_(_) ___ _ __ ___
67  | |_ | '__/ _ \| '_ \| __| |/ _ \ '__/ __|
68  |  _|| | | (_) | | | | |_| |  __/ |  \__ \
69  |_|  |_|  \___/|_| |_|\__|_|\___|_|  |___/
70
71 */
72
73 /**
74  * The dominance frontier for a graph.
75  */
76 struct _be_dom_front_info_t {
77         pmap *df_map;         /**< A map, mapping every block to a list of its dominance frontier blocks. */
78         struct obstack obst;  /**< An obstack holding all the frontier data. */
79 };
80
81 /**
82  * A wrapper for get_Block_idom.
83  * This function returns the block itself, if the block is the start
84  * block. Returning NULL would make any != comparison true which
85  * suggests, that the start block is dominated by some other node.
86  * @param bl The block.
87  * @return The immediate dominator of the block.
88  */
89 static INLINE ir_node *get_idom(ir_node *bl)
90 {
91         ir_node *idom = get_Block_idom(bl);
92         return idom == NULL ? bl : idom;
93 }
94
95 /**
96  * Compute the dominance frontier for a given block.
97  *
98  * @param blk   the block where the calculation starts
99  *
100  * @return the list of all blocks in the dominance frontier of blk
101  */
102 static ir_node **compute_df(ir_node *blk, be_dom_front_info_t *info)
103 {
104         ir_node *c;
105         const ir_edge_t *edge;
106         ir_node **df_list = NEW_ARR_F(ir_node *, 0);
107         ir_node **df;
108         int len;
109
110         /* Add local dominance frontiers */
111         foreach_block_succ(blk, edge) {
112                 ir_node *y = edge->src;
113
114                 if (get_idom(y) != blk) {
115                         ARR_APP1(ir_node *, df_list, y);
116                 }
117         }
118
119         /*
120          * Go recursively down the dominance tree and add all blocks
121          * into the dominance frontiers of the children, which are not
122          * dominated by the given block.
123          */
124         for (c = get_Block_dominated_first(blk); c; c = get_Block_dominated_next(c)) {
125                 int i;
126                 ir_node **df_c_list = compute_df(c, info);
127
128                 for (i = ARR_LEN(df_c_list) - 1; i >= 0; --i) {
129                         ir_node *w = df_c_list[i];
130                         if (get_idom(w) != blk)
131                                 ARR_APP1(ir_node *, df_list, w);
132                 }
133         }
134
135         /* now copy the flexible array to the obstack */
136         len = ARR_LEN(df_list);
137         df = NEW_ARR_D(ir_node *, &info->obst, len);
138         memcpy(df, df_list, len * sizeof(df[0]));
139         DEL_ARR_F(df_list);
140
141         pmap_insert(info->df_map, blk, df);
142         return df;
143 }
144
145 be_dom_front_info_t *be_compute_dominance_frontiers(ir_graph *irg)
146 {
147         be_dom_front_info_t *info = xmalloc(sizeof(*info));
148
149         edges_assure(irg);
150         obstack_init(&info->obst);
151         info->df_map = pmap_create();
152         assure_doms(irg);
153         (void)compute_df(get_irg_start_block(irg), info);
154
155         return info;
156 }
157
158 void be_free_dominance_frontiers(be_dom_front_info_t *info)
159 {
160         obstack_free(&info->obst, NULL);
161         pmap_destroy(info->df_map);
162         free(info);
163 }
164
165 /* Get the dominance frontier of a block. */
166 ir_node **be_get_dominance_frontier(be_dom_front_info_t *info, ir_node *block)
167 {
168         return pmap_get(info->df_map, block);
169 }
170
171 static void determine_phi_blocks(pset *copies, pset *copy_blocks, pset *phi_blocks, be_dom_front_info_t *df_info)
172 {
173         ir_node *bl;
174         waitq *worklist = new_waitq();
175         FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
176
177         /*
178          * Fill the worklist queue and the rest of the orig blocks array.
179          */
180         for (bl = pset_first(copy_blocks); bl; bl = pset_next(copy_blocks)) {
181                 waitq_put(worklist, bl);
182         }
183
184         while (!pdeq_empty(worklist)) {
185                 ir_node *bl  = waitq_get(worklist);
186                 ir_node **df = be_get_dominance_frontier(df_info, bl);
187                 int i;
188
189                 ir_node *y;
190
191                 DBG((dbg, LEVEL_3, "dom front of %+F\n", bl));
192                 DEBUG_ONLY(
193                         for (i = ARR_LEN(df) - 1; i >= 0; --i)
194                                 DBG((dbg, LEVEL_3, "\t%+F\n", df[i]))
195                 );
196
197                 for (i = ARR_LEN(df) - 1; i >= 0; --i) {
198                         y = df[i];
199                         if (!pset_find_ptr(phi_blocks, y)) {
200                                 pset_insert_ptr(phi_blocks, y);
201
202                                 /*
203                                  * Clear the link field of a possible phi block, since
204                                  * the possibly created phi will be stored there. See,
205                                  * search_def()
206                                  */
207                                 set_irn_link(y, NULL);
208
209                                 if(!pset_find_ptr(copy_blocks, y))
210                                         waitq_put(worklist, y);
211                         }
212                 }
213         }
214
215         del_waitq(worklist);
216 }
217
218 /*
219   ____ ____    _
220  / ___/ ___|  / \
221  \___ \___ \ / _ \
222   ___) |__) / ___ \
223  |____/____/_/   \_\
224    ____                _                   _   _
225   / ___|___  _ __  ___| |_ _ __ _   _  ___| |_(_) ___  _ __
226  | |   / _ \| '_ \/ __| __| '__| | | |/ __| __| |/ _ \| '_ \
227  | |__| (_) | | | \__ \ |_| |  | |_| | (__| |_| | (_) | | | |
228   \____\___/|_| |_|___/\__|_|   \__,_|\___|\__|_|\___/|_| |_|
229
230 */
231
232 /**
233  * Find the copy of the given original node whose value is 'active'
234  * at a usage.
235  *
236  * The usage is given as a node and a position. Initially, the given operand
237  * points to a node for which copies were introduced. We have to find
238  * the valid copy for this usage. This is done by traversing the
239  * dominance tree upwards. If the usage is a phi function, we start
240  * traversing from the predecessor block which corresponds to the phi
241  * usage.
242  *
243  * @param usage       The node which uses the original node.
244  * @param pos         The position of the argument which corresponds to the original node.
245  * @param copies      A set containing all node which are copies from the original node.
246  * @param copy_blocks A set containing all basic block in which copies of the original node are located.
247  * @param phis        A set where all created phis are recorded.
248  * @param phi_blocks  A set of all blocks where Phis shall be inserted (iterated dominance frontier).
249  * @param mode        The mode for the Phi if one has to be created.
250  * @return            The valid copy for usage.
251  */
252 static ir_node *search_def(ir_node *usage, int pos, pset *copies, pset *copy_blocks, pset *phis, pset *phi_blocks, ir_mode *mode)
253 {
254         ir_node *curr_bl;
255         ir_node *start_irn;
256         FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
257
258         curr_bl = get_nodes_block(usage);
259
260         DBG((dbg, LEVEL_1, "Searching valid def for use %+F at pos %d\n", usage, pos));
261         /*
262          * If the usage is in a phi node, search the copy in the
263          * predecessor denoted by pos.
264          */
265         if(is_Phi(usage)) {
266                 curr_bl = get_Block_cfgpred_block(curr_bl, pos);
267                 start_irn = sched_last(curr_bl);
268         } else {
269                 start_irn = sched_prev(usage);
270         }
271
272         /*
273          * Traverse the dominance tree upwards from the
274          * predecessor block of the usage.
275          */
276         while(curr_bl != NULL) {
277                 ir_node *phim;
278
279             /*
280                  * If this block contains a copy, search the block
281                  * instruction by instruction. If nothing is found
282                  * search for a not scheduled PhiM.
283                  */
284                 if(pset_find_ptr(copy_blocks, curr_bl)) {
285                         ir_node *irn;
286
287                         /* Look at each instruction from last to first. */
288                         sched_foreach_reverse_from(start_irn, irn) {
289
290                                 /* Take the first copy we find. */
291                                 if(pset_find_ptr(copies, irn))
292                                         return irn;
293                         }
294
295                         for(phim = pset_first(copies); phim; phim = pset_next(copies)) {
296                                 if(!is_Phi(phim) || !(get_irn_mode(phim) == mode_M))
297                                         continue;
298
299                                 if(get_nodes_block(phim) == curr_bl) {
300                                         pset_break(copies);
301                                         return phim;
302                                 }
303                         }
304                 }
305
306                 if(pset_find_ptr(phi_blocks, curr_bl)) {
307                         ir_node *phi = get_irn_link(curr_bl);
308
309                         if(phi == NULL) {
310                                 int i, n_preds = get_irn_arity(curr_bl);
311                                 ir_graph *irg = get_irn_irg(curr_bl);
312                                 ir_node **ins = alloca(n_preds * sizeof(ins[0]));
313
314                                 for(i = 0; i < n_preds; ++i)
315                                         ins[i] = new_r_Bad(irg);
316
317                                 phi = new_r_Phi(irg, curr_bl, n_preds, ins, mode);
318                                 DBG((dbg, LEVEL_2, "\tcreating phi %+F in %+F\n", phi, curr_bl));
319
320                                 set_irn_link(curr_bl, phi);
321                                 if(mode != mode_M)
322                                         sched_add_after(curr_bl, phi);
323
324                                 for(i = 0; i < n_preds; ++i) {
325                                         ir_node *arg = search_def(phi, i, copies, copy_blocks, phis, phi_blocks, mode);
326                                         if(arg == NULL) {
327                                                 ir_node *irn;
328
329                                                 ir_fprintf(stderr, "no definition found for %+F at position %d\nCopies: ", phi, i);
330                                                 for(irn = pset_first(copies); irn; irn = pset_next(copies)) {
331                                                         ir_fprintf(stderr, "%+F ", irn);
332                                                 }
333                                                 ir_fprintf(stderr, "\n\n");
334                                                 assert(arg && "no definition found");
335                                         }
336                                         DBG((dbg, LEVEL_2, "\t\t%+F(%d) -> %+F\n", phi, i, arg));
337                                         set_irn_n(phi, i, arg);
338                                 }
339
340                                 if(phis != NULL)
341                                         pset_insert_ptr(phis, phi);
342                         }
343
344                         return phi;
345                 }
346
347                 /* If were not done yet, look in the immediate dominator */
348                 curr_bl = get_Block_idom(curr_bl);
349                 if(curr_bl)
350                         start_irn = sched_last(curr_bl);
351         }
352
353         return NULL;
354 }
355
356 static void fix_usages(pset *copies, pset *copy_blocks, pset *phi_blocks, pset *phis, pset *ignore_uses)
357 {
358         int n_outs = 0;
359         struct obstack obst;
360         ir_node *irn;
361         int i;
362         struct out {
363                 ir_node *irn;
364                 int pos;
365         } *outs;
366
367         FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
368
369         obstack_init(&obst);
370
371         /*
372          * Put all outs into an array.
373          * This is necessary, since the outs would be modified while
374          * iterating on them what could bring the outs module in trouble.
375          */
376         for (irn = pset_first(copies); irn; irn = pset_next(copies)) {
377                 const ir_edge_t *edge;
378                 foreach_out_edge(irn, edge) {
379                         ir_node *src = get_edge_src_irn(edge);
380                         /* ignore all users from ignore_uses or keep-alives (user is End node) */
381                         if (! pset_find_ptr(ignore_uses, src) && ! is_End(src)) {
382                                 struct out tmp;
383                                 tmp.irn = src;
384                                 tmp.pos = get_edge_src_pos(edge);
385                                 obstack_grow(&obst, &tmp, sizeof(tmp));
386                                 n_outs++;
387                         }
388                 }
389         }
390         outs = obstack_finish(&obst);
391
392         /*
393          * Search the valid def for each out and set it.
394          */
395         for(i = 0; i < n_outs; ++i) {
396                 ir_node *irn  = outs[i].irn;
397                 int pos       = outs[i].pos;
398                 ir_mode *mode = get_irn_mode(get_irn_n(irn, pos));
399
400                 ir_node *def;
401
402                 def = search_def(irn, pos, copies, copy_blocks, phis, phi_blocks, mode);
403                 DBG((dbg, LEVEL_2, "\t%+F(%d) -> %+F\n", irn, pos, def));
404
405                 if(def == NULL) {
406                         ir_fprintf(stderr, "no definition found for %+F at position %d\nCopies: ", irn, pos);
407                         for(irn = pset_first(copies); irn; irn = pset_next(copies)) {
408                                 ir_fprintf(stderr, "%+F ", irn);
409                         }
410                         ir_fprintf(stderr, "\n\n");
411                         assert(def && "no definition found");
412                 }
413                 set_irn_n(irn, pos, def);
414         }
415
416         obstack_free(&obst, NULL);
417 }
418
419 #if 0
420 /**
421  * Remove phis which are not necessary.
422  * During place_phi_functions() phi functions are put on the dominance
423  * frontiers blindly. However some of them will never be used (these
424  * have at least one predecessor which is NULL, see search_def() for
425  * this case). Since place_phi_functions() enters them into the
426  * schedule, we have to remove them from there.
427  *
428  * @param copies The set of all copies made (including the phi functions).
429  */
430 static void remove_odd_phis(pset *copies, pset *unused_copies)
431 {
432         ir_node *irn;
433
434         for(irn = pset_first(copies); irn; irn = pset_next(copies)) {
435                 if(is_Phi(irn)) {
436                         int i, n;
437                         int illegal = 0;
438
439                         assert(sched_is_scheduled(irn) && "phi must be scheduled");
440                         for(i = 0, n = get_irn_arity(irn); i < n && !illegal; ++i)
441                                 illegal = get_irn_n(irn, i) == NULL;
442
443                         if(illegal) {
444                                 for(i = 0, n = get_irn_arity(irn); i < n; ++i)
445                                         set_irn_n(irn, i, new_Bad());
446                                 sched_remove(irn);
447                         }
448                 }
449         }
450
451         for(irn = pset_first(unused_copies); irn; irn = pset_next(unused_copies)) {
452                 for(i = 0, n = get_irn_arity(irn); i < n; ++i)
453                         set_irn_n(irn, i, new_Bad());
454                 sched_remove(irn);
455         }
456 }
457 #endif /* if 0 */
458
459 void be_ssa_constr_phis_ignore(be_dom_front_info_t *info, be_lv_t *lv, int n, ir_node *nodes[], pset *phis, pset *ignore_uses)
460 {
461         pset *irns = pset_new_ptr(n);
462         int i;
463
464         for(i = 0; i < n; ++i)
465                 pset_insert_ptr(irns, nodes[i]);
466         be_ssa_constr_set_phis_ignore(info, lv, irns, phis, ignore_uses);
467         del_pset(irns);
468 }
469
470 void be_ssa_constr_ignore(be_dom_front_info_t *info, be_lv_t *lv, int n, ir_node *nodes[], pset *ignore_uses)
471 {
472         be_ssa_constr_phis_ignore(info, lv, n, nodes, NULL, ignore_uses);
473 }
474
475 void be_ssa_constr(be_dom_front_info_t *info, be_lv_t *lv, int n, ir_node *nodes[])
476 {
477         pset *empty_set = be_empty_set();
478         be_ssa_constr_ignore(info, lv, n, nodes, empty_set);
479 }
480
481 void be_ssa_constr_set_phis_ignore(be_dom_front_info_t *df, be_lv_t *lv, pset *nodes, pset *phis, pset *ignore_uses)
482 {
483         int n                  = pset_count(nodes);
484         pset *blocks           = pset_new_ptr(n);
485         pset *phi_blocks       = pset_new_ptr(n);
486         int save_optimize      = get_optimize();
487         int save_normalize     = get_opt_normalize();
488         int phis_set_created   = 0;
489         FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, DBG_MODULE);
490
491         ir_node *irn;
492
493         /* We need to collect the phi functions to compute their liveness. */
494         if(lv && !phis) {
495                 phis_set_created = 1;
496                 phis = pset_new_ptr_default();
497         }
498
499         DBG((dbg, LEVEL_1, "Introducing following copies for:\n"));
500
501         /* Fill the sets. */
502         for(irn = pset_first(nodes); irn; irn = pset_next(nodes)) {
503                 ir_node *bl = get_nodes_block(irn);
504                 pset_insert_ptr(blocks, bl);
505                 DBG((dbg, LEVEL_1, "\t%+F in %+F\n", irn, bl));
506         }
507
508         /*
509          * Disable optimization so that the phi functions do not
510          * disappear.
511          */
512         set_optimize(0);
513         set_opt_normalize(0);
514
515         /*
516          * Place the phi functions and reroute the usages.
517          */
518         determine_phi_blocks(nodes, blocks, phi_blocks, df);
519         fix_usages(nodes, blocks, phi_blocks, phis, ignore_uses);
520
521         /* reset the optimizations */
522         set_optimize(save_optimize);
523         set_opt_normalize(save_normalize);
524
525         del_pset(phi_blocks);
526         del_pset(blocks);
527
528         /* Recompute the liveness (if wanted) of the original nodes, the copies and the inserted phis. */
529         if(lv) {
530 #if 1
531                 foreach_pset(nodes, irn)
532                         be_liveness_update(lv, irn);
533
534                 foreach_pset(phis, irn)
535                         be_liveness_introduce(lv, irn);
536 #else
537                 be_liveness_recompute(lv);
538 #endif
539         }
540
541         /* Free the phi set of we created it. */
542         if(phis_set_created)
543                 del_pset(phis);
544
545 }
546
547 void be_ssa_constr_set_phis(be_dom_front_info_t *df, be_lv_t *lv, pset *nodes, pset *phis)
548 {
549         pset *empty_set = be_empty_set();
550         be_ssa_constr_set_phis_ignore(df, lv, nodes, phis, empty_set);
551 }
552
553 void be_ssa_constr_set_ignore(be_dom_front_info_t *df, be_lv_t *lv, pset *nodes, pset *ignore_uses)
554 {
555         be_ssa_constr_set_phis_ignore(df, lv, nodes, NULL, ignore_uses);
556 }
557
558 void be_ssa_constr_set(be_dom_front_info_t *info, be_lv_t *lv, pset *nodes)
559 {
560         pset *empty_set = be_empty_set();
561         be_ssa_constr_set_ignore(info, lv, nodes, empty_set);
562 }
563
564 /*
565   ___                     _     ____
566  |_ _|_ __  ___  ___ _ __| |_  |  _ \ ___ _ __ _ __ ___
567   | || '_ \/ __|/ _ \ '__| __| | |_) / _ \ '__| '_ ` _ \
568   | || | | \__ \  __/ |  | |_  |  __/  __/ |  | | | | | |
569  |___|_| |_|___/\___|_|   \__| |_|   \___|_|  |_| |_| |_|
570
571 */
572
573 ir_node *insert_Perm_after(const arch_env_t *arch_env,
574                                                    be_lv_t *lv,
575                                                    const arch_register_class_t *cls,
576                                                    be_dom_front_info_t *dom_front,
577                                                    ir_node *pos)
578 {
579         ir_node *bl     = is_Block(pos) ? pos : get_nodes_block(pos);
580         ir_graph *irg   = get_irn_irg(bl);
581         pset *live      = pset_new_ptr_default();
582         FIRM_DBG_REGISTER(firm_dbg_module_t *dbg, "be.node");
583
584         ir_node *curr, *irn, *perm, **nodes;
585         int i, n;
586
587         DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos));
588
589         be_liveness_nodes_live_at(lv, arch_env, cls, pos, live);
590
591         n = pset_count(live);
592
593         if(n == 0) {
594                 del_pset(live);
595                 return NULL;
596         }
597
598         nodes = xmalloc(n * sizeof(nodes[0]));
599
600         DBG((dbg, LEVEL_1, "live:\n"));
601         for(irn = pset_first(live), i = 0; irn; irn = pset_next(live), i++) {
602                 DBG((dbg, LEVEL_1, "\t%+F\n", irn));
603                 nodes[i] = irn;
604         }
605         del_pset(live);
606
607         perm = be_new_Perm(cls, irg, bl, n, nodes);
608         sched_add_after(pos, perm);
609         free(nodes);
610
611         curr = perm;
612         for (i = 0; i < n; ++i) {
613                 ir_node *copies[2];
614                 ir_node *perm_op = get_irn_n(perm, i);
615                 const arch_register_t *reg = arch_get_irn_register(arch_env, perm_op);
616
617                 ir_mode *mode = get_irn_mode(perm_op);
618                 ir_node *proj = new_r_Proj(irg, bl, perm, mode, i);
619                 arch_set_irn_register(arch_env, proj, reg);
620
621                 sched_add_after(curr, proj);
622                 curr = proj;
623
624                 copies[0] = perm_op;
625                 copies[1] = proj;
626
627                 be_ssa_constr(dom_front, lv, 2, copies);
628         }
629
630         return perm;
631 }
632
633 struct _elr_closure_t {
634         struct obstack obst;
635         const be_chordal_env_t *cenv;
636 };
637
638 static void elr_split_walker(ir_node *bl, void *data)
639 {
640         struct _elr_closure_t *c     = data;
641         const be_chordal_env_t *cenv = c->cenv;
642         const arch_env_t *aenv       = cenv->birg->main_env->arch_env;
643         be_lv_t *lv                  = cenv->birg->lv;
644         be_dom_front_info_t *dom_front = cenv->birg->dom_front;
645         be_insn_t *insn;
646         be_insn_env_t ie;
647
648         be_insn_env_init(&ie, cenv->birg, cenv->cls, &c->obst);
649
650         for(insn = be_scan_insn(&ie, sched_first(bl)); !is_Block(insn->irn); insn = be_scan_insn(&ie, insn->next_insn)) {
651                 ir_node *pred = sched_prev(insn->irn);
652                 if(!is_Block(pred) && !is_Phi(insn->irn))
653                         insert_Perm_after(aenv, lv, cenv->cls, dom_front, insn->irn);
654         }
655 }
656
657 void extreme_liverange_splitting(struct _be_chordal_env_t *cenv)
658 {
659         struct _elr_closure_t c;
660         be_lv_t *lv = cenv->birg->lv;
661
662         c.cenv = cenv;
663         obstack_init(&c.obst);
664         be_liveness_recompute(lv);
665         irg_block_walk_graph(cenv->irg, elr_split_walker, NULL, &c);
666         be_liveness_recompute(lv);
667         obstack_free(&c.obst, NULL);
668 }
669
670 /**
671  * Post-block-walker: Find blocks containing only one jump and
672  * remove them.
673  */
674 static void remove_empty_block(ir_node *block, void *data) {
675         const ir_edge_t *edge, *next;
676         ir_node *node;
677         int *changed = data;
678         ir_node *jump = NULL;
679
680         assert(is_Block(block));
681
682         if (get_Block_n_cfgpreds(block) != 1)
683                 return;
684
685         sched_foreach(block, node) {
686                 if (! is_Jmp(node))
687                         return;
688                 if (jump != NULL) {
689                         /* we should never have 2 jumps in a block */
690                         assert(0 && "We should never have 2 jumps in a block");
691                         return;
692                 }
693                 jump = node;
694         }
695
696         if (jump == NULL)
697                 return;
698
699         node = get_Block_cfgpred(block, 0);
700         foreach_out_edge_safe(jump, edge, next) {
701                 ir_node *block = get_edge_src_irn(edge);
702                 int     pos    = get_edge_src_pos(edge);
703
704                 set_irn_n(block, pos, node);
705         }
706
707         set_Block_cfgpred(block, 0, new_Bad());
708         sched_remove(jump);
709         *changed = 1;
710 }
711
712 /* removes basic blocks that just contain a jump instruction */
713 int be_remove_empty_blocks(ir_graph *irg) {
714         int changed = 0;
715
716         irg_block_walk_graph(irg, remove_empty_block, NULL, &changed);
717         if (changed) {
718                 /* invalidate analysis info */
719                 set_irg_doms_inconsistent(irg);
720                 set_irg_extblk_inconsistent(irg);
721                 set_irg_outs_inconsistent(irg);
722         }
723         return changed;
724 }
725
726 typedef struct _be_dead_out_env_t {
727         ir_graph *irg;
728         bitset_t *reachable;
729         DEBUG_ONLY(firm_dbg_module_t *dbg);
730 } be_dead_out_env_t;
731
732 /**
733  * Check if @p node has dead users, i.e. they are reachable only via outedges from @p node.
734  * Set all ins of those users to BAD.
735  */
736 static void kill_dead_out(ir_node *node, be_dead_out_env_t *env) {
737         ir_graph        *irg = env->irg;
738         const ir_edge_t *edge, *tmp_edge;
739
740         if (irn_visited(node))
741                 return;
742         mark_irn_visited(node);
743
744         /* check all out edges */
745         foreach_out_edge_safe(node, edge, tmp_edge) {
746                 ir_node *src = get_edge_src_irn(edge);
747
748                 if (! bitset_is_set(env->reachable, get_irn_idx(src))) {
749                         /* BEWARE: do not kill anchors or TLS */
750                         if (src != get_irg_globals(irg) && src != get_irg_tls(irg)) {
751                                 DBG((env->dbg, LEVEL_1, "killing %+F, only reachable from %+F\n", src, node));
752                                 be_kill_node(src);
753                         }
754                         continue;
755                 }
756
757                 /* descent */
758                 if (! is_Block(src)) {
759                         kill_dead_out(src, env);
760                 }
761         }
762 }
763
764 static void set_reachable(ir_node *node, void *data) {
765         bitset_t *reachable = data;
766         bitset_set(reachable, get_irn_idx(node));
767 }
768
769 /**
770  * Set input of all nodes only reachable via out edges to BAD.
771  */
772 void be_kill_dead_nodes(ir_graph *irg) {
773         be_dead_out_env_t env;
774
775         env.irg       = irg;
776         env.reachable = bitset_alloca(get_irg_last_idx(irg));
777         FIRM_DBG_REGISTER(env.dbg, "firm.be.killdead");
778
779         /* collect all reachable nodes */
780         irg_walk_in_or_dep_graph(irg, set_reachable, NULL, env.reachable);
781
782         /* this is a forward walk (start -> end) */
783         inc_irg_visited(irg);
784         kill_dead_out(get_irg_start(irg), &env);
785 }