make if-conversion and archdep optimisations get their information directly from...
authorMatthias Braun <matze@braunis.de>
Wed, 18 Aug 2010 13:37:10 +0000 (13:37 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 18 Aug 2010 13:37:10 +0000 (13:37 +0000)
[r27937]

include/libfirm/be.h
include/libfirm/irarch.h
include/libfirm/iroptimize.h
ir/be/arm/bearch_arm.c
ir/be/ia32/bearch_ia32.c
ir/common/firm.c
ir/ir/irarch.c
ir/opt/ifconv.c

index 510ce7d..4549368 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include "irarch.h"
 #include "lowering.h"
+#include "iroptimize.h"
 #include "begin.h"
 
 typedef enum {
@@ -77,7 +78,7 @@ typedef struct backend_params {
        void *create_intrinsic_ctx;
 
        /** Backend settings for if-conversion. */
-       const ir_settings_if_conv_t *if_conv_info;
+       arch_allow_ifconv_func allow_ifconv;
 
        /**
         * some backends like x87 can only do arithmetic in a specific float
index a4fdf08..ab1370a 100644 (file)
@@ -79,11 +79,6 @@ struct ir_settings_arch_dep_t {
  */
 typedef const ir_settings_arch_dep_t *(*arch_dep_params_factory_t)(void);
 
-/**
- * A default parameter factory for testing purposes.
- */
-FIRM_API const ir_settings_arch_dep_t *arch_dep_default_factory(void);
-
 /**
  * Optimization flags.
  */
@@ -94,15 +89,6 @@ typedef enum {
        arch_dep_mod_by_const = 4   /**< optimize Mod into Shift/Add/Mulh */
 } arch_dep_opts_t;
 
-/**
- * Initialize the machine dependent optimizations.
- * @param factory   A factory that delivers parameters for these
- *                  optimizations. If NULL is passed, or this method
- *                  is not called, the machine dependent optimizations
- *                  are not enabled at all.
- */
-FIRM_API void arch_dep_init(arch_dep_params_factory_t factory);
-
 /**
  * Set the optimizations that shall be applied.
  * @param opts An optimization bit mask.
index 907f3f2..cb149fe 100644 (file)
@@ -254,38 +254,24 @@ FIRM_API ir_graph_pass_t *do_gvn_pre_pass(const char *name);
 typedef int (*arch_allow_ifconv_func)(ir_node *sel, ir_node *mux_false,
                                       ir_node *mux_true);
 
-/**
- * The parameters structure.
- */
-struct ir_settings_if_conv_t {
-       int                 max_depth;       /**< The maximum depth up to which expressions
-                                              are examined when it has to be decided if they
-                                              can be placed into another block. */
-       arch_allow_ifconv_func allow_ifconv; /**< Evaluator function, if not set all possible Psi
-                                              nodes will be created. */
-};
-
 /**
  * Perform If conversion on a graph.
  *
  * @param irg The graph.
- * @param params The parameters for the if conversion.
  *
  * Cannot handle blocks with Bad control predecessors, so call it after control
  * flow optimization.
  */
-FIRM_API void opt_if_conv(ir_graph *irg, const ir_settings_if_conv_t *params);
+FIRM_API void opt_if_conv(ir_graph *irg);
 
 /**
  * Creates an ir_graph pass for opt_if_conv().
  *
  * @param name     the name of this pass or NULL
- * @param params   The parameters for the if conversion.
  *
  * @return  the newly created ir_graph pass
  */
-FIRM_API ir_graph_pass_t *opt_if_conv_pass(
-       const char *name, const ir_settings_if_conv_t *params);
+FIRM_API ir_graph_pass_t *opt_if_conv_pass(const char *name);
 
 /**
  * Tries to reduce dependencies for memory nodes where possible by parllelizing
index 4c7b239..e868e17 100644 (file)
@@ -680,10 +680,6 @@ static int arm_is_valid_clobber(const char *clobber)
  */
 static const backend_params *arm_get_libfirm_params(void)
 {
-       static const ir_settings_if_conv_t ifconv = {
-               4,                    /* maxdepth, doesn't matter for Psi-conversion */
-               arm_is_mux_allowed   /* allows or disallows Mux creation for given selector */
-       };
        static ir_settings_arch_dep_t ad = {
                1,    /* allow subs */
                1,        /* Muls are fast enough on ARM but ... */
@@ -696,10 +692,10 @@ static const backend_params *arm_get_libfirm_params(void)
        static backend_params p = {
                1,     /* need dword lowering */
                0,     /* don't support inline assembler yet */
-               NULL,  /* will be set later */
+               &ad,   /* will be set later */
                NULL,  /* but yet no creator function */
                NULL,  /* context for create_intrinsic_fkt */
-               NULL,  /* ifconv_info will be set below */
+               arm_is_mux_allowed, /* allow_ifconv function */
                NULL,  /* float arithmetic mode (TODO) */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
@@ -707,8 +703,6 @@ static const backend_params *arm_get_libfirm_params(void)
                4      /* alignment of stack parameter */
        };
 
-       p.dep_param    = &ad;
-       p.if_conv_info = &ifconv;
        return &p;
 }
 
index 825508d..7070625 100644 (file)
@@ -2366,10 +2366,6 @@ static ir_node *ia32_create_trampoline_fkt(ir_node *block, ir_node *mem, ir_node
  */
 static const backend_params *ia32_get_libfirm_params(void)
 {
-       static const ir_settings_if_conv_t ifconv = {
-               4,                    /* maxdepth, doesn't matter for Mux-conversion */
-               ia32_is_mux_allowed   /* allows or disallows Mux creation for given selector */
-       };
        static const ir_settings_arch_dep_t ad = {
                1,                   /* also use subs */
                4,                   /* maximum shifts */
@@ -2385,8 +2381,8 @@ static const backend_params *ia32_get_libfirm_params(void)
                1,     /* support inline assembly */
                NULL,  /* will be set later */
                ia32_create_intrinsic_fkt,
-               &intrinsic_env,  /* context for ia32_create_intrinsic_fkt */
-               NULL,  /* ifconv info will be set below */
+               &intrinsic_env,      /* context for ia32_create_intrinsic_fkt */
+               ia32_is_mux_allowed, /* ifconv info will be set below */
                NULL,  /* float arithmetic mode, will be set below */
                12,    /* size of trampoline code */
                4,     /* alignment of trampoline code */
@@ -2401,7 +2397,6 @@ static const backend_params *ia32_get_libfirm_params(void)
        init_asm_constraints();
 
        p.dep_param    = &ad;
-       p.if_conv_info = &ifconv;
        if (! ia32_cg_config.use_sse2)
                p.mode_float_arithmetic = mode_E;
        return &p;
index 5e08ff4..71ad318 100644 (file)
@@ -137,7 +137,6 @@ void ir_init(const firm_parameter_t *param)
        firm_init_loop_opt();
 
        /* Init architecture dependent optimizations. */
-       arch_dep_init(arch_dep_default_factory);
        arch_dep_set_opts(0);
 
        init_irnode();
index 93f24c7..daf6227 100644 (file)
@@ -24,7 +24,8 @@
  * @author  Sebastian Hack, Michael Beck
  * @version $Id$
  *
- * Implements "Strength Reduction of Multiplications by Integer Constants" by Youfeng Wu.
+ * Implements "Strength Reduction of Multiplications by Integer Constants"
+ * by Youfeng Wu.
  * Implements Division and Modulo by Consts from "Hackers Delight",
  */
 #include "config.h"
 #include "ircons.h"
 #include "irarch.h"
 #include "irflag.h"
+#include "be.h"
 #include "error.h"
 
-#undef DEB
-
-#define MAX_BITSTR 64
-
-/** The params got from the factory in arch_dep_init(...). */
-static const ir_settings_arch_dep_t *params = NULL;
-
 /** The bit mask, which optimizations to apply. */
 static arch_dep_opts_t opts;
 
-void arch_dep_init(arch_dep_params_factory_t factory)
-{
-       opts = arch_dep_none;
-
-       if (factory != NULL)
-               params = factory();
-}
-
 void arch_dep_set_opts(arch_dep_opts_t the_opts)
 {
        opts = the_opts;
 }
 
 /** check, whether a mode allows a Mulh instruction. */
-static int allow_Mulh(ir_mode *mode)
+static int allow_Mulh(const ir_settings_arch_dep_t *params, ir_mode *mode)
 {
        if (get_mode_size_bits(mode) > params->max_bits_for_mulh)
                return 0;
@@ -97,6 +84,7 @@ struct instruction {
  */
 typedef struct mul_env {
        struct obstack obst;       /**< an obstack for local space. */
+       const ir_settings_arch_dep_t *params;
        ir_mode        *mode;      /**< the mode of the multiplication constant */
        unsigned       bits;       /**< number of bits in the mode */
        unsigned       max_S;      /**< the maximum LEA shift value. */
@@ -353,7 +341,7 @@ static instruction *decompose_mul(mul_env *env, unsigned char *R, int r, tarval
        if (r <= 2)
                return decompose_simple_cases(env, R, r, N);
 
-       if (params->also_use_subs) {
+       if (env->params->also_use_subs) {
                gain = calculate_gain(R, r);
                if (gain > 0) {
                        instruction *instr1, *instr2;
@@ -499,7 +487,7 @@ static int evaluate_insn(mul_env *env, instruction *inst)
                inst->costs = costs;
                return costs;
        case SHIFT:
-               if (inst->shift_count > params->highest_shift_amount)
+               if (inst->shift_count > env->params->highest_shift_amount)
                        env->fail = 1;
                if (env->n_shift <= 0)
                        env->fail = 1;
@@ -540,13 +528,14 @@ static ir_node *do_decomposition(ir_node *irn, ir_node *operand, tarval *tv)
        int           mul_costs;
 
        obstack_init(&env.obst);
+       env.params   = be_get_backend_param()->dep_param;
        env.mode     = get_tarval_mode(tv);
        env.bits     = (unsigned)get_mode_size_bits(env.mode);
        env.max_S    = 3;
        env.root     = emit_ROOT(&env, operand);
        env.fail     = 0;
-       env.n_shift  = params->maximum_shifts;
-       env.evaluate = params->evaluate != NULL ? params->evaluate : default_evaluate;
+       env.n_shift  = env.params->maximum_shifts;
+       env.evaluate = env.params->evaluate != NULL ? env.params->evaluate : default_evaluate;
 
        R = value_to_condensed(&env, tv, &r);
        inst = decompose_mul(&env, R, r, tv);
@@ -577,6 +566,7 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn)
        ir_node *right;
        ir_node *operand;
        tarval  *tv;
+       const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
 
 
        /* If the architecture dependent optimizations were not initialized
@@ -900,6 +890,7 @@ static ir_node *replace_div_by_mulh(ir_node *div, tarval *tv)
 /* Replace Divs with Shifts and Add/Subs and Mulh. */
 ir_node *arch_dep_replace_div_by_const(ir_node *irn)
 {
+       const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
        ir_node *res  = irn;
 
        /* If the architecture dependent optimizations were not initialized
@@ -984,7 +975,7 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn)
                        }
                } else {
                        /* other constant */
-                       if (allow_Mulh(mode))
+                       if (allow_Mulh(params, mode))
                                res = replace_div_by_mulh(irn, tv);
                }
        }
@@ -998,6 +989,7 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn)
 /* Replace Mods with Shifts and Add/Subs and Mulh. */
 ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
 {
+       const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
        ir_node *res  = irn;
 
        /* If the architecture dependent optimizations were not initialized
@@ -1071,7 +1063,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
                        }
                } else {
                        /* other constant */
-                       if (allow_Mulh(mode)) {
+                       if (allow_Mulh(params, mode)) {
                                res = replace_div_by_mulh(irn, tv);
 
                                res = new_rd_Mul(dbg, block, res, c, mode);
@@ -1092,6 +1084,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
 /* Replace DivMods with Shifts and Add/Subs and Mulh. */
 void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn)
 {
+       const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
        *div = *mod = NULL;
 
        /* If the architecture dependent optimizations were not initialized
@@ -1181,7 +1174,7 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn
                        }
                } else {
                        /* other constant */
-                       if (allow_Mulh(mode)) {
+                       if (allow_Mulh(params, mode)) {
                                ir_node *t;
 
                                *div = replace_div_by_mulh(irn, tv);
@@ -1198,21 +1191,3 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn
        if (*div)
                hook_arch_dep_replace_division_by_const(irn);
 }
-
-
-static const ir_settings_arch_dep_t default_params = {
-       1,  /* also use subs */
-       4,  /* maximum shifts */
-       31, /* maximum shift amount */
-       default_evaluate,  /* default evaluator */
-
-       0,  /* allow Mulhs */
-       0,  /* allow Mulus */
-       32  /* Mulh allowed up to 32 bit */
-};
-
-/* A default parameter factory for testing purposes. */
-const ir_settings_arch_dep_t *arch_dep_default_factory(void)
-{
-       return &default_params;
-}
index 6aaca19..1d4bab0 100644 (file)
@@ -23,7 +23,6 @@
  * @author  Christoph Mallon
  * @version $Id$
  */
-
 #include "config.h"
 
 #include <assert.h>
@@ -40,8 +39,8 @@
 #include "irtools.h"
 #include "array_t.h"
 #include "irpass_t.h"
+#include "be.h"
 
-// debug
 #include "irdump.h"
 #include "debug.h"
 
@@ -49,8 +48,8 @@
  * Environment for if-conversion.
  */
 typedef struct walker_env {
-       const ir_settings_if_conv_t *params; /**< Conversion parameter. */
-       int                         changed; /**< Set if the graph was changed. */
+       arch_allow_ifconv_func allow_ifconv;
+       bool                   changed; /**< Set if the graph was changed. */
 } walker_env;
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg);
@@ -67,14 +66,6 @@ static int default_allow_ifconv(ir_node *sel, ir_node *mux_false,
        return 0;
 }
 
-/**
- * Default options.
- */
-static const ir_settings_if_conv_t default_info = {
-       0,    /* doesn't matter for Mux */
-       default_allow_ifconv
-};
-
 /**
  * Returns non-zero if a Block can be emptied.
  *
@@ -357,7 +348,7 @@ restart:
                                                mux_true  = get_Phi_pred(p, i);
                                                mux_false = get_Phi_pred(p, j);
                                        }
-                                       if (!env->params->allow_ifconv(sel, mux_false, mux_true)) {
+                                       if (!env->allow_ifconv(sel, mux_false, mux_true)) {
                                                supported = false;
                                                break;
                                        }
@@ -369,7 +360,7 @@ restart:
                                        cond, projx0, projx1
                                ));
 
-                               env->changed = 1;
+                               env->changed = true;
                                prepare_path(block, i, dependency);
                                prepare_path(block, j, dependency);
                                arity = get_irn_arity(block);
@@ -485,13 +476,17 @@ static void collect_phis(ir_node *node, void *env)
        }
 }
 
-void opt_if_conv(ir_graph *irg, const ir_settings_if_conv_t *params)
+void opt_if_conv(ir_graph *irg)
 {
-       walker_env env;
+       walker_env            env;
+       const backend_params *be_params = be_get_backend_param();
 
        /* get the parameters */
-       env.params  = (params != NULL ? params : &default_info);
-       env.changed = 0;
+       if (be_params->allow_ifconv != NULL)
+               env.allow_ifconv = be_params->allow_ifconv;
+       else
+               env.allow_ifconv = default_allow_ifconv;
+       env.changed = false;
 
        FIRM_DBG_REGISTER(dbg, "firm.opt.ifconv");
 
@@ -523,27 +518,7 @@ void opt_if_conv(ir_graph *irg, const ir_settings_if_conv_t *params)
        free_cdep(irg);
 }
 
-struct pass_t {
-       ir_graph_pass_t             pass;
-       const ir_settings_if_conv_t *params;
-};
-
-/**
- * Wrapper for running opt_if_conv() as an ir_graph pass.
- */
-static int pass_wrapper(ir_graph *irg, void *context)
-{
-       struct pass_t *pass = context;
-       opt_if_conv(irg, pass->params);
-       return 0;
-}
-
-ir_graph_pass_t *opt_if_conv_pass(const char *name,
-                                  const ir_settings_if_conv_t *params)
+ir_graph_pass_t *opt_if_conv_pass(const char *name)
 {
-       struct pass_t *pass = XMALLOCZ(struct pass_t);
-       pass->params = params;
-
-       return def_graph_pass_constructor(
-               &pass->pass, name ? name : "ifconv", pass_wrapper);
+       return def_graph_pass(name ? name : "ifconv", opt_if_conv);
 }