#include <stdio.h>
#include "irarch.h"
#include "lowering.h"
+#include "iroptimize.h"
#include "begin.h"
typedef enum {
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
*/
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.
*/
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.
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
*/
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 ... */
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 */
4 /* alignment of stack parameter */
};
- p.dep_param = &ad;
- p.if_conv_info = &ifconv;
return &p;
}
*/
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 */
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 */
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;
firm_init_loop_opt();
/* Init architecture dependent optimizations. */
- arch_dep_init(arch_dep_default_factory);
arch_dep_set_opts(0);
init_irnode();
* @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;
*/
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. */
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;
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;
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);
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
/* 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
}
} else {
/* other constant */
- if (allow_Mulh(mode))
+ if (allow_Mulh(params, mode))
res = replace_div_by_mulh(irn, tv);
}
}
/* 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
}
} 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);
/* 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
}
} else {
/* other constant */
- if (allow_Mulh(mode)) {
+ if (allow_Mulh(params, mode)) {
ir_node *t;
*div = replace_div_by_mulh(irn, tv);
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;
-}
* @author Christoph Mallon
* @version $Id$
*/
-
#include "config.h"
#include <assert.h>
#include "irtools.h"
#include "array_t.h"
#include "irpass_t.h"
+#include "be.h"
-// debug
#include "irdump.h"
#include "debug.h"
* 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);
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.
*
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;
}
cond, projx0, projx1
));
- env->changed = 1;
+ env->changed = true;
prepare_path(block, i, dependency);
prepare_path(block, j, dependency);
arity = get_irn_arity(block);
}
}
-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");
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);
}