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