Heavy changes:
[libfirm] / ir / opt / ifconv.c
1 /**
2  * If conversion.
3  * Make Mux nodes from Conds where it its possible.
4  * @author Sebastian Hack
5  * @date 4.2.2005
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <alloca.h>
11
12 #include "irgraph_t.h"
13 #include "irnode_t.h"
14 #include "iropt_t.h"
15 #include "irgmod.h"
16 #include "irmode_t.h"
17 #include "ircons_t.h"
18 #include "irdom_t.h"
19
20 #include "ifconv.h"
21 #include "irflag_t.h"
22
23 #include "debug.h"
24 #include "obst.h"
25 #include "set.h"
26 #include "bitset.h"
27 #include "bitfiddle.h"
28
29 #define MAX_DEPTH 4
30
31 /*
32  * Mux optimization routines.
33  */
34
35 #if 0
36 static ir_node *local_optimize_mux(ir_node *mux)
37 {
38         int i, n;
39         ir_node *res = mux;
40   ir_node *sel = get_Mux_sel(mux);
41         ir_node *cmp = skip_Proj(sel);
42
43         /* Optimize the children  */
44         for(i = 1, n = get_irn_arity(mux); i < n; ++i) {
45                 ir_node *operand = get_irn_n(mux, i);
46                 if(get_irn_op(operand) == op_Mux)
47                         optimize_mux(operand);
48         }
49
50         /* If we have no cmp above the mux, get out. */
51         if(is_Proj(sel) && get_irn_mode(sel) == mode_b && get_irn_opcode(cmp) == iro_Cmp) {
52
53                 pn_Cmp cc = get_Proj_proj(sel);
54                 ir_mode *mode = get_irn_mode(mux);
55                 ir_node *block = get_nodes_block(n);
56                 ir_node *cmp_left = get_Cmp_left(cmp);
57                 ir_node *cmp_right = get_Cmp_right(cmp);
58                 ir_node *mux_true = get_Mux_true(mux);
59                 ir_node *mux_false = get_Mux_false(mux);
60
61                 /*
62                  * Check for comparisons with signed integers.
63                  */
64                 if(mode_is_int(mode)                                    /* We need an integral mode */
65                                 && mode_is_signed(mode)   /* which is signed */
66                                 && cc == Lt) {                                          /* and have to compare for < */
67
68                         /*
69                          * Mux(x:T < 0, -1, 0) -> Shrs(x, sizeof_bits(T) - 1)
70                          * Conditions:
71                          * T must be signed.
72                          */
73                         if(classify_Const(cmp_right) == CNST_NULL
74                                 && classify_Const(mux_true) == CNST_ALL_ONE
75                                 && classify_Const(mux_false) == CNST_NULL) {
76
77                                 ir_mode *u_mode = find_unsigned_mode(mode);
78
79                                 res = new_r_Shrs(current_ir_graph, block, cmp_left,
80                                                 new_r_Const_long(current_ir_graph, block, u_mode,
81                                                         get_mode_size_bits(mode) - 1),
82                                                 mode);
83                         }
84
85                         /*
86                          * Mux(0 < x:T, 1, 0) -> Shr(-x, sizeof_bits(T) - 1)
87                          * Conditions:
88                          * T must be signed.
89                          */
90                         else if(classify_Const(cmp_left) == CNST_NULL
91                                 && classify_Const(mux_true) == CNST_ONE
92                                 && classify_Const(mux_false) == CNST_NULL) {
93
94                                 ir_mode *u_mode = find_unsigned_mode(mode);
95
96                                 res = new_r_Shr(current_ir_graph, block,
97
98                                                 /* -x goes to 0 - x in Firm (cmp_left is 0, see the if) */
99                                                 new_r_Sub(current_ir_graph, block, cmp_left, cmp_right, mode),
100
101                                                 /* This is sizeof_bits(T) - 1 */
102                                                 new_r_Const_long(current_ir_graph, block, u_mode,
103                                                         get_mode_size_bits(mode) - 1),
104                                                 mode);
105                         }
106                 }
107         }
108
109         return res;
110 }
111 #endif
112
113 /**
114  * check, if a node is const and return its tarval or
115  * return a default tarval.
116  * @param cnst The node whose tarval to get.
117  * @param or The alternative tarval, if the node is no Const.
118  * @return The tarval of @p cnst, if the node is Const, @p otherwise.
119  */
120 static tarval *get_value_or(ir_node *cnst, tarval *or)
121 {
122         return get_irn_op(cnst) == op_Const ? get_Const_tarval(cnst) : or;
123 }
124
125
126 /**
127  * Try to optimize nested muxes into a dis- or conjunction
128  * of two muxes.
129  * @param mux The parent mux, which has muxes as operands.
130  * @return The replacement node for this mux. If the optimization is
131  * successful, this might be an And or Or node, if not, its the mux
132  * himself.
133  */
134 static ir_node *optimize_mux_chain(ir_node *mux)
135 {
136         int i;
137         ir_node *res;
138         ir_node *ops[2];
139         ir_mode *mode = get_irn_mode(mux);
140         tarval *null;
141         tarval *minus_one;
142
143         /*
144          * If we have no mux, or its mode is not integer, we
145          * can return.
146          */
147         if(get_irn_op(mux) != op_Mux || !mode_is_int(mode))
148                 return mux;
149
150         res = mux;
151         null = get_tarval_null(mode);
152         minus_one = tarval_sub(null, get_tarval_one(mode));
153
154         ops[0] = get_Mux_false(mux);
155         ops[1] = get_Mux_true(mux);
156
157         for(i = 0; i < 2; ++i) {
158                 ir_node *a, *b, *d;
159                 tarval *tva, *tvb, *tvd;
160                 ir_node *child_mux;
161
162                 /*
163                  * A mux operand at the first position can be factored
164                  * out, if the operands fulfill several conditions:
165                  *
166                  * mux(c1, mux(c2, a, b), d)
167                  *
168                  * This can be made into:
169                  * 1) mux(c1, 0, d) | mux(c2, a, b)
170                  *    if a | d == d and b | d == d
171                  *
172                  * 2) mux(c1, -1, d) & mux(c2, a, b)
173                  *    if a & d == d and a & b == b
174                  */
175                 if(get_irn_op(ops[i]) == op_Mux) {
176
177                         child_mux = ops[i];
178                         a = get_Mux_false(child_mux);
179                         b = get_Mux_true(child_mux);
180                         d = ops[1 - i];
181
182                         /* Try the or stuff */
183                         tva = get_value_or(a, minus_one);
184                         tvb = get_value_or(b, minus_one);
185                         tvd = get_value_or(d, null);
186
187                         if(tarval_cmp(tarval_or(tva, tvd), tvd) == pn_Cmp_Eq
188                                         && tarval_cmp(tarval_or(tvb, tvd), tvd) == pn_Cmp_Eq) {
189
190                                 ops[i] = new_Const(mode, null);
191                                 res = new_r_Or(current_ir_graph, get_nodes_block(mux),
192                                                 mux, child_mux, mode);
193                                 break;
194                         }
195
196                         /* If the or didn't go, try the and stuff */
197                         tva = get_value_or(a, null);
198                         tvb = get_value_or(b, null);
199                         tvd = get_value_or(d, minus_one);
200
201                         if(tarval_cmp(tarval_and(tva, tvd), tvd) == pn_Cmp_Eq
202                                         && tarval_cmp(tarval_and(tvb, tvd), tvd) == pn_Cmp_Eq) {
203
204                                 ops[i] = new_Const(mode, minus_one);
205                                 res = new_r_And(current_ir_graph, get_nodes_block(mux),
206                                                 mux, child_mux, mode);
207                                 break;
208                         }
209                 }
210         }
211
212         /* recursively optimize nested muxes. */
213         set_irn_n(mux, 1, optimize_mux_chain(ops[0]));
214         set_irn_n(mux, 2, optimize_mux_chain(ops[1]));
215
216         return res;
217 }
218
219
220 /***********************************************************
221  * The If conversion itself.
222  ***********************************************************/
223
224 /**
225  * Default options.
226  */
227 static opt_if_conv_info_t default_info = {
228         4
229 };
230
231 /** The debugging module. */
232 static firm_dbg_module_t *dbg;
233
234 /**
235  * A simple check for sde effects upton an opcode of a ir node.
236  * @param irn The ir node to check,
237  * @return 1 if the opcode itself may produce side effects, 0 if not.
238  */
239 static INLINE int has_side_effects(const ir_node *irn)
240 {
241         opcode opc = get_irn_opcode(irn);
242
243         if(opc == iro_Cmp)
244                 return 0;
245
246         return !mode_is_datab(get_irn_mode(irn));
247 }
248
249 /**
250  * Decdies, if a given expression and its subexpressions
251  * (to certain, also given extent) can be moved to a block.
252  * @param expr The expression to examine.
253  * @param block The block where the expression should go.
254  * @param depth The current depth, passed recursively. Use 0 for
255  * non-recursive calls.
256  * @param max_depth The maximum depth to which the expression should be
257  * examined.
258  */
259 static int _can_move_to(ir_node *expr, ir_node *dest_block, int depth, int max_depth)
260 {
261         int i, n;
262         int res = 1;
263         ir_node *expr_block = get_nodes_block(expr);
264
265
266         /*
267          * If we are forced to look too deep into the expression,
268          * treat it like it could not be moved.
269          */
270         if(depth >= max_depth) {
271                 res = 0;
272                 goto end;
273         }
274
275         /*
276          * If the block of the expression dominates the specified
277          * destination block, it does not matter if the expression
278          * has side effects or anything else. It is executed on each
279          * path the destination block is reached.
280          */
281         if(block_dominates(expr_block, dest_block))
282                 goto end;
283
284         /*
285          * We cannot move phis!
286          */
287         if(is_Phi(expr)) {
288                 res = 0;
289                 goto end;
290         }
291
292         /*
293          * This should be superflous and could be converted into a assertion.
294          * The destination block _must_ dominate the block of the expression,
295          * else the expression could be used without its definition.
296          */
297         if(!block_dominates(dest_block, expr_block)) {
298                 res = 0;
299                 goto end;
300         }
301
302         /*
303          * Surely, if the expression does not have a data mode, it is not
304          * movable. Perhaps onw should also test the floating property of
305          * the opcode/node.
306          */
307         if(has_side_effects(expr)) {
308                 res = 0;
309                 goto end;
310         }
311
312         /*
313          * If the node looks alright so far, look at its operands and
314          * check them out. If one of them cannot be moved, this one
315          * cannot be moved either.
316          */
317         for(i = 0, n = get_irn_arity(expr); i < n; ++i) {
318                 ir_node *op = get_irn_n(expr, i);
319                 int new_depth = is_Proj(op) ? depth : depth + 1;
320                 if(!_can_move_to(op, dest_block, new_depth, max_depth)) {
321                         res = 0;
322                         goto end;
323                 }
324         }
325
326 end:
327         DBG((dbg, LEVEL_5, "\t\t\t%Dcan move to %n: %d\n", depth, expr, res));
328
329         return res;
330 }
331
332 /**
333  * Convenience function for _can_move_to.
334  * Checks, if an expression can be moved to another block. The check can
335  * be limited to a expression depth meaning if we need to crawl in
336  * deeper into an expression than a given threshold to examine if
337  * it can be moved, the expression is rejected and the test returns
338  * false.
339  * @param expr The expression to check for.
340  * @param dest_block The destination block you want @p expr to be.
341  * @param max_depth The maximum depth @p expr should be investigated.
342  * @return 1, if the expression can be moved to the destination block,
343  * 0 if not.
344  */
345 static INLINE int can_move_to(ir_node *expr, ir_node *dest_block, int max_depth)
346 {
347         return _can_move_to(expr, dest_block, 0, max_depth);
348 }
349
350 static void move_to(ir_node *expr, ir_node *dest_block)
351 {
352         int i, n;
353         ir_node *expr_block = get_nodes_block(expr);
354
355         /*
356          * If we reached the dominator, we are done.
357          * We will never put code through the dominator
358          */
359         if(block_dominates(expr_block, dest_block))
360                 return;
361
362         for(i = 0, n = get_irn_arity(expr); i < n; ++i)
363                 move_to(get_irn_n(expr, i), dest_block);
364
365         set_nodes_block(expr, dest_block);
366 }
367
368 static ir_node *common_idom(ir_node *b1, ir_node *b2)
369 {
370         if(block_dominates(b1, b2))
371                 return b1;
372         else if(block_dominates(b2, b1))
373                 return b2;
374         else {
375                 ir_node *p;
376
377                 for(p = b1; !block_dominates(p, b2); p = get_Block_idom(p));
378                 return p;
379         }
380 }
381
382 /**
383  * Information about a cond node.
384  */
385 typedef struct _cond_t {
386         ir_node *cond;                                  /**< The cond node. */
387         ir_node *mux;                                           /**< The mux node, that will be generated for this cond. */
388         struct list_head list;  /**< List head which is used for queueing this cond
389                                                                                                                 into the cond bunch it belongs to. */
390         unsigned in_list : 1;
391         struct _cond_t *link;
392         long visited_nr;
393
394         /**
395          * Information about the both 'branches'
396          * (true and false), the cond creates.
397          */
398         struct {
399                 int pos;                                                /**< Number of the predecessor of the
400                                                                                                         phi block by which this branch is
401                                                                                                         reached. It is -1, if this branch is
402                                                                                                         only reached through another cond. */
403
404                 ir_node *masked_by;     /**< If this cond's branch is only reached
405                                                                                                         through another cond, we store this
406                                                                                                         cond ir_node here. */
407         } cases[2];
408 } cond_t;
409
410 static INLINE cond_t *get_cond(ir_node *irn, set *cond_set)
411 {
412         cond_t templ;
413
414         templ.cond = irn;
415         return set_find(cond_set, &templ, sizeof(templ), HASH_PTR(templ.cond));
416 }
417
418
419 typedef void (cond_walker_t)(cond_t *cond, void *env);
420
421 static void _walk_conds(cond_t *cond, cond_walker_t *pre, cond_walker_t *post,
422                 long visited_nr, set *cond_set, void *env)
423 {
424         int i;
425
426         if(cond->visited_nr >= visited_nr)
427                 return;
428
429         cond->visited_nr = visited_nr;
430
431         if(pre)
432                 pre(cond, env);
433
434         for(i = 0; i < 2; ++i) {
435                 cond_t *c = get_cond(cond->cases[i].masked_by, cond_set);
436
437                 if(c)
438                         _walk_conds(c, pre, post, visited_nr, cond_set, env);
439         }
440
441         if(post)
442                 post(cond, env);
443 }
444
445 static void walk_conds(cond_t *cond, cond_walker_t *pre, cond_walker_t *post,
446                 set *cond_set, void *env)
447 {
448         static long visited_nr = 0;
449
450         _walk_conds(cond, pre, post, ++visited_nr, cond_set, env);
451 }
452
453 static void link_conds(cond_t *cond, void *env)
454 {
455         cond_t **ptr = (cond_t **) env;
456
457         cond->link = *ptr;
458         *ptr = cond;
459 }
460
461 /**
462  * Compare two conds for use in a firm set.
463  * Two cond_t's are equal, if they designate the same cond node.
464  * @param a A cond_t.
465  * @param b Another one.
466  * @param size Not used.
467  * @return 0 (!) if they are equal, != 0 otherwise.
468  */
469 static int cond_cmp(const void *a, const void *b, size_t size)
470 {
471         const cond_t *x = a;
472         const cond_t *y = b;
473         return x->cond != y->cond;
474 }
475
476 /**
477  * Information about conds which can be made to muxes.
478  * Instances of this struct are attached to the link field of
479  * blocks in which phis are located.
480  */
481 typedef struct _cond_info_t {
482         struct list_head list;                  /**< Used to list all of these structs per class. */
483
484         struct list_head roots;                 /**< A list of non-depending conds. Two conds are
485                                                                                                                                 independent, if yot can not reach the one from the
486                                                                                                                                 other (all conds in this list have to dominate the
487                                                                                                                                 block this struct is attached to. */
488
489         set *cond_set;                                                  /**< A set of all dominating reachable conds. */
490 } cond_info_t;
491
492 /**
493  * @see find_conds.
494  */
495 static void _find_conds(ir_node *irn, ir_node *base_block, long visited_nr,
496                 ir_node *dominator, ir_node *masked_by, int pos, int depth, cond_info_t *ci)
497 {
498         ir_node *block;
499
500         block = get_nodes_block(irn);
501
502         if(block_dominates(dominator, block)) {
503                 ir_node *cond = NULL;
504                 int i, n;
505
506                 /* check, if we're on a ProjX
507                  *
508                  * Further, the ProjX/Cond block must dominate the base block
509                  * (the block with the phi in it), otherwise, the Cond
510                  * is not affecting the phi so that a mux can be inserted.
511                  */
512                 if(is_Proj(irn) && get_irn_mode(irn) == mode_X) {
513
514                         int proj = get_Proj_proj(irn);
515                         cond = get_Proj_pred(irn);
516
517                         /* Check, if the pred of the proj is a Cond
518                          * with a Projb as selector.
519                          */
520                         if(get_irn_opcode(cond) == iro_Cond
521                                         && get_irn_mode(get_Cond_selector(cond)) == mode_b) {
522
523                                 cond_t *res, c;
524
525                                 memset(&c, 0, sizeof(c));
526                                 c.cond = cond;
527                                 INIT_LIST_HEAD(&c.list);
528                                 c.cases[0].pos = -1;
529                                 c.cases[1].pos = -1;
530
531                                 /* get or insert the cond info into the set. */
532                                 res = set_insert(ci->cond_set, &c, sizeof(c), HASH_PTR(cond));
533
534                                 if(!res->in_list) {
535                                         res->in_list = 1;
536                                         list_add(&res->list, &ci->roots);
537                                 }
538
539                                 /*
540                                  * Link it to the cond ir_node. We need that later, since
541                                  * one cond masks the other we want to retreive the cond_t
542                                  * data from the masking cond ir_node.
543                                  */
544                                 set_irn_link(cond, res);
545
546                                 /*
547                                  * Set masked by (either NULL or another cond node.
548                                  * If this cond is truly masked by another one, set
549                                  * the position of the actually investigated branch
550                                  * to -1. Since the cond is masked by another one,
551                                  * there could be more ways from the start block
552                                  * to this branch, so we choose -1.
553                                  */
554                                 res->cases[proj].masked_by = masked_by;
555                                 if(!masked_by)
556                                         res->cases[proj].pos = pos;
557
558                                 /*
559                                  * Since the masked_by nodes masks a cond, remove it from the
560                                  * root list of the conf trees.
561                                  */
562                                 else {
563                                         cond_t *m = get_cond(masked_by, ci->cond_set);
564                                         struct list_head *list = &m->list;
565
566                                         /*
567                                          * If this cond was not removed before,
568                                          * remove it now from the list.
569                                          */
570                                         if(!list_empty(list))
571                                                 list_del_init(list);
572                                 }
573
574                                 DBG((dbg, LEVEL_5, "%{firm:indent}found cond %n (%s branch) "
575                                                         "for pos %d in block %n reached by %n\n",
576                                                         depth, cond, get_Proj_proj(irn) ? "true" : "false", pos, block, masked_by));
577                         }
578
579                         /*
580                          * We set cond to NULL if the cond was an switch cond, since it is
581                          * passed (as the masked_by argument) to recursive calls to this
582                          * function. We do not consider switch conds as masking conds for
583                          * other conds.
584                          */
585                         else
586                                 cond = NULL;
587                 }
588
589                 if(get_Block_block_visited(block) < visited_nr) {
590
591                         set_Block_block_visited(block, visited_nr);
592
593                         /* Search recursively from this cond. */
594                         for(i = 0, n = get_irn_arity(block); i < n; ++i) {
595                                 ir_node *pred = get_irn_n(block, i);
596
597                                 /*
598                                  * If the depth is 0 (the first recursion), we set the pos to
599                                  * the current viewed predecessor, else we adopt the position
600                                  * as given by the caller. We also increase the depth for the
601                                  * recursively called functions.
602                                  */
603                                 _find_conds(pred, base_block, visited_nr, dominator, cond, pos, depth + 1, ci);
604                         }
605                 }
606         }
607 }
608
609
610 /**
611  * A convenience function for _find_conds.
612  * It sets some parameters needed for recursion to appropriate start
613  * values. Always use this function.
614  * @param irn The node to start looking for conds from. This might
615  *      be the phi node we are investigating.
616  * @param conds The set to record the found conds in.
617  */
618 static INLINE void find_conds(ir_node *irn, cond_info_t *ci)
619 {
620         int i, n;
621         long visited_nr;
622         ir_node *block = get_nodes_block(irn);
623
624         inc_irg_block_visited(current_ir_graph);
625         visited_nr = get_irg_block_visited(current_ir_graph);
626
627         for(i = 0, n = get_irn_arity(block); i < n; ++i) {
628                 ir_node *pred = get_irn_n(block, i);
629                 ir_node *pred_block = get_nodes_block(pred);
630                 ir_node *dom = get_Block_idom(pred_block);
631
632                 /*
633                  * If the pred_block is the start block, its idom is NULL
634                  * so we treat the block itself as its immediate dominator.
635                  */
636                 if(dom == NULL)
637                         dom = pred_block;
638
639                 _find_conds(pred, pred_block, visited_nr, dom, NULL, i, 0, ci);
640         }
641 }
642
643
644 /**
645  * Make the mux for a given cond.
646  * @param phi The phi node which shall be replaced by a mux.
647  * @param dom The block where the muxes shall be placed.
648  * @param cond The cond information.
649  * @return The mux node made for this cond.
650  */
651 static ir_node *make_mux_on_demand(ir_node *phi, ir_node *dom, cond_t *cond, set *cond_set)
652 {
653         int i;
654         ir_node *projb = get_Cond_selector(cond->cond);
655         ir_node *operands[2];
656
657         operands[0] = NULL;
658         operands[1] = NULL;
659         cond->mux = NULL;
660
661         for(i = 0; i < 2; ++i) {
662
663                 /*
664                  * If this cond branch is masked by another cond, make the mux
665                  * for that cond first, since the mux for this cond takes
666                  * it as an operand.
667                  */
668                 if(cond->cases[i].masked_by) {
669                         cond_t templ;
670                         cond_t *masking_cond;
671
672                         templ.cond = cond->cases[i].masked_by;
673                         masking_cond = set_find(cond_set, &templ, sizeof(templ), HASH_PTR(templ.cond));
674
675                         operands[i] = make_mux_on_demand(phi, dom, masking_cond, cond_set);
676                 }
677
678                 /*
679                  * If this cond branch is not masked by another cond, take
680                  * the corresponding phi operand as an operand to the mux.
681                  */
682                 else {
683                         if(cond->cases[i].pos >= 0)
684                                 operands[i] = get_irn_n(phi, cond->cases[i].pos);
685                 }
686         }
687
688         /*
689          * Move the operands to the dominator block if the cond
690          * made sense. Some conds found are not suitable for making a mux
691          * out of them, since one of their branches cannot be reached from
692          * the phi block. In that case we do not make a mux and return NULL.
693          */
694         if(operands[0] && operands[1]) {
695                 move_to(operands[0], dom);
696                 move_to(operands[1], dom);
697                 move_to(projb, dom);
698
699                 /* Make the mux. */
700                 cond->mux = new_r_Mux(current_ir_graph, dom, projb,
701                                 operands[0], operands[1], get_irn_mode(operands[0]));
702         }
703
704         return cond->mux;
705 }
706
707 typedef struct _phi_info_t {
708         struct list_head list;
709         cond_info_t *cond_info;
710         ir_node *irn;
711 } phi_info_t;
712
713
714 /**
715  * Examine a phi node if it can be replaced by some muxes.
716  * @param irn A phi node.
717  * @param info Parameters for the if conversion algorithm.
718  */
719 static void check_out_phi(phi_info_t *phi_info, opt_if_conv_info_t *info)
720 {
721         int max_depth = info->max_depth;
722         int i, n;
723         ir_node *irn = phi_info->irn;
724         ir_node *block, *nw;
725         cond_info_t *cond_info = phi_info->cond_info;
726         cond_t *cond;
727         int arity;
728
729         set *cond_set = cond_info->cond_set;
730         bitset_t *positions;
731
732         block = get_nodes_block(irn);
733         arity = get_irn_arity(irn);
734
735         assert(is_Phi(irn));
736         assert(get_irn_arity(irn) == get_irn_arity(block));
737         assert(arity > 0);
738
739         positions = bitset_alloca(arity);
740
741         DBG((dbg, LEVEL_5, "phi candidate: %n\n", irn));
742
743         list_for_each_entry(cond_t, cond, &cond_info->roots, list) {
744                 int cannot_move = 0;
745                 ir_node *cidom = get_nodes_block(cond->cond);
746
747                 cond_t *p, *head = NULL;
748
749                 DBG((dbg, LEVEL_5, "\tcond root: %n\n", cond->cond));
750
751                 /* clear the position array. */
752                 bitset_clear_all(positions);
753
754                 /*
755                  * Link all conds which are in the subtree of
756                  * the current cond in the list together.
757                  */
758                 walk_conds(cond, link_conds, NULL, cond_set, &head);
759
760                 for(p = head, n = 0; p; p = p->link)
761                         cidom = common_idom(cidom, get_nodes_block(p->cond));
762
763                 DBG((dbg, LEVEL_5, "\tcommon idom: %n\n", cidom));
764
765                 for(p = head, n = 0; p && !cannot_move; p = p->link) {
766
767                         if(!can_move_to(get_Cond_selector(p->cond), cidom, max_depth)) {
768                                 DBG((dbg, LEVEL_5, "\tcannot move selector of %n\n", p->cond));
769                                 cannot_move = 1;
770                                 break;
771                         }
772
773                         for(i = 0; i < 2; ++i) {
774                                 int pos = p->cases[i].pos;
775
776                                 if(pos != -1) {
777                                         bitset_set(positions, pos);
778
779                                         if(!can_move_to(get_irn_n(irn, pos), cidom, max_depth)) {
780                                                 cannot_move = 1;
781                                                 DBG((dbg, LEVEL_5, "\tcannot move phi operand %d\n", pos));
782                                                 break;
783                                         }
784
785                                         DBG((dbg, LEVEL_5, "\tcan move phi operand %d\n", pos));
786                                 }
787                         }
788                 }
789
790                 /*
791                  * If all operands and the cond condition can be moved to
792                  * the common immediate dominator, move them there, make a
793                  * mux and associate the corresponding phi operands with
794                  * the mux.
795                  */
796                 if(!cannot_move) {
797                         ir_node *mux = make_mux_on_demand(irn, cidom, cond, cond_info->cond_set);
798
799                         /* If a mux could be made, associate the phi operands with it. */
800                         DBG((dbg, LEVEL_5, "\tassociating:\n"));
801                         if(mux) {
802                                 unsigned long elm;
803                                 bitset_foreach(positions, elm) {
804                                         DBG((dbg, LEVEL_5, "\t\t%d\n", positions[i]));
805                                         set_irn_n(irn, (int) elm, mux);
806                                 }
807                         }
808                 }
809         }
810
811         /*
812          * optimize the phi away. This can anable further runs of this
813          * function. Look at _can_move. phis cannot be moved there.
814          */
815         nw = optimize_in_place_2(irn);
816         if(nw != irn)
817                 exchange(irn, nw);
818 }
819
820 typedef struct _cond_walk_info_t {
821         struct obstack *obst;
822         struct list_head cond_info_head;
823         struct list_head phi_head;
824 } cond_walk_info_t;
825
826
827 static void annotate_cond_info_pre(ir_node *irn, void *data)
828 {
829         set_irn_link(irn, NULL);
830 }
831
832 static void annotate_cond_info_post(ir_node *irn, void *data)
833 {
834         cond_walk_info_t *cwi = data;
835
836         /*
837          * Check, if the node is a phi
838          * we then compute a set of conds which are reachable from this
839          * phi's block up to its dominator.
840          * The set is attached to the blocks link field.
841          */
842         if(is_Phi(irn) && mode_is_datab(get_irn_mode(irn))) {
843                 ir_node *block = get_nodes_block(irn);
844
845                 cond_info_t *ci = get_irn_link(block);
846
847                 /* If the set is not yet computed, do it now. */
848                 if(!ci) {
849                         ci = obstack_alloc(cwi->obst, sizeof(*ci));
850                         ci->cond_set = new_set(cond_cmp, log2_ceil(get_irn_arity(block)));
851                         INIT_LIST_HEAD(&ci->roots);
852                         INIT_LIST_HEAD(&ci->list);
853
854                         /*
855                          * Add this cond info to the list of all cond infos
856                          * in this graph. This is just done to free the
857                          * set easier afterwards (we save an irg_walk_graph).
858                          */
859                         list_add(&cwi->cond_info_head, &ci->list);
860
861                         DBG((dbg, LEVEL_5, "searching conds at %n\n", irn));
862
863                         /*
864                          * Fill the set with conds we find on the way from
865                          * the block to its dominator.
866                          */
867                         find_conds(irn, ci);
868
869                         /*
870                          * If there where no suitable conds, delete the set
871                          * immediately and reset the set pointer to NULL
872                          */
873                         if(set_count(ci->cond_set) == 0) {
874                                 del_set(ci->cond_set);
875                                 ci->cond_set = NULL;
876                                 obstack_free(cwi->obst, ci);
877                         }
878                 }
879
880                 else
881                         DBG((dbg, LEVEL_5, "conds already computed for %n\n", irn));
882
883                 set_irn_link(block, ci);
884
885                 if(ci) {
886                         phi_info_t *pi = obstack_alloc(cwi->obst, sizeof(*pi));
887                         pi->irn = irn;
888                         pi->cond_info = ci;
889                         INIT_LIST_HEAD(&pi->list);
890                         list_add(&pi->list, &cwi->phi_head);
891                 }
892
893         }
894 }
895
896 #if 0
897 /**
898  * Free the sets which are put at some blocks.
899  */
900 static void free_sets(ir_node *irn, void *data)
901 {
902         if(is_Block(irn) && get_irn_link(irn)) {
903                 set *conds = get_irn_link(irn);
904                 del_set(conds);
905         }
906 }
907 #endif
908
909 void opt_if_conv(ir_graph *irg, opt_if_conv_info_t *params)
910 {
911         struct obstack obst;
912         phi_info_t *phi_info;
913         cond_info_t *cond_info;
914         cond_walk_info_t cwi;
915
916         opt_if_conv_info_t *p = params ? params : &default_info;
917
918         if(!get_opt_if_conversion())
919                 return;
920
921         obstack_init(&obst);
922
923         cwi.obst = &obst;
924         INIT_LIST_HEAD(&cwi.cond_info_head);
925         INIT_LIST_HEAD(&cwi.phi_head);
926
927         /* Init the debug stuff. */
928         dbg = firm_dbg_register("firm.opt.ifconv");
929         firm_dbg_set_mask(dbg, 0);
930
931         /* Ensure, that the dominators are computed. */
932         compute_doms(irg);
933
934         DBG((dbg, LEVEL_4, "if conversion for irg %s(%p)\n",
935                                 get_entity_name(get_irg_entity(irg)), irg));
936
937         /*
938          * Collect information about the conds pu the phis on an obstack.
939          * It is important that phi nodes which are 'higher' (with a
940          * lower dfs pre order) are in front of the obstack. Since they are
941          * possibly turned in to muxes this can enable the optimization
942          * of 'lower' ones.
943          */
944         irg_walk_graph(irg, annotate_cond_info_pre, annotate_cond_info_post, &cwi);
945
946         /* Process each suitable phi found. */
947         list_for_each_entry(phi_info_t, phi_info, &cwi.phi_head, list) {
948                 DBG((dbg, LEVEL_4, "phi node %n\n", phi_info->irn));
949                 check_out_phi(phi_info, p);
950         }
951
952         list_for_each_entry(cond_info_t, cond_info, &cwi.cond_info_head, list) {
953                 del_set(cond_info->cond_set);
954         }
955
956         obstack_free(&obst, NULL);
957 }