- if (val != get_Psi_default(psi)) {
- conds[j] = cond;
- vals[j] = val;
- ++j;
- }
- vals[j] = get_Psi_default(psi);
- assert(j == new_arity);
- new_psi = new_r_Psi(
- current_ir_graph, get_nodes_block(psi),
- new_arity, conds, vals, get_irn_mode(psi)
- );
- ir_fprintf(stderr, "Molded %+F into %+F\n", psi, new_psi);
- exchange(psi, new_psi);
-}
-
-
-static void optimise_psis(ir_node* node, void* env)
-{
- if (get_irn_op(node) != op_Psi) return;
-#if 1
- node = fold_psi(node);
-#endif
-#if 1
- meld_psi(node);
-#endif
-}
-
-
-void opt_if_conv(ir_graph *irg, const opt_if_conv_info_t *params)
-{
- ir_fprintf(stderr, "Running if-conversion on %+F\n", irg);
-
- dump_ir_block_graph(irg, "_00_pre");
-
- normalize_one_return(irg);
- remove_critical_cf_edges(irg);
-
- dump_ir_block_graph(irg, "_01_normal");
-
- compute_cdep(irg);
- compute_doms(irg);
-
- irg_block_walk_graph(irg, init_block_link, NULL, NULL);
- irg_walk_graph(irg, collect_phis, NULL, NULL);
- irg_block_walk_graph(irg, NULL, if_conv_walker, NULL);
-
- local_optimize_graph(irg);
- dump_ir_block_graph(irg, "_02_ifconv");
-
- irg_walk_graph(irg, NULL, optimise_psis, NULL);
-
- dump_ir_block_graph(irg, "_03_postifconv");
-
- free_dom(irg);
- free_cdep(irg);
-}
-
-#else
-
-/**
- * @file ifconv.c
- * If conversion.
- * Make Mux nodes from Conds where it its possible.
- * @author Sebastian Hack
- * @date 4.2.2005
- */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#ifdef HAVE_xmalloc_H
-#include <xmalloc.h>
-#endif
-
-#include "irgraph_t.h"
-#include "irnode_t.h"
-#include "irgwalk.h"
-#include "iropt_t.h"
-#include "irgmod.h"
-#include "irmode_t.h"
-#include "ircons_t.h"
-#include "irdom_t.h"
-#include "irgwalk.h"
-
-#include "ifconv.h"
-#include "irflag_t.h"
-
-#include "irprintf.h"
-#include "debug.h"
-#include "obst.h"
-#include "set.h"
-#include "bitset.h"
-#include "bitfiddle.h"
-#include "irhooks.h"
-#include "return.h"
-
-#define MAX_DEPTH 4
-
-/**
- * check, if a node is const and return its tarval or
- * return a default tarval.
- * @param cnst The node whose tarval to get.
- * @param or The alternative tarval, if the node is no Const.
- * @return The tarval of @p cnst, if the node is Const, @p otherwise.
- */
-static tarval *get_value_or(ir_node *cnst, tarval *or)
-{
- return get_irn_op(cnst) == op_Const ? get_Const_tarval(cnst) : or;
-}
-
-
-/**
- * Try to optimize nested muxes into a dis- or conjunction
- * of two muxes.
- * @param mux The parent mux, which has muxes as operands.
- * @return The replacement node for this mux. If the optimization is
- * successful, this might be an And or Or node, if not, its the mux
- * himself.
- */
-static ir_node *optimize_mux_chain(ir_node *mux)
-{
- int i;
- ir_node *res;
- ir_node *ops[2];
- ir_mode *mode = get_irn_mode(mux);
- tarval *null;
- tarval *minus_one;
-
- /*
- * If we have no mux, or its mode is not integer, we
- * can return.
- */
- if(get_irn_op(mux) != op_Mux || !mode_is_int(mode))
- return mux;
-
- res = mux;
- null = get_mode_null(mode);
- minus_one = tarval_sub(null, get_tarval_one(mode));
-
- ops[0] = get_Mux_false(mux);
- ops[1] = get_Mux_true(mux);
-
- for(i = 0; i < 2; ++i) {
- ir_node *a, *b, *d;
- tarval *tva, *tvb, *tvd;
- ir_node *child_mux;
-
- /*
- * A mux operand at the first position can be factored
- * out, if the operands fulfill several conditions:
- *
- * mux(c1, mux(c2, a, b), d)
- *
- * This can be made into:
- * 1) mux(c1, 0, d) | mux(c2, a, b)
- * if a | d == d and b | d == d
- *
- * 2) mux(c1, -1, d) & mux(c2, a, b)
- * if a & d == d and a & b == b
- */
- if(get_irn_op(ops[i]) == op_Mux) {
-
- child_mux = ops[i];
- a = get_Mux_false(child_mux);
- b = get_Mux_true(child_mux);
- d = ops[1 - i];
-
- /* Try the or stuff */
- tva = get_value_or(a, minus_one);
- tvb = get_value_or(b, minus_one);
- tvd = get_value_or(d, null);
-
- if(tarval_cmp(tarval_or(tva, tvd), tvd) == pn_Cmp_Eq
- && tarval_cmp(tarval_or(tvb, tvd), tvd) == pn_Cmp_Eq) {
-
- ops[i] = new_Const(mode, null);
- res = new_r_Or(current_ir_graph, get_nodes_block(mux),
- mux, child_mux, mode);
- break;
- }
-
- /* If the or didn't go, try the and stuff */
- tva = get_value_or(a, null);
- tvb = get_value_or(b, null);
- tvd = get_value_or(d, minus_one);
-
- if(tarval_cmp(tarval_and(tva, tvd), tvd) == pn_Cmp_Eq
- && tarval_cmp(tarval_and(tvb, tvd), tvd) == pn_Cmp_Eq) {
-
- ops[i] = new_Const(mode, minus_one);
- res = new_r_And(current_ir_graph, get_nodes_block(mux),
- mux, child_mux, mode);
- break;
- }
- }
- }
-
- /* recursively optimize nested muxes. */
- set_irn_n(mux, 1, optimize_mux_chain(ops[0]));
- set_irn_n(mux, 2, optimize_mux_chain(ops[1]));
-
- return res;
-}
-
-
-/***********************************************************
- * The If conversion itself.
- ***********************************************************/
-
-/** allow every Mux to be created. */
-static int default_allow_mux(ir_node *sel, ir_node *false_res, ir_node *true_res) {
- return 1;