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