added new licence header
[libfirm] / ir / opt / ifconv.c
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /*
21  * Project:     libFIRM
22  * File name:   ir/opt/ifconv.c
23  * Purpose:     If conversion
24  * Author:      Sebastian Hack.
25  * Created:
26  * CVS-ID:      $Id$
27  * Copyright:   (c) 1998-2005 Universität Karlsruhe
28  */
29
30 #if 1
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <assert.h>
37
38 #include "obst.h"
39 #include "irnode_t.h"
40 #include "cdep.h"
41 #include "ircons.h"
42 #include "ifconv.h"
43 #include "irdom.h"
44 #include "irgmod.h"
45 #include "irgopt.h"
46 #include "irgwalk.h"
47 #include "irtools.h"
48 #include "return.h"
49 #include "array.h"
50 #include "xmalloc.h"
51
52 // debug
53 #include "irdump.h"
54 #include "debug.h"
55
56 DEBUG_ONLY(firm_dbg_module_t *dbg);
57
58 /** allow every Psi to be created. */
59 static int default_allow_ifconv(ir_node *sel, ir_node* phi_list, int i, int j)
60 {
61         return 1;
62 }
63
64 /**
65  * Default options.
66  */
67 static const opt_if_conv_info_t default_info = {
68         0,    /* doesn't matter for Psi */
69         default_allow_ifconv
70 };
71
72 /**
73  * Additional block info.
74  */
75 typedef struct block_info {
76         ir_node *phi;   /**< head of the Phi list */
77         int has_pinned; /**< set if the block contains instructions that cannot be moved */
78 } block_info;
79
80 #define get_block_blockinfo(block) ((block_info *)get_irn_link(block))
81
82 /**
83  * Returns non-zero if a Block can be emptied.
84  */
85 static int can_empty_block(ir_node *block)
86 {
87         return !get_block_blockinfo(block)->has_pinned;
88 }
89
90
91 static ir_node* walk_to_projx(ir_node* start, const ir_node* dependency)
92 {
93         int arity;
94         int i;
95
96         /* No need to find the conditional block if this block cannot be emptied and
97          * therefore not moved
98          */
99         if (!can_empty_block(start)) return NULL;
100
101         arity = get_irn_arity(start);
102         for (i = 0; i < arity; ++i) {
103                 ir_node* pred = get_irn_n(start, i);
104                 ir_node* pred_block = get_nodes_block(pred);
105
106                 if (pred_block == dependency) {
107                         if (is_Proj(pred)) {
108                                 assert(get_irn_mode(pred) == mode_X);
109                                 return pred;
110                         }
111                         return NULL;
112                 }
113
114                 if (is_Proj(pred)) {
115                         assert(get_irn_mode(pred) == mode_X);
116                         return NULL;
117                 }
118
119                 if (is_cdep_on(pred_block, dependency)) {
120                         return walk_to_projx(pred_block, dependency);
121                 }
122         }
123         return NULL;
124 }
125
126
127 /**
128  * Copies the DAG starting at node to the ith predecessor block of src_block
129  * -if the node isn't in the src_block, this is a nop and the node is returned
130  * -if the node is a phi in the src_block, the ith predecessor of the phi is
131  *   returned
132  * otherwise returns the copy of the passed node
133  */
134 static ir_node* copy_to(ir_node* node, ir_node* src_block, int i)
135 {
136         ir_node* dst_block;
137         ir_node* copy;
138         int arity;
139         int j;
140
141         if (get_nodes_block(node) != src_block) return node;
142         if (get_irn_op(node) == op_Phi) return get_irn_n(node, i);
143
144         copy = exact_copy(node);
145         dst_block = get_nodes_block(get_irn_n(src_block, i));
146         set_nodes_block(copy, dst_block);
147
148         DB((dbg, LEVEL_1, "Copying node %+F to block %+F, copy is %+F\n",
149                 node, dst_block, copy));
150
151         arity = get_irn_arity(node);
152         for (j = 0; j < arity; ++j) {
153                 set_irn_n(copy, j, copy_to(get_irn_n(node, j), src_block, i));
154                 DB((dbg, LEVEL_2, "-- pred %d is %+F\n", j, get_irn_n(copy, j)));
155         }
156         return copy;
157 }
158
159
160 /**
161  * Remove predecessors i and j from node and add predecessor new_pred
162  */
163 static void rewire(ir_node* node, int i, int j, ir_node* new_pred)
164 {
165         int arity = get_irn_arity(node);
166         ir_node **ins;
167         int k;
168         int l;
169
170         NEW_ARR_A(ir_node *, ins, arity - 1);
171
172         l = 0;
173         for (k = 0; k < i; ++k) ins[l++] = get_irn_n(node, k);
174         for (++k; k < j; ++k) ins[l++] = get_irn_n(node, k);
175         for (++k; k < arity; ++k) ins[l++] = get_irn_n(node, k);
176         ins[l++] = new_pred;
177         assert(l == arity - 1);
178         set_irn_in(node, l, ins);
179 }
180
181
182 /**
183  * Remove the jth predecessors from the ith predecessor of block and add it to block
184  */
185 static void split_block(ir_node* block, int i, int j)
186 {
187         ir_node* pred_block = get_nodes_block(get_irn_n(block, i));
188         int arity = get_irn_arity(block);
189         int new_pred_arity;
190         ir_node* phi;
191         ir_node **ins;
192         ir_node **pred_ins;
193         int k;
194
195         DB((dbg, LEVEL_1, "Splitting predecessor %d of predecessor %d of %+F\n", j, i, block));
196
197         NEW_ARR_A(ir_node*, ins, arity + 1);
198
199         for (phi = get_block_blockinfo(block)->phi; phi != NULL; phi = get_irn_link(phi)) {
200                 ir_node* copy = copy_to(get_irn_n(phi, i), pred_block, j);
201
202                 for (k = 0; k < i; ++k) ins[k] = get_irn_n(phi, k);
203                 ins[k++] = copy;
204                 for (; k < arity; ++k) ins[k] = get_irn_n(phi, k);
205                 ins[k] = get_irn_n(phi, i);
206                 assert(k == arity);
207                 set_irn_in(phi, arity + 1, ins);
208         }
209
210         for (k = 0; k < i; ++k) ins[k] = get_irn_n(block, k);
211         ins[k++] = get_irn_n(pred_block, j);
212         for (; k < arity; ++k) ins[k] = get_irn_n(block, k);
213         ins[k] = get_irn_n(block, i);
214         assert(k == arity);
215         set_irn_in(block, arity + 1, ins);
216
217         new_pred_arity = get_irn_arity(pred_block) - 1;
218         NEW_ARR_A(ir_node*, pred_ins, new_pred_arity);
219
220         for (phi = get_block_blockinfo(pred_block)->phi; phi != NULL; phi = get_irn_link(phi)) {
221                 for (k = 0; k < j; ++k) pred_ins[k] = get_irn_n(phi, k);
222                 for (; k < new_pred_arity; ++k) pred_ins[k] = get_irn_n(phi, k + 1);
223                 assert(k == new_pred_arity);
224                 if (new_pred_arity > 1) {
225                         set_irn_in(phi, new_pred_arity, pred_ins);
226                 } else {
227                         exchange(phi, pred_ins[0]);
228                 }
229         }
230
231         for (k = 0; k < j; ++k) pred_ins[k] = get_irn_n(pred_block, k);
232         for (; k < new_pred_arity; ++k) pred_ins[k] = get_irn_n(pred_block, k + 1);
233         assert(k == new_pred_arity);
234         if (new_pred_arity > 1) {
235                 set_irn_in(pred_block, new_pred_arity, pred_ins);
236         } else {
237                 exchange(pred_block, get_nodes_block(pred_ins[0]));
238         }
239 }
240
241
242 static void prepare_path(ir_node* block, int i, const ir_node* dependency)
243 {
244         ir_node* pred = get_nodes_block(get_irn_n(block, i));
245         int pred_arity;
246         int j;
247
248         DB((dbg, LEVEL_1, "Preparing predecessor %d of %+F\n", i, block));
249
250         pred_arity = get_irn_arity(pred);
251         for (j = 0; j < pred_arity; ++j) {
252                 ir_node* pred_pred = get_nodes_block(get_irn_n(pred, j));
253
254                 if (is_cdep_on(pred_pred, dependency)) {
255                         prepare_path(pred, j, dependency);
256                         split_block(block, i, j);
257                         break;
258                 }
259         }
260 }
261
262
263 static void if_conv_walker(ir_node* block, void* env)
264 {
265         int arity;
266         int i;
267         opt_if_conv_info_t *opt_info = env;
268
269         /* Bail out, if there are no Phis at all */
270         if (get_block_blockinfo(block)->phi == NULL) return;
271
272 restart:
273         arity = get_irn_arity(block);
274         for (i = 0; i < arity; ++i) {
275                 ir_node* pred;
276                 cdep* cdep;
277
278                 pred = get_nodes_block(get_irn_n(block, i));
279                 for (cdep = find_cdep(pred); cdep != NULL; cdep = cdep->next) {
280                         const ir_node* dependency = cdep->node;
281                         ir_node* projx0 = walk_to_projx(pred, dependency);
282                         ir_node* cond;
283                         int j;
284
285                         if (projx0 == NULL) continue;
286
287                         cond = get_Proj_pred(projx0);
288                         if (get_irn_op(cond) != op_Cond) continue;
289
290                         /* We only handle boolean decisions, no switches */
291                         if (get_irn_mode(get_Cond_selector(cond)) != mode_b) continue;
292
293                         for (j = i + 1; j < arity; ++j) {
294                                 ir_node* projx1;
295                                 ir_node* conds[1];
296                                 ir_node* vals[2];
297                                 ir_node* psi = NULL;
298                                 ir_node* psi_block;
299                                 ir_node* phi;
300
301                                 pred = get_nodes_block(get_irn_n(block, j));
302
303                                 if (!is_cdep_on(pred, dependency)) continue;
304
305                                 projx1 = walk_to_projx(pred, dependency);
306
307                                 if (projx1 == NULL) continue;
308
309                                 phi = get_block_blockinfo(block)->phi;
310                                 if (!opt_info->allow_ifconv(get_Cond_selector(cond), phi, i, j)) continue;
311
312                                 DB((dbg, LEVEL_1, "Found Cond %+F with proj %+F and %+F\n",
313                                         cond, projx0, projx1
314                                 ));
315
316                                 prepare_path(block, i, dependency);
317                                 prepare_path(block, j, dependency);
318                                 arity = get_irn_arity(block);
319
320                                 conds[0] = get_Cond_selector(cond);
321
322                                 psi_block = get_nodes_block(cond);
323                                 do {
324                                         ir_node* val_i = get_irn_n(phi, i);
325                                         ir_node* val_j = get_irn_n(phi, j);
326
327                                         if (val_i == val_j) {
328                                                 psi = val_i;
329                                                 DB((dbg, LEVEL_2,  "Generating no psi, because both values are equal\n"));
330                                         } else {
331                                                 /* Something is very fishy if two predecessors of a PhiM point into
332                                                  * one block, but not at the same memory node
333                                                  */
334                                                 assert(get_irn_mode(phi) != mode_M);
335                                                 if (get_Proj_proj(projx0) == pn_Cond_true) {
336                                                         vals[0] = val_i;
337                                                         vals[1] = val_j;
338                                                 } else {
339                                                         vals[0] = val_j;
340                                                         vals[1] = val_i;
341                                                 }
342
343                                                 psi = new_r_Psi(
344                                                         current_ir_graph, psi_block, 1, conds, vals, get_irn_mode(phi)
345                                                 );
346                                                 DB((dbg, LEVEL_2, "Generating %+F for %+F\n", psi, phi));
347                                         }
348
349                                         /* only exchange if we have a Psi */
350                                         if (arity == 2) {
351                                                 exchange(phi, psi);
352                                         } else {
353                                                 rewire(phi, i, j, psi);
354                                         }
355
356                                         phi = get_irn_link(phi);
357                                 } while (phi != NULL);
358
359                                 exchange(get_nodes_block(get_irn_n(block, i)), psi_block);
360                                 exchange(get_nodes_block(get_irn_n(block, j)), psi_block);
361
362                                 if (arity == 2) {
363 #if 1
364                                         DB((dbg, LEVEL_1,  "Welding block %+F and %+F\n", block, psi_block));
365                                         /* copy the block-info from the Psi-block to the block before merging */
366                                         get_block_blockinfo(psi_block)->has_pinned |= get_block_blockinfo(block)->has_pinned;
367                                         set_irn_link(block, get_irn_link(psi_block));
368
369                                         set_irn_in(block, get_irn_arity(psi_block), get_irn_in(psi_block) + 1);
370                                         exchange_cdep(psi_block, block);
371                                         exchange(psi_block, block);
372 #else
373                                         DB((dbg, LEVEL_1,  "Welding block %+F to %+F\n", block, psi_block));
374                                         get_block_blockinfo(psi_block)->has_pinned |=   get_block_blockinfo(block)->has_pinned;
375                                         exchange(block, psi_block);
376 #endif
377                                         return;
378                                 } else {
379                                         rewire(block, i, j, new_r_Jmp(current_ir_graph, psi_block));
380                                         goto restart;
381                                 }
382                         }
383                 }
384         }
385 }
386
387 /**
388  * Block walker: add additional data
389  */
390 static void init_block_link(ir_node *block, void *env)
391 {
392         struct obstack *obst = env;
393         block_info *bi = obstack_alloc(obst, sizeof(*bi));
394
395         bi->phi = NULL;
396         bi->has_pinned = 0;
397         set_irn_link(block, bi);
398 }
399
400
401 /**
402  * Daisy-chain all phis in a block
403  * If a non-movable node is encountered set the has_pinned flag
404  */
405 static void collect_phis(ir_node *node, void *env)
406 {
407         if (is_Phi(node)) {
408                 ir_node *block = get_nodes_block(node);
409                 block_info *bi = get_block_blockinfo(block);
410
411                 set_irn_link(node, bi->phi);
412                 bi->phi = node;
413         }
414         else {
415                 if (is_no_Block(node) && get_irn_pinned(node) == op_pin_state_pinned) {
416                         /*
417                          * Ignore control flow nodes, these will be removed.
418                          * This ignores Raise. That is surely bad. FIXME.
419                          */
420                         if (! is_cfop(node)) {
421                                 ir_node *block = get_nodes_block(node);
422                                 block_info *bi = get_block_blockinfo(block);
423
424                                 DB((dbg, LEVEL_2, "Node %+F in block %+F is unmovable\n", node, block));
425                                 bi->has_pinned = 1;
426                         }
427                 }
428         }
429 }
430
431
432 /*
433  * Transform multiple cascaded Psis into one Psi
434  */
435 static ir_node* fold_psi(ir_node* psi)
436 {
437         int arity = get_Psi_n_conds(psi);
438         int new_arity = 0;
439         int i;
440         ir_node* n;
441         ir_node** conds;
442         ir_node** vals;
443         int j;
444         int k;
445         int a;
446         ir_node* new_psi;
447
448         for (i = 0; i < arity; ++i) {
449                 n = get_Psi_val(psi, i);
450                 if (get_irn_op(n) == op_Psi) {
451                         new_arity += get_Psi_n_conds(n) + 1;
452                 } else {
453                         ++new_arity;
454                 }
455         }
456         n = get_Psi_default(psi);
457         if (get_irn_op(n) == op_Psi) {
458                 new_arity += get_Psi_n_conds(n);
459         }
460
461         if (arity == new_arity) return psi; // no attached Psis found
462         DB((dbg, LEVEL_1, "Folding %+F from %d to %d conds\n", psi, arity, new_arity));
463
464         NEW_ARR_A(ir_node *, conds, new_arity);
465         NEW_ARR_A(ir_node *, vals, new_arity + 1);
466         j = 0;
467         for (i = 0; i < arity; ++i) {
468                 ir_node* c = get_Psi_cond(psi, i);
469
470                 n = get_Psi_val(psi, i);
471                 if (get_irn_op(n) == op_Psi) {
472                         a = get_Psi_n_conds(n);
473                         for (k = 0; k < a; ++k) {
474                                 conds[j] = new_r_And(
475                                         current_ir_graph, get_nodes_block(psi),
476                                         c, get_Psi_cond(n, k), mode_b
477                                 );
478                                 vals[j] = get_Psi_val(n, k);
479                                 ++j;
480                         }
481                         conds[j] = c;
482                         vals[j] = get_Psi_default(n);
483                 } else {
484                         conds[j] = c;
485                         vals[j] = n;
486                 }
487                 ++j;
488         }
489         n = get_Psi_default(psi);
490         if (get_irn_op(n) == op_Psi) {
491                 a = get_Psi_n_conds(n);
492                 for (k = 0; k < a; ++k) {
493                         conds[j] = get_Psi_cond(n, k);
494                         vals[j] = get_Psi_val(n, k);
495                         ++j;
496                 }
497                 vals[j] = get_Psi_default(n);
498         } else {
499                 vals[j] = n;
500         }
501         assert(j == new_arity);
502         new_psi = new_r_Psi(
503                 current_ir_graph, get_nodes_block(psi),
504                 new_arity, conds, vals, get_irn_mode(psi)
505         );
506         DB((dbg, LEVEL_1, "Folded %+F into new %+F\n", psi, new_psi));
507         exchange(psi, new_psi);
508         return new_psi;
509 }
510
511
512 /*
513  * Merge consecutive psi inputs if the data inputs are the same
514  */
515 static ir_node* meld_psi(ir_node* psi)
516 {
517         int arity = get_Psi_n_conds(psi);
518         int new_arity;
519         ir_node** conds;
520         ir_node** vals;
521         ir_node* cond;
522         ir_node* val;
523         int i;
524         int j;
525         ir_node* new_psi;
526
527         new_arity = 1;
528         val = get_Psi_val(psi, 0);
529         DB((dbg, LEVEL_1, "Pred  0 of %+F is %+F\n", psi, val));
530         for (i = 1; i < arity; ++i) {
531                 ir_node* v = get_Psi_val(psi, i);
532                 DB((dbg, LEVEL_1, "Pred %2d of %+F is %+F\n", i, psi, v));
533                 if (val != v) {
534                         val = v;
535                         ++new_arity;
536                 }
537         }
538         DB((dbg, LEVEL_1, "Default of %+F is %+F\n", psi, get_Psi_default(psi)));
539         if (val == get_Psi_default(psi)) --new_arity;
540
541         DB((dbg, LEVEL_1, "Melding Psi %+F from %d conds to %d\n", psi, arity, new_arity));
542
543         if (new_arity == arity) return psi;
544
545         /* If all data inputs of the Psi are equal, exchange the Psi with that value */
546         if (new_arity == 0) {
547                 exchange(psi, val);
548                 return val;
549         }
550
551         NEW_ARR_A(ir_node *, conds, new_arity);
552         NEW_ARR_A(ir_node *, vals, new_arity + 1);
553         cond = get_Psi_cond(psi, 0);
554         val = get_Psi_val(psi, 0);
555         j = 0;
556         for (i = 1; i < arity; ++i) {
557                 ir_node* v = get_Psi_val(psi, i);
558
559                 if (v == val) {
560                         cond = new_r_Or(
561                                 current_ir_graph, get_nodes_block(psi),
562                                 cond, get_Psi_cond(psi, i), mode_b
563                         );
564                 } else {
565                         conds[j] = cond;
566                         vals[j] = val;
567                         ++j;
568                         val = v;
569                 }
570         }
571         if (val != get_Psi_default(psi)) {
572                 conds[j] = cond;
573                 vals[j] = val;
574                 ++j;
575         }
576         vals[j] = get_Psi_default(psi);
577         assert(j == new_arity);
578         new_psi = new_r_Psi(
579                 current_ir_graph, get_nodes_block(psi),
580                 new_arity, conds, vals, get_irn_mode(psi)
581         );
582         DB((dbg, LEVEL_1, "Molded %+F into %+F\n", psi, new_psi));
583         exchange(psi, new_psi);
584         return new_psi;
585 }
586
587
588 /**
589  * Split a Psi with multiple conditions into multiple Psis with one condtition
590  * each
591  */
592 static ir_node* split_psi(ir_node* psi)
593 {
594         int arity = get_Psi_n_conds(psi);
595         ir_mode* mode;
596         ir_node* block;
597         ir_node* rval;
598         int i;
599
600         if (arity == 1) return psi;
601
602         mode = get_irn_mode(psi);
603         block = get_nodes_block(psi);
604         rval = get_Psi_default(psi);
605         for (i = arity - 1; i >= 0; --i) {
606                 ir_node* conds[1];
607                 ir_node* vals[2];
608
609                 conds[0] = get_Psi_cond(psi, i);
610                 vals[0] = get_Psi_val(psi, i);
611                 vals[1] = rval;
612                 rval = new_r_Psi(
613                         current_ir_graph, block, 1, conds, vals, mode
614                 );
615         }
616         exchange(psi, rval);
617         return rval;
618 }
619
620
621 static void optimise_psis(ir_node* node, void* env)
622 {
623         if (get_irn_op(node) != op_Psi) return;
624 #if 1
625         node = fold_psi(node);
626 #endif
627 #if 1
628         node = meld_psi(node);
629 #endif
630 #if 1
631         node = split_psi(node);
632 #endif
633 }
634
635
636 void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params)
637 {
638         struct obstack obst;
639         opt_if_conv_info_t p;
640
641         if (! get_opt_if_conversion())
642                 return;
643
644         /* get the parameters */
645         if (params)
646                 memcpy(&p, params, sizeof(p));
647         else
648                 memcpy(&p, &default_info, sizeof(p));
649
650         FIRM_DBG_REGISTER(dbg, "firm.opt.ifconv");
651
652         DB((dbg, LEVEL_1, "Running if-conversion on %+F\n", irg));
653
654         normalize_one_return(irg);
655         remove_critical_cf_edges(irg);
656
657         compute_cdep(irg);
658         assure_doms(irg);
659
660         obstack_init(&obst);
661         irg_block_walk_graph(irg, init_block_link, NULL, &obst);
662         irg_walk_graph(irg, collect_phis, NULL, NULL);
663         irg_block_walk_graph(irg, NULL, if_conv_walker, &p);
664
665         local_optimize_graph(irg);
666
667         irg_walk_graph(irg, NULL, optimise_psis, NULL);
668
669         obstack_free(&obst, NULL);
670
671         free_dom(irg);
672         free_cdep(irg);
673 }
674
675 #else
676
677 /**
678  * @file ifconv.c
679  * If conversion.
680  * Make Mux nodes from Conds where it its possible.
681  * @author Sebastian Hack
682  * @date 4.2.2005
683  */
684 #ifdef HAVE_CONFIG_H
685 #include "config.h"
686 #endif
687
688 #ifdef HAVE_STDLIB_H
689 #include <stdlib.h>
690 #endif
691 #ifdef HAVE_STRING_H
692 #include <string.h>
693 #endif
694 #ifdef HAVE_ALLOCA_H
695 #include <alloca.h>
696 #endif
697
698 #include "irgraph_t.h"
699 #include "irnode_t.h"
700 #include "irgwalk.h"
701 #include "iropt_t.h"
702 #include "irgmod.h"
703 #include "irmode_t.h"
704 #include "ircons_t.h"
705 #include "irdom_t.h"
706 #include "irgwalk.h"
707
708 #include "ifconv.h"
709 #include "irflag_t.h"
710
711 #include "irprintf.h"
712 #include "debug.h"
713 #include "obst.h"
714 #include "set.h"
715 #include "bitset.h"
716 #include "bitfiddle.h"
717 #include "irhooks.h"
718 #include "return.h"
719
720 #define MAX_DEPTH   4
721
722 /**
723  * check, if a node is const and return its tarval or
724  * return a default tarval.
725  * @param cnst The node whose tarval to get.
726  * @param or The alternative tarval, if the node is no Const.
727  * @return The tarval of @p cnst, if the node is Const, @p otherwise.
728  */
729 static tarval *get_value_or(ir_node *cnst, tarval *or)
730 {
731   return get_irn_op(cnst) == op_Const ? get_Const_tarval(cnst) : or;
732 }
733
734
735 /**
736  * Try to optimize nested muxes into a dis- or conjunction
737  * of two muxes.
738  * @param mux The parent mux, which has muxes as operands.
739  * @return The replacement node for this mux. If the optimization is
740  * successful, this might be an And or Or node, if not, its the mux
741  * himself.
742  */
743 static ir_node *optimize_mux_chain(ir_node *mux)
744 {
745   int i;
746   ir_node *res;
747   ir_node *ops[2];
748   ir_mode *mode = get_irn_mode(mux);
749   tarval *null;
750   tarval *minus_one;
751
752   /*
753    * If we have no mux, or its mode is not integer, we
754    * can return.
755    */
756   if(get_irn_op(mux) != op_Mux || !mode_is_int(mode))
757     return mux;
758
759   res = mux;
760   null = get_mode_null(mode);
761   minus_one = tarval_sub(null, get_tarval_one(mode));
762
763   ops[0] = get_Mux_false(mux);
764   ops[1] = get_Mux_true(mux);
765
766   for(i = 0; i < 2; ++i) {
767     ir_node *a, *b, *d;
768     tarval *tva, *tvb, *tvd;
769     ir_node *child_mux;
770
771     /*
772      * A mux operand at the first position can be factored
773      * out, if the operands fulfill several conditions:
774      *
775      * mux(c1, mux(c2, a, b), d)
776      *
777      * This can be made into:
778      * 1) mux(c1, 0, d) | mux(c2, a, b)
779      *    if a | d == d and b | d == d
780      *
781      * 2) mux(c1, -1, d) & mux(c2, a, b)
782      *    if a & d == d and a & b == b
783      */
784     if(get_irn_op(ops[i]) == op_Mux) {
785
786       child_mux = ops[i];
787       a = get_Mux_false(child_mux);
788       b = get_Mux_true(child_mux);
789       d = ops[1 - i];
790
791       /* Try the or stuff */
792       tva = get_value_or(a, minus_one);
793       tvb = get_value_or(b, minus_one);
794       tvd = get_value_or(d, null);
795
796       if(tarval_cmp(tarval_or(tva, tvd), tvd) == pn_Cmp_Eq
797           && tarval_cmp(tarval_or(tvb, tvd), tvd) == pn_Cmp_Eq) {
798
799         ops[i] = new_Const(mode, null);
800         res = new_r_Or(current_ir_graph, get_nodes_block(mux),
801             mux, child_mux, mode);
802         break;
803       }
804
805       /* If the or didn't go, try the and stuff */
806       tva = get_value_or(a, null);
807       tvb = get_value_or(b, null);
808       tvd = get_value_or(d, minus_one);
809
810       if(tarval_cmp(tarval_and(tva, tvd), tvd) == pn_Cmp_Eq
811           && tarval_cmp(tarval_and(tvb, tvd), tvd) == pn_Cmp_Eq) {
812
813         ops[i] = new_Const(mode, minus_one);
814         res = new_r_And(current_ir_graph, get_nodes_block(mux),
815             mux, child_mux, mode);
816         break;
817       }
818     }
819   }
820
821   /* recursively optimize nested muxes. */
822   set_irn_n(mux, 1, optimize_mux_chain(ops[0]));
823   set_irn_n(mux, 2, optimize_mux_chain(ops[1]));
824
825   return res;
826 }
827
828
829 /***********************************************************
830  * The If conversion itself.
831  ***********************************************************/
832
833 /** allow every Mux to be created. */
834 static int default_allow_mux(ir_node *sel, ir_node *false_res, ir_node *true_res) {
835   return 1;
836 }
837
838 /**
839  * Default options.
840  */
841 static const opt_if_conv_info_t default_info = {
842   MAX_DEPTH,
843   default_allow_mux
844 };
845
846 /** The debugging module. */
847 DEBUG_ONLY(static firm_dbg_module_t *dbg;)
848
849 /**
850  * A simple check for side effects upto an opcode of a ir node.
851  * @param irn The ir node to check,
852  * @return 1 if the opcode itself may produce side effects, 0 if not.
853  */
854 static INLINE int has_side_effects(const ir_node *irn)
855 {
856   ir_op *op = get_irn_op(irn);
857
858   if (op == op_Cmp)
859     return 0;
860
861   return !mode_is_datab(get_irn_mode(irn));
862 }
863
864 /**
865  * Possible failure reasons
866  */
867 enum failure_reason_t {
868   SUCCESS      = IF_RESULT_SUCCESS,
869   TO_DEEP      = IF_RESULT_TOO_DEEP,
870   SIDE_EFFECTS = IF_RESULT_SIDE_EFFECT,
871   PHI_FOUND    = IF_RESULT_SIDE_EFFECT_PHI,
872   DENIED       = IF_RESULT_DENIED
873 };
874
875 /**
876  * Decides, if a given expression and its subexpressions
877  * (to certain, also given extent) can be moved to a block.
878  *
879  * @param expr      The expression to examine.
880  * @param block     The block where the expression should go.
881  * @param depth     The current depth, passed recursively. Use 0 for
882  *                  non-recursive calls.
883  * @param info      The options for createing Mux nodes.
884  * examined.
885  *
886  * @return a failure reason
887  */
888 static int _can_move_to(ir_node *expr, ir_node *dest_block, int depth, const opt_if_conv_info_t *info)
889 {
890   int i, n;
891   int res = SUCCESS;
892   ir_node *expr_block = get_nodes_block(expr);
893
894   /*
895    * If we are forced to look too deep into the expression,
896    * treat it like it could not be moved.
897    */
898   if(depth >= info->max_depth) {
899     res = TO_DEEP;
900     goto end;
901   }
902
903   /*
904    * If the block of the expression dominates the specified
905    * destination block, it does not matter if the expression
906    * has side effects or anything else. It is executed on each
907    * path the destination block is reached.
908    */
909   if (block_dominates(expr_block, dest_block))
910     goto end;
911
912   /*
913    * We cannot move phis!
914    */
915   if (is_Phi(expr)) {
916     res = PHI_FOUND;
917     goto end;
918   }
919
920   /*
921    * This should be superfluous and could be converted into a assertion.
922    * The destination block _must_ dominate the block of the expression,
923    * else the expression could be used without its definition.
924    */
925   if (! block_dominates(dest_block, expr_block)) {
926     res = IF_RESULT_SIDE_EFFECT;
927     goto end;
928   }
929
930   /*
931    * Surely, if the expression does not have a data mode, it is not
932    * movable. Perhaps one should also test the floating property of
933    * the opcode/node.
934    */
935   if (has_side_effects(expr)) {
936     res = IF_RESULT_SIDE_EFFECT;
937     goto end;
938   }
939
940   /*
941    * If the node looks alright so far, look at its operands and
942    * check them out. If one of them cannot be moved, this one
943    * cannot be moved either.
944    */
945   for (i = 0, n = get_irn_arity(expr); i < n; ++i) {
946     ir_node *op = get_irn_n(expr, i);
947     int new_depth = is_Proj(op) ? depth : depth + 1;
948
949     res = _can_move_to(op, dest_block, new_depth, info);
950
951     if (res != SUCCESS)
952       goto end;
953   }
954
955 end:
956   DBG((dbg, LEVEL_3, "\t\t\tcan move to %n: %d\n", expr, res));
957
958   return res;
959 }
960
961 /**
962  * Convenience function for _can_move_to.
963  * Checks, if an expression can be moved to another block. The check can
964  * be limited to a expression depth meaning if we need to crawl in
965  * deeper into an expression than a given threshold to examine if
966  * it can be moved, the expression is rejected and the test returns
967  * false.
968  *
969  * @param expr       The expression to check for.
970  * @param dest_block The destination block you want @p expr to be.
971  * @param info       The options for createing Mux nodes.
972  *
973  * @return return a failure reason
974  */
975 static INLINE int can_move_to(ir_node *expr, ir_node *dest_block, const opt_if_conv_info_t *info)
976 {
977   return _can_move_to(expr, dest_block, 0, info);
978 }
979
980 /**
981  * move a DAG given by a root node expr into a new block
982  *
983  * @param expr       the root of a dag
984  * @param dest_block the destination block
985  */
986 static void move_to(ir_node *expr, ir_node *dest_block)
987 {
988   int i, n;
989   ir_node *expr_block = get_nodes_block(expr);
990
991   /*
992    * If we reached the dominator, we are done.
993    * We will never put code through the dominator
994    */
995   if (block_dominates(expr_block, dest_block))
996     return;
997
998   for (i = 0, n = get_irn_arity(expr); i < n; ++i)
999     move_to(get_irn_n(expr, i), dest_block);
1000
1001   set_nodes_block(expr, dest_block);
1002 }
1003
1004 /**
1005  * return the common dominator of two blocks
1006  */
1007 static INLINE ir_node *common_idom(ir_node *b1, ir_node *b2)
1008 {
1009   if(block_dominates(b1, b2))
1010     return b1;
1011   else if(block_dominates(b2, b1))
1012     return b2;
1013   else {
1014     ir_node *p;
1015
1016     for (p = get_Block_idom(b1); !block_dominates(p, b2); p = get_Block_idom(p));
1017     return p;
1018   }
1019 }
1020
1021 /**
1022  * Information about a cond node.
1023  */
1024 typedef struct _cond_t {
1025   ir_node *cond;          /**< The cond node. */
1026   struct list_head list;  /**< List head which is used for queuing this cond
1027                                into the cond bunch it belongs to. */
1028   unsigned is_new : 1;
1029   unsigned totally_covers : 1;
1030   struct _cond_t *link;
1031   long visited_nr;
1032
1033   /**
1034    * Information about the both 'branches'
1035    * (true and false), the cond creates.
1036    */
1037   struct {
1038     int pos;         /**< Number of the predecessor of the
1039                           phi block by which this branch is
1040                           reached. It is -1, if this branch is
1041                           only reached through another cond. */
1042
1043     struct _cond_t *masked_by; /**< If this cond's branch is only reached
1044                                     through another cond, we store this
1045                                     cond ir_node here. */
1046   } cases[2];
1047 } cond_t;
1048
1049 /**
1050  * retrieve the conditional information from a Cond node
1051  */
1052 static INLINE cond_t *get_cond(ir_node *irn, set *cond_set)
1053 {
1054   cond_t templ;
1055
1056   templ.cond = irn;
1057   return set_find(cond_set, &templ, sizeof(templ), HASH_PTR(templ.cond));
1058 }
1059
1060
1061 typedef void (cond_walker_t)(cond_t *cond, void *env);
1062
1063 static void _walk_conds(cond_t *cond, cond_walker_t *pre, cond_walker_t *post,
1064       long visited_nr, void *env)
1065 {
1066   int i;
1067
1068   if(cond->visited_nr >= visited_nr)
1069     return;
1070
1071   cond->visited_nr = visited_nr;
1072
1073   if(pre)
1074     pre(cond, env);
1075
1076   for(i = 0; i < 2; ++i) {
1077     cond_t *c = cond->cases[i].masked_by;
1078
1079     if(c)
1080       _walk_conds(c, pre, post, visited_nr, env);
1081   }
1082
1083   if(post)
1084     post(cond, env);
1085 }
1086
1087 static long cond_visited_nr = 0;
1088
1089 static void walk_conds(cond_t *cond, cond_walker_t *pre, cond_walker_t *post, void *env)
1090 {
1091   _walk_conds(cond, pre, post, ++cond_visited_nr, env);
1092 }
1093
1094 static void link_conds(cond_t *cond, void *env)
1095 {
1096   cond_t **ptr = (cond_t **) env;
1097
1098   cond->link = *ptr;
1099   *ptr = cond;
1100 }
1101
1102 /**
1103  * Compare two conds for use in a firm set.
1104  * Two cond_t's are equal, if they designate the same cond node.
1105  * @param a A cond_t.
1106  * @param b Another one.
1107  * @param size Not used.
1108  * @return 0 (!) if they are equal, != 0 otherwise.
1109  */
1110 static int cond_cmp(const void *a, const void *b, size_t size)
1111 {
1112   const cond_t *x = a;
1113   const cond_t *y = b;
1114   return x->cond != y->cond;
1115 }
1116
1117 /**
1118  * Information about conds which can be made to muxes.
1119  * Instances of this struct are attached to the link field of
1120  * blocks in which phis are located.
1121  */
1122 typedef struct _cond_info_t {
1123   struct list_head list;      /**< Used to list all of these structs per class. */
1124
1125   struct list_head roots;     /**< A list of non-depending Conds. Two Conds are
1126                                 independent, if it's not possible not reach one from the
1127                                 other (all Conds in this list have to dominate the
1128                                 block this struct is attached to). */
1129
1130   ir_node *first_phi;         /**< The first phi node this cond info was made for. */
1131   set *cond_set;              /**< A set of all dominating reachable Conds. */
1132 } cond_info_t;
1133
1134 /**
1135  * @see find_conds.
1136  */
1137 static void _find_conds(ir_node *irn, unsigned long visited_nr,
1138     ir_node *dominator, cond_t *masked_by, int pos, int depth, cond_info_t *ci)
1139 {
1140   ir_node *block;
1141   int saw_select_cond = 0;
1142
1143   block = get_nodes_block(irn);
1144
1145   /*
1146    * Only check this block if it is dominated by the specified
1147    * dominator or it has not been visited yet.
1148    */
1149   if (block_dominates(dominator, block) && get_Block_block_visited(block) < visited_nr) {
1150     cond_t *res = masked_by;
1151     int i, n;
1152
1153     /* check, if we're on a ProjX
1154      *
1155      * Further, the ProjX/Cond block must dominate the base block
1156      * (the block with the phi in it), otherwise, the Cond
1157      * is not affecting the phi so that a mux can be inserted.
1158      */
1159     if(is_Proj(irn) && get_irn_mode(irn) == mode_X) {
1160
1161       int proj = get_Proj_proj(irn);
1162       ir_node *cond = get_Proj_pred(irn);
1163
1164       /* true, if the mode is a mode_b cond _NO_ switch cond */
1165       int is_modeb_cond = get_irn_opcode(cond) == iro_Cond
1166         && get_irn_mode(get_Cond_selector(cond)) == mode_b;
1167
1168       saw_select_cond = !is_modeb_cond;
1169
1170       /* Check, if the pred of the proj is a Cond
1171        * with a Projb as selector.
1172        */
1173       if(is_modeb_cond) {
1174         cond_t c;
1175
1176         memset(&c, 0, sizeof(c));
1177         c.cond = cond;
1178         c.is_new = 1;
1179         c.cases[0].pos = -1;
1180         c.cases[1].pos = -1;
1181
1182         /* get or insert the cond info into the set. */
1183         res = set_insert(ci->cond_set, &c, sizeof(c), HASH_PTR(cond));
1184
1185         /*
1186          * If this cond is already masked by the masked_by cond
1187          * return immediately, since we don't have anything to add.
1188          */
1189         if(masked_by && res->cases[proj].masked_by == masked_by)
1190           return;
1191
1192         if(res->is_new) {
1193           res->is_new = 0;
1194           list_add(&res->list, &ci->roots);
1195         }
1196
1197         /*
1198          * Set masked by (either NULL or another cond node.
1199          * If this cond is truly masked by another one, set
1200          * the position of the actually investigated branch
1201          * to -1. Since the cond is masked by another one,
1202          * there could be more ways from the start block
1203          * to this branch, so we choose -1.
1204          */
1205         res->cases[proj].masked_by = masked_by;
1206
1207         if(!masked_by)
1208           res->cases[proj].pos = pos;
1209
1210         /*
1211          * Since the masked_by nodes masks a cond, remove it from the
1212          * root list of the conf trees.
1213          */
1214         else {
1215           assert(res->cases[proj].pos < 0);
1216           list_del_init(&masked_by->list);
1217         }
1218
1219         DBG((dbg, LEVEL_2, "%n (%s branch) "
1220               "for pos %d in block %n reached by %n\n",
1221               cond, proj ? "true" : "false", pos,
1222               block, masked_by ? masked_by->cond : NULL));
1223       }
1224     }
1225
1226     if(get_Block_block_visited(block) < visited_nr && !saw_select_cond) {
1227
1228       set_Block_block_visited(block, visited_nr);
1229
1230       /* Search recursively from this cond. */
1231       for(i = 0, n = get_irn_arity(block); i < n; ++i) {
1232         ir_node *pred = get_irn_n(block, i);
1233
1234         /*
1235          * If the depth is 0 (the first recursion), we set the pos to
1236          * the current viewed predecessor, else we adopt the position
1237          * as given by the caller. We also increase the depth for the
1238          * recursively called functions.
1239          */
1240         _find_conds(pred, visited_nr, dominator, res, pos, depth + (res != masked_by), ci);
1241       }
1242     }
1243   }
1244 }
1245
1246
1247 /**
1248  * A convenience function for _find_conds.
1249  * It sets some parameters needed for recursion to appropriate start
1250  * values. Always use this function.
1251  *
1252  * @param irn   The node to start looking for Conds from. This might
1253  *              be the phi node we are investigating.
1254  * @param conds The set to record the found Conds in.
1255  */
1256 static INLINE void find_conds(ir_node *irn, cond_info_t *ci)
1257 {
1258   int i, n;
1259   unsigned long visited_nr;
1260   ir_node *block = get_nodes_block(irn);
1261   ir_node *dom = get_Block_idom(block);
1262
1263   for(i = 0, n = get_irn_arity(block); i < n; ++i) {
1264     ir_node *pred = get_irn_n(block, i);
1265
1266     inc_irg_block_visited(current_ir_graph);
1267     visited_nr = get_irg_block_visited(current_ir_graph);
1268     set_Block_block_visited(block, visited_nr);
1269
1270     DBG((dbg, LEVEL_2, "find conds at pred %d (%n) and idom %n\n", i, pred, dom));
1271     _find_conds(pred, visited_nr, dom, NULL, i, 0, ci);
1272   }
1273 }
1274
1275 /**
1276  * Make the mux for a given cond.
1277  *
1278  * @param phi       The phi node which shall be replaced by a mux.
1279  * @param dom       The block where the muxes shall be placed.
1280  * @param cond      The cond information.
1281  * @param info      The options for createing Mux nodes.
1282  * @return The mux node made for this cond.
1283  */
1284 static ir_node *make_mux_on_demand(ir_node *phi, ir_node *dom, cond_t *cond,
1285     const opt_if_conv_info_t *info, ir_node **mux, bitset_t *positions,
1286     int *muxes_made, long visited_nr)
1287 {
1288   int i, can_move[2];
1289   ir_node *projb = get_Cond_selector(cond->cond);
1290   ir_node *bl = get_nodes_block(cond->cond);
1291   ir_node *operands[2];
1292   int set[2];
1293
1294   cond->visited_nr = visited_nr;
1295   DBG((dbg, LEVEL_2, "%n\n", cond->cond));
1296   for(i = 0; i < 2; ++i) {
1297     cond_t *masked_by = cond->cases[i].masked_by;
1298     int pos = cond->cases[i].pos;
1299
1300     operands[i] = NULL;
1301     set[i] = -1;
1302
1303     /*
1304      * If this Cond branch is masked by another cond, make the mux
1305      * for that Cond first, since the Mux for this cond takes
1306      * it as an operand.
1307      */
1308     if(masked_by) {
1309       assert(pos < 0);
1310       DBG((dbg, LEVEL_2, "\tmasked by: %n\n", masked_by->cond));
1311       if(masked_by->visited_nr < visited_nr)
1312         operands[i] = make_mux_on_demand(phi, dom, masked_by, info, mux, positions, muxes_made, visited_nr);
1313     }
1314
1315     /*
1316      * If this cond branch is not masked by another cond, take
1317      * the corresponding phi operand as an operand to the mux.
1318      */
1319     else if(pos >= 0) {
1320       operands[i] = get_irn_n(phi, pos);
1321       set[i] = pos;
1322     }
1323   }
1324
1325   /*
1326    * Move the operands to the dominator block if the cond
1327    * made sense. Some Conds found are not suitable for making a mux
1328    * out of them, since one of their branches cannot be reached from
1329    * the phi block. In that case we do not make a mux and return NULL.
1330    */
1331   if(operands[0] && operands[1]) {
1332     if (operands[0] == operands[1]) {
1333       /* there is no gain in using mux in this case, as
1334          it will be optimized away. We will NOT move the
1335          content of the blocks either
1336         */
1337       for (i = 0; i < 2; ++i)
1338         if(set[i] >= 0)
1339           bitset_set(positions, set[i]);
1340
1341       *mux = operands[0];
1342       return *mux;
1343     }
1344
1345     can_move[0] = can_move_to(operands[0], bl, info);
1346     can_move[1] = can_move_to(operands[1], bl, info);
1347
1348     if (can_move[0] == SUCCESS && can_move[1] == SUCCESS) {
1349       if (info->allow_mux(projb, operands[0], operands[1])) {
1350         move_to(operands[0], bl);
1351         move_to(operands[1], bl);
1352
1353         /* Make the mux. */
1354         *mux = new_r_Mux(current_ir_graph, bl, projb,
1355             operands[0], operands[1], get_irn_mode(operands[0]));
1356
1357         *muxes_made += 1;
1358
1359         DBG((dbg, LEVEL_2, "\t%n(%n, %n, %n)[%d, %d]\n",
1360               *mux, projb, operands[0], operands[1], set[0], set[1]));
1361
1362         for(i = 0; i < 2; ++i)
1363           if(set[i] >= 0) {
1364             bitset_set(positions, set[i]);
1365
1366             /* we have done one */
1367             hook_if_conversion(current_ir_graph, phi, set[i], *mux, IF_RESULT_SUCCESS);
1368           }
1369       }
1370       else {
1371         hook_if_conversion(current_ir_graph, phi, set[i], *mux, IF_RESULT_DENIED);
1372       }
1373     }
1374     else {
1375       if(can_move[0] != SUCCESS)
1376         hook_if_conversion(current_ir_graph, phi, set[0], NULL, can_move[0]);
1377       if(can_move[1] != SUCCESS)
1378         hook_if_conversion(current_ir_graph, phi, set[1], NULL, can_move[1]);
1379     }
1380   }
1381   else {
1382     if(operands[0])
1383       hook_if_conversion(current_ir_graph, phi, set[0], NULL, IF_RESULT_BAD_CF);
1384     if(operands[1])
1385       hook_if_conversion(current_ir_graph, phi, set[1], NULL, IF_RESULT_BAD_CF);
1386   }
1387
1388   return *mux;
1389 }
1390
1391 typedef struct _phi_info_t {
1392   struct list_head list;
1393   cond_info_t *cond_info;
1394   ir_node *irn;
1395 } phi_info_t;
1396
1397
1398 /**
1399  * Examine a phi node if it can be replaced by some muxes.
1400  * @param irn A phi node.
1401  * @param info Parameters for the if conversion algorithm.
1402  */
1403 static int check_out_phi(phi_info_t *phi_info, const opt_if_conv_info_t *info)
1404 {
1405   ir_node *irn = phi_info->irn;
1406   ir_node *block, *nw;
1407   cond_info_t *cond_info = phi_info->cond_info;
1408   cond_t *cond;
1409   int i, arity;
1410   int muxes_made = 0;
1411   bitset_t *positions;
1412
1413   block = get_nodes_block(irn);
1414   arity = get_irn_arity(irn);
1415   positions = bitset_alloca(arity);
1416
1417   assert(is_Phi(irn));
1418   assert(get_irn_arity(irn) == get_irn_arity(block));
1419   assert(arity > 0);
1420
1421   DBG((dbg, LEVEL_2, "phi candidate: %n\n", irn));
1422
1423   list_for_each_entry(cond_t, cond, &cond_info->roots, list) {
1424     ir_node *cidom = block;
1425     ir_node *mux = NULL;
1426     cond_t *p, *head = NULL;
1427     long pos;
1428
1429     bitset_clear_all(positions);
1430
1431     DBG((dbg, LEVEL_2, "\tcond root: %n\n", cond->cond));
1432     /*
1433      * Link all conds which are in the subtree of
1434      * the current cond in the list together.
1435      */
1436     walk_conds(cond, link_conds, NULL, &head);
1437
1438     cidom = block;
1439     for(p = head; p; p = p->link) {
1440       for(i = 0; i < 2; ++i) {
1441         int pos = p->cases[i].pos;
1442         if(pos != -1)
1443           cidom = common_idom(cidom, get_nodes_block(get_irn_n(block, pos)));
1444       }
1445     }
1446
1447     DBG((dbg, LEVEL_2, "\tcommon idom: %n\n", cidom));
1448     make_mux_on_demand(irn, cidom, cond, info, &mux, positions, &muxes_made, ++cond_visited_nr);
1449
1450     if(mux) {
1451       bitset_foreach(positions, pos)
1452         set_irn_n(irn, (int) pos, mux);
1453     }
1454   }
1455
1456   /*
1457    * optimize the phi away. This can anable further runs of this
1458    * function. Look at _can_move. phis cannot be moved there.
1459    */
1460   nw = optimize_in_place_2(irn);
1461   if(nw != irn)
1462     exchange(irn, nw);
1463
1464   return muxes_made;
1465 }
1466
1467 typedef struct _cond_walk_info_t {
1468   struct obstack *obst;
1469   struct list_head cond_info_head;
1470   struct list_head phi_head;
1471 } cond_walk_info_t;
1472
1473
1474 static void annotate_cond_info_pre(ir_node *irn, void *data)
1475 {
1476   set_irn_link(irn, NULL);
1477 }
1478
1479 static void annotate_cond_info_post(ir_node *irn, void *data)
1480 {
1481   cond_walk_info_t *cwi = data;
1482
1483   /*
1484    * Check, if the node is a phi
1485    * we then compute a set of conds which are reachable from this
1486    * phi's block up to its dominator.
1487    * The set is attached to the blocks link field.
1488    */
1489   if(is_Phi(irn) && mode_is_datab(get_irn_mode(irn))) {
1490     ir_node *block = get_nodes_block(irn);
1491
1492     cond_info_t *ci = get_irn_link(block);
1493
1494     /* If the set is not yet computed, do it now. */
1495     if(!ci) {
1496       ci = obstack_alloc(cwi->obst, sizeof(*ci));
1497       ci->cond_set = new_set(cond_cmp, log2_ceil(get_irn_arity(block)));
1498       ci->first_phi = irn;
1499
1500       INIT_LIST_HEAD(&ci->roots);
1501       INIT_LIST_HEAD(&ci->list);
1502
1503       /*
1504        * Add this cond info to the list of all cond infos
1505        * in this graph. This is just done to xfree the
1506        * set easier afterwards (we save an irg_walk_graph).
1507        */
1508       list_add(&cwi->cond_info_head, &ci->list);
1509
1510       DBG((dbg, LEVEL_2, "searching conds at %n\n", irn));
1511
1512       /*
1513        * Fill the set with conds we find on the way from
1514        * the block to its dominator.
1515        */
1516       find_conds(irn, ci);
1517
1518       /*
1519        * If there where no suitable conds, delete the set
1520        * immediately and reset the set pointer to NULL
1521        */
1522       if(set_count(ci->cond_set) == 0) {
1523         del_set(ci->cond_set);
1524         list_del(&ci->list);
1525         obstack_free(cwi->obst, ci);
1526         ci = NULL;
1527       }
1528     }
1529
1530     else
1531       DBG((dbg, LEVEL_2, "conds already computed for %n (look at %n)\n", irn, ci->first_phi));
1532
1533     set_irn_link(block, ci);
1534
1535     if(ci) {
1536       phi_info_t *pi = obstack_alloc(cwi->obst, sizeof(*pi));
1537       pi->irn = irn;
1538       pi->cond_info = ci;
1539       INIT_LIST_HEAD(&pi->list);
1540       list_add(&pi->list, &cwi->phi_head);
1541     }
1542
1543   }
1544 }
1545
1546 static void dump_conds(cond_t *cond, void *env)
1547 {
1548   int i;
1549   FILE *f = env;
1550
1551   ir_fprintf(f, "node:{title:\"n%p\" label:\"%n(%d, %d)\n%n\"}\n",
1552       cond, cond->cond, cond->cases[0].pos, cond->cases[1].pos,
1553       get_nodes_block(cond->cond));
1554
1555   for(i = 0; i < 2; ++i)
1556     if(cond->cases[i].masked_by)
1557       ir_fprintf(f, "edge:{sourcename:\"n%p\" targetname:\"n%p\" label:\"%d\"}\n",
1558           cond, cond->cases[i].masked_by, i);
1559 }
1560
1561 static void vcg_dump_conds(ir_graph *irg, cond_walk_info_t *cwi)
1562 {
1563   char buf[512];
1564   FILE *f;
1565
1566   snprintf(buf, sizeof(buf), "%s-conds.vcg", get_entity_name(get_irg_entity(irg)));
1567
1568   if((f = fopen(buf, "wt")) != NULL) {
1569     cond_info_t *ci;
1570     phi_info_t *phi;
1571     cond_t *cond;
1572
1573     ir_fprintf(f, "graph:{\ndisplay_edge_labels:yes\n");
1574     list_for_each_entry(cond_info_t, ci, &cwi->cond_info_head, list) {
1575       ir_fprintf(f, "node:{title:\"n%p\" label:\"cond info\"}\n", ci);
1576       list_for_each_entry(cond_t, cond, &ci->roots, list) {
1577         walk_conds(cond, NULL, dump_conds, f);
1578         ir_fprintf(f, "edge:{sourcename:\"n%p\" targetname:\"n%p\"}\n", ci, cond);
1579       }
1580     }
1581
1582     list_for_each_entry(phi_info_t, phi, &cwi->phi_head, list) {
1583       ir_fprintf(f, "node:{title:\"n%p\" label:\"%n\n%n\"}\n",
1584           phi->irn, phi->irn, get_nodes_block(phi->irn));
1585       ir_fprintf(f, "edge:{sourcename:\"n%p\" targetname:\"n%p\"}\n", phi->irn, phi->cond_info);
1586     }
1587     fprintf(f, "}\n");
1588   }
1589 }
1590
1591 void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params)
1592 {
1593   int muxes_made = 0;
1594   struct obstack obst;
1595   phi_info_t *phi_info;
1596   cond_info_t *cond_info;
1597   cond_walk_info_t cwi;
1598
1599   opt_if_conv_info_t p;
1600
1601   if(!get_opt_if_conversion())
1602     return;
1603
1604   /* get the parameters */
1605   if (params)
1606     memcpy(&p, params, sizeof(p));
1607   else
1608     memcpy(&p, &default_info, sizeof(p));
1609
1610   if (! p.allow_mux)
1611     p.allow_mux = default_info.allow_mux;
1612
1613   obstack_init(&obst);
1614
1615   cwi.obst = &obst;
1616   INIT_LIST_HEAD(&cwi.cond_info_head);
1617   INIT_LIST_HEAD(&cwi.phi_head);
1618
1619   /* Init the debug stuff. */
1620   FIRM_DBG_REGISTER(dbg, "firm.opt.ifconv");
1621 #if 0
1622   firm_dbg_set_mask(dbg, LEVEL_1|LEVEL_2|LEVEL_3);
1623 #endif
1624
1625   /* if-conversion works better with normalized returns */
1626   normalize_one_return(irg);
1627
1628   /* Ensure, that the dominators are computed. */
1629   assure_doms(irg);
1630
1631   DBG((dbg, LEVEL_1, "if conversion for irg %s(%p)\n",
1632         get_entity_name(get_irg_entity(irg)), irg));
1633
1634   /*
1635    * Collect information about the conds pu the phis on an obstack.
1636    * It is important that phi nodes which are 'higher' (with a
1637    * lower dfs pre order) are in front of the obstack. Since they are
1638    * possibly turned in to muxes this can enable the optimization
1639    * of 'lower' ones.
1640    */
1641   irg_walk_graph(irg, annotate_cond_info_pre, annotate_cond_info_post, &cwi);
1642
1643 #if 0
1644   vcg_dump_conds(irg, &cwi);
1645 #endif
1646
1647   /* Process each suitable phi found. */
1648   list_for_each_entry(phi_info_t, phi_info, &cwi.phi_head, list) {
1649     DBG((dbg, LEVEL_2, "phi node %n\n", phi_info->irn));
1650     muxes_made += check_out_phi(phi_info, &p);
1651   }
1652
1653   list_for_each_entry(cond_info_t, cond_info, &cwi.cond_info_head, list) {
1654     del_set(cond_info->cond_set);
1655   }
1656
1657   DBG((dbg, LEVEL_1, "muxes made: %d\n", muxes_made));
1658
1659   obstack_free(&obst, NULL);
1660 }
1661
1662 #endif