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