From: Matthias Braun Date: Wed, 18 Aug 2010 13:37:10 +0000 (+0000) Subject: make if-conversion and archdep optimisations get their information directly from... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=18011a85e62d81f6d8d08957192fa34d03b747c5;p=libfirm make if-conversion and archdep optimisations get their information directly from the backend without frontends needing special code to transfer these infos [r27937] --- diff --git a/include/libfirm/be.h b/include/libfirm/be.h index 510ce7da9..4549368eb 100644 --- a/include/libfirm/be.h +++ b/include/libfirm/be.h @@ -29,6 +29,7 @@ #include #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 diff --git a/include/libfirm/irarch.h b/include/libfirm/irarch.h index a4fdf0828..ab1370a87 100644 --- a/include/libfirm/irarch.h +++ b/include/libfirm/irarch.h @@ -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. diff --git a/include/libfirm/iroptimize.h b/include/libfirm/iroptimize.h index 907f3f2be..cb149fee7 100644 --- a/include/libfirm/iroptimize.h +++ b/include/libfirm/iroptimize.h @@ -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 diff --git a/ir/be/arm/bearch_arm.c b/ir/be/arm/bearch_arm.c index 4c7b239f2..e868e171a 100644 --- a/ir/be/arm/bearch_arm.c +++ b/ir/be/arm/bearch_arm.c @@ -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; } diff --git a/ir/be/ia32/bearch_ia32.c b/ir/be/ia32/bearch_ia32.c index 825508d86..70706251e 100644 --- a/ir/be/ia32/bearch_ia32.c +++ b/ir/be/ia32/bearch_ia32.c @@ -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; diff --git a/ir/common/firm.c b/ir/common/firm.c index 5e08ff4a1..71ad31824 100644 --- a/ir/common/firm.c +++ b/ir/common/firm.c @@ -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(); diff --git a/ir/ir/irarch.c b/ir/ir/irarch.c index 93f24c7d1..daf62276b 100644 --- a/ir/ir/irarch.c +++ b/ir/ir/irarch.c @@ -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" @@ -47,33 +48,19 @@ #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; -} diff --git a/ir/opt/ifconv.c b/ir/opt/ifconv.c index 6aaca19c7..1d4bab051 100644 --- a/ir/opt/ifconv.c +++ b/ir/opt/ifconv.c @@ -23,7 +23,6 @@ * @author Christoph Mallon * @version $Id$ */ - #include "config.h" #include @@ -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); }