Commit acf1a376 authored by Matthias Braun's avatar Matthias Braun

irarch: Leave setup to backends

Let backends perform the irarch setup in lower_for_target(). Frontends
do not need to explicitely enable it any longer and there is no need to
keep the settings around in backend_params.
parent ec7cfdce
......@@ -12,7 +12,6 @@
#define FIRM_BE_H
#include <stdio.h>
#include "irarch.h"
#include "iroptimize.h"
#include "irmode.h"
#include "begin.h"
......@@ -104,9 +103,6 @@ typedef struct backend_params {
*/
unsigned modulo_shift;
/** Settings for architecture dependent optimizations. */
const ir_settings_arch_dep_t *dep_param;
/** Backend settings for if-conversion. */
arch_allow_ifconv_func allow_ifconv;
......
......@@ -77,7 +77,6 @@
#include "firm_types.h"
#include "heights.h"
#include "ident.h"
#include "irarch.h"
#include "ircgopt.h"
#include "irconsconfirm.h"
#include "ircons.h"
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Some machine dependent optimizations.
* @date 1.10.2004
* @author Sebastian Hack
*/
#ifndef FIRM_IR_IRARCH_H
#define FIRM_IR_IRARCH_H
#include "firm_types.h"
#include "begin.h"
/**
* @addtogroup iroptimize
* @{
*/
/**
* Optimization flags.
*/
typedef enum arch_dep_opts_t {
arch_dep_none = 0,
arch_dep_mul_to_shift = 1u << 0, /**< optimize Mul into Shift/Add/Sub */
arch_dep_div_by_const = 1u << 1, /**< optimize Div into Shift/Add/Mulh */
arch_dep_mod_by_const = 1u << 2 /**< optimize Mod into Shift/Add/Mulh */
} arch_dep_opts_t;
ENUM_BITSET(arch_dep_opts_t)
typedef struct ir_settings_arch_dep_t ir_settings_arch_dep_t;
/**
* Sets the optimizations that shall be applied.
* @param opts An optimization bit mask.
*/
FIRM_API void arch_dep_set_opts(arch_dep_opts_t opts);
/** @} */
#include "end.h"
#endif
......@@ -147,7 +147,6 @@ static const backend_params *TEMPLATE_get_backend_params(void)
.pic_supported = false,
.unaligned_memaccess_supported = false,
.modulo_shift = 32,
.dep_param = NULL,
.allow_ifconv = TEMPLATE_is_mux_allowed,
.machine_size = 32,
.mode_float_arithmetic = NULL,
......
......@@ -24,7 +24,7 @@
#include "beutil.h"
#include "debug.h"
#include "gen_amd64_regalloc_if.h"
#include "irarch_t.h"
#include "irarch.h"
#include "ircons.h"
#include "iredges_t.h"
#include "irgmod.h"
......@@ -685,8 +685,24 @@ static void amd64_generate_code(FILE *output, const char *cup_name)
pmap_destroy(amd64_constants);
}
static const ir_settings_arch_dep_t amd64_arch_dep = {
.replace_muls = true,
.replace_divs = true,
.replace_mods = true,
.allow_mulhs = true,
.allow_mulhu = true,
.also_use_subs = true,
.maximum_shifts = 4,
.highest_shift_amount = 63,
.evaluate = NULL,
.max_bits_for_mulh = 32,
};
static void amd64_lower_for_target(void)
{
ir_arch_lower(&amd64_arch_dep);
be_after_irp_transform("lower_arch-dep");
/* lower compound param handling */
lower_calls_with_compounds(LF_RETURN_HIDDEN, NULL);
be_after_irp_transform("lower-calls");
......@@ -736,23 +752,12 @@ static int amd64_is_mux_allowed(ir_node *sel, ir_node *mux_false,
return false;
}
static const ir_settings_arch_dep_t amd64_arch_dep = {
.also_use_subs = true,
.maximum_shifts = 4,
.highest_shift_amount = 63,
.evaluate = NULL,
.allow_mulhs = true,
.allow_mulhu = true,
.max_bits_for_mulh = 32,
};
static backend_params amd64_backend_params = {
.experimental = "the amd64 backend is highly experimental and unfinished (consider the ia32 backend)",
.byte_order_big_endian = false,
.pic_supported = true,
.unaligned_memaccess_supported = true,
.modulo_shift = 32,
.dep_param = &amd64_arch_dep,
.allow_ifconv = amd64_is_mux_allowed,
.machine_size = 64,
.mode_float_arithmetic = NULL, /* will be set later */
......
......@@ -23,7 +23,7 @@
#include "besched.h"
#include "betranshlp.h"
#include "gen_arm_regalloc_if.h"
#include "irarch_t.h"
#include "irarch.h"
#include "irgopt.h"
#include "irgwalk.h"
#include "irprog_t.h"
......@@ -217,8 +217,24 @@ static int arm_is_mux_allowed(ir_node *sel, ir_node *mux_false,
return false;
}
static const ir_settings_arch_dep_t arm_arch_dep = {
.replace_muls = true,
.replace_divs = true,
.replace_mods = true,
.allow_mulhs = false,
.allow_mulhu = false,
.also_use_subs = true,
.maximum_shifts = 1,
.highest_shift_amount = 31,
.evaluate = NULL,
.max_bits_for_mulh = ARM_MACHINE_SIZE,
};
static void arm_lower_for_target(void)
{
ir_arch_lower(&arm_arch_dep);
be_after_irp_transform("lower-arch-dep");
/* lower compound param handling */
lower_calls_with_compounds(LF_RETURN_HIDDEN, NULL);
be_after_irp_transform("lower-calls");
......@@ -250,22 +266,12 @@ static void arm_lower_for_target(void)
be_after_irp_transform("lower-64");
}
static const ir_settings_arch_dep_t arm_arch_dep = {
.also_use_subs = true,
.maximum_shifts = 1,
.highest_shift_amount = 31,
.evaluate = NULL,
.allow_mulhs = false,
.allow_mulhu = false,
.max_bits_for_mulh = ARM_MACHINE_SIZE,
};
static backend_params arm_backend_params = {
.experimental = "the arm backend is highly experimental and unfinished",
.byte_order_big_endian = false,
.pic_supported = false,
.unaligned_memaccess_supported = false,
.modulo_shift = ARM_MODULO_SHIFT,
.dep_param = &arm_arch_dep,
.allow_ifconv = arm_is_mux_allowed,
.machine_size = ARM_MACHINE_SIZE,
.mode_float_arithmetic = NULL,
......
......@@ -14,7 +14,7 @@
#include <stdbool.h>
#include "firm_types.h"
#include "irarch_t.h"
#include "irarch.h"
typedef struct {
/** optimize for size */
......
......@@ -1339,22 +1339,12 @@ static int ia32_is_mux_allowed(ir_node *sel, ir_node *mux_false,
return true;
}
static const ir_settings_arch_dep_t ia32_arch_dep = {
.also_use_subs = true,
.maximum_shifts = 4,
.highest_shift_amount = 63,
.evaluate = ia32_evaluate_insn,
.allow_mulhs = true,
.allow_mulhu = true,
.max_bits_for_mulh = 32,
};
static backend_params ia32_backend_params = {
.byte_order_big_endian = false,
.pic_supported = true,
.unaligned_memaccess_supported = true,
.thread_local_storage_supported = true,
.modulo_shift = 32,
.dep_param = &ia32_arch_dep,
.allow_ifconv = ia32_is_mux_allowed,
.machine_size = 32,
.mode_float_arithmetic = NULL, /* will be set later */
......@@ -1586,8 +1576,24 @@ static void ia32_lower_va_arg(ir_node *node)
be_default_lower_va_arg(node, false, 4);
}
static const ir_settings_arch_dep_t ia32_arch_dep = {
.replace_muls = true,
.replace_divs = true,
.replace_mods = true,
.allow_mulhs = true,
.allow_mulhu = true,
.also_use_subs = true,
.maximum_shifts = 4,
.highest_shift_amount = 63,
.evaluate = ia32_evaluate_insn,
.max_bits_for_mulh = 32,
};
static void ia32_lower_for_target(void)
{
ir_arch_lower(&ia32_arch_dep);
be_after_irp_transform("lower-arch-dep");
ir_mode *mode_gp = ia32_reg_classes[CLASS_ia32_gp].mode;
/* lower compound param handling
......
......@@ -13,7 +13,7 @@
#include "betranshlp.h"
#include "gen_mips_new_nodes.h"
#include "gen_mips_regalloc_if.h"
#include "irarch_t.h"
#include "irarch.h"
#include "iredges.h"
#include "irgwalk.h"
#include "irprog_t.h"
......@@ -50,7 +50,6 @@ static backend_params mips_backend_params = {
.pic_supported = false,
.unaligned_memaccess_supported = false,
.modulo_shift = MIPS_MACHINE_SIZE,
.dep_param = &mips_arch_dep,
.allow_ifconv = &mips_is_mux_allowed,
.machine_size = MIPS_MACHINE_SIZE,
.mode_float_arithmetic = NULL, /* will be set later */ // TODO
......@@ -273,6 +272,9 @@ static void mips_generate_code(FILE *const output, char const *const cup_name)
static void mips_lower_for_target(void)
{
ir_arch_lower(&mips_arch_dep);
be_after_irp_transform("lower-arch-dep");
lower_calls_with_compounds(LF_RETURN_HIDDEN | LF_DONT_LOWER_ARGUMENTS, NULL);
be_after_irp_transform("lower-calls");
......
......@@ -21,7 +21,7 @@
#include "bevarargs.h"
#include "debug.h"
#include "gen_sparc_regalloc_if.h"
#include "irarch_t.h"
#include "irarch.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "irgwalk.h"
......@@ -474,8 +474,24 @@ static void sparc_lower_va_arg(ir_node *node)
be_default_lower_va_arg(node, true, 4);
}
static const ir_settings_arch_dep_t sparc_arch_dep = {
.replace_muls = true,
.replace_divs = true,
.replace_mods = true,
.allow_mulhs = true,
.allow_mulhu = true,
.also_use_subs = true,
.maximum_shifts = 1,
.highest_shift_amount = 31,
.evaluate = NULL,
.max_bits_for_mulh = 32,
};
static void sparc_lower_for_target(void)
{
ir_arch_lower(&sparc_arch_dep);
be_after_irp_transform("lower-arch-dep");
lower_calls_with_compounds(LF_RETURN_HIDDEN, NULL);
be_after_irp_transform("lower-calls");
......@@ -529,22 +545,12 @@ static int sparc_is_mux_allowed(ir_node *sel, ir_node *mux_false,
*/
static const backend_params *sparc_get_backend_params(void)
{
static const ir_settings_arch_dep_t arch_dep = {
.also_use_subs = true,
.maximum_shifts = 1,
.highest_shift_amount = 31,
.evaluate = NULL,
.allow_mulhs = true,
.allow_mulhu = true,
.max_bits_for_mulh = 32,
};
static backend_params p = {
.byte_order_big_endian = true,
.pic_supported = false,
.unaligned_memaccess_supported = false,
.thread_local_storage_supported = true,
.modulo_shift = 32,
.dep_param = &arch_dep,
.allow_ifconv = sparc_is_mux_allowed,
.machine_size = 32,
.mode_float_arithmetic = NULL, /* will be set later */
......
......@@ -27,7 +27,6 @@
#include "irgraph_t.h"
#include "type_t.h"
#include "entity_t.h"
#include "irarch.h"
#include "irhooks.h"
#include "iredges_t.h"
#include "irmemory_t.h"
......@@ -67,8 +66,6 @@ void ir_init(void)
firm_init_memory_disambiguator();
firm_init_loop_opt();
arch_dep_set_opts(arch_dep_none);
init_execfreq();
firm_be_init();
......
......@@ -13,41 +13,46 @@
* by Youfeng Wu.
* Implements Division and Modulo by Consts from "Hackers Delight",
*/
#include "irarch.h"
#include <stdlib.h>
#include <assert.h>
#include "irnode_t.h"
#include "be.h"
#include "dbginfo_t.h"
#include "ircons.h"
#include "ircons_t.h"
#include "irflag.h"
#include "irflag_t.h"
#include "irgmod.h"
#include "irgraph_t.h"
#include "irhooks.h"
#include "irmode_t.h"
#include "irgopt.h"
#include "irnode_t.h"
#include "iropt_dbg.h"
#include "iropt_t.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "irprog_t.h"
#include "irverify.h"
#include "tv_t.h"
#include "dbginfo_t.h"
#include "iropt_dbg.h"
#include "irflag_t.h"
#include "irhooks.h"
#include "ircons.h"
#include "irarch_t.h"
#include "irflag.h"
#include "be.h"
#include "panic.h"
#include "tv_t.h"
/** The bit mask, which optimizations to apply. */
static arch_dep_opts_t opts;
static ir_settings_arch_dep_t settings;
void arch_dep_set_opts(arch_dep_opts_t the_opts)
void ir_arch_lower(ir_settings_arch_dep_t const *const new_settings)
{
opts = the_opts;
settings = *new_settings;
foreach_irp_irg(i, irg) {
optimize_graph_df(irg);
}
}
/** check, whether a mode allows a Mulh instruction. */
static int allow_Mulh(const ir_settings_arch_dep_t *params, ir_mode *mode)
static bool allow_Mulh(ir_mode *mode)
{
if (get_mode_size_bits(mode) > params->max_bits_for_mulh)
return 0;
return mode_is_signed(mode) ? params->allow_mulhs : params->allow_mulhu;
if (get_mode_size_bits(mode) > settings.max_bits_for_mulh)
return false;
return mode_is_signed(mode) ? settings.allow_mulhs : settings.allow_mulhu;
}
/**
......@@ -67,7 +72,6 @@ struct instruction {
*/
typedef struct mul_env {
struct obstack obst;
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. */
......@@ -305,7 +309,7 @@ static instruction *decompose_mul(mul_env *env, unsigned char *R, int r,
if (r <= 2)
return decompose_simple_cases(env, R, r);
if (env->params->also_use_subs) {
if (settings.also_use_subs) {
int gain = calculate_gain(R, r);
if (gain > 0) {
int r1;
......@@ -449,7 +453,7 @@ static int evaluate_insn(mul_env *env, instruction *inst)
return costs;
}
case SHIFT:
if (inst->shift_count > env->params->highest_shift_amount)
if (inst->shift_count > settings.highest_shift_amount)
env->fail = true;
if (env->n_shift <= 0)
env->fail = true;
......@@ -486,15 +490,14 @@ static ir_node *do_decomposition(ir_node *irn, ir_node *operand, ir_tarval *tv)
{
mul_env env;
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 = false;
env.n_shift = env.params->maximum_shifts;
env.evaluate = env.params->evaluate != NULL ? env.params->evaluate
: default_evaluate;
env.n_shift = settings.maximum_shifts;
env.evaluate = settings.evaluate != NULL ? settings.evaluate
: default_evaluate;
env.irg = get_irn_irg(irn);
int r;
......@@ -521,11 +524,9 @@ static ir_node *do_decomposition(ir_node *irn, ir_node *operand, ir_tarval *tv)
/* Replace Muls with Shifts and Add/Subs. */
ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn)
{
const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
/* If the architecture dependent optimizations were not initialized
or this optimization was not enabled. */
if (params == NULL || (opts & arch_dep_mul_to_shift) == 0)
if (!settings.replace_muls)
return irn;
assert(is_Mul(irn));
......@@ -887,8 +888,7 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn)
{
/* If the architecture dependent optimizations were not initialized
or this optimization was not enabled. */
const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
if (params == NULL || (opts & arch_dep_div_by_const) == 0)
if (!settings.replace_divs)
return irn;
if (!is_Div(irn))
return irn;
......@@ -965,7 +965,7 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn)
}
} else if (k != 0) {
/* other constant */
if (allow_Mulh(params, mode))
if (allow_Mulh(mode))
res = replace_div_by_mulh(irn, tv);
} else { /* k == 0 i.e. division by 1 */
res = left;
......@@ -979,8 +979,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
{
/* If the architecture dependent optimizations were not initialized
or this optimization was not enabled. */
const ir_settings_arch_dep_t *params = be_get_backend_param()->dep_param;
if (params == NULL || (opts & arch_dep_mod_by_const) == 0)
if (!settings.replace_mods)
return irn;
if (!is_Mod(irn))
return irn;
......@@ -1046,7 +1045,7 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn)
res = new_rd_And(dbg, block, left, k_node);
}
/* other constant */
} else if (allow_Mulh(params, mode)) {
} else if (allow_Mulh(mode)) {
res = replace_div_by_mulh(irn, tv);
res = new_rd_Mul(dbg, block, res, c);
res = new_rd_Sub(dbg, block, left, res);
......
......@@ -8,10 +8,11 @@
* @brief Some machine dependent optimizations.
* @author Sebastian Hack
*/
#ifndef FIRM_IR_IRARCH_T_H
#define FIRM_IR_IRARCH_T_H
#ifndef FIRM_IR_IRARCH_H
#define FIRM_IR_IRARCH_H
#include "irarch.h"
#include "firm_types.h"
#include <stdbool.h>
/**
* The Multiplication replacement can consist of the following instructions.
......@@ -41,9 +42,13 @@ typedef int (*evaluate_costs_func)(insn_kind kind, const ir_mode *mode, ir_tarva
* A parameter structure that drives the machine dependent Firm
* optimizations.
*/
struct ir_settings_arch_dep_t {
/* Mul optimization */
unsigned also_use_subs : 1; /**< Use also Subs when resolving Muls to shifts */
typedef struct ir_settings_arch_dep_t {
bool replace_muls : 1;
bool replace_divs : 1;
bool replace_mods : 1;
bool allow_mulhs : 1; /**< Use Mulhs for division by constant */
bool allow_mulhu : 1; /**< Use Mulhu for division by constant */
bool also_use_subs : 1; /**< Use Subs when resolving Muls to shifts */
unsigned maximum_shifts; /**< The maximum number of shifts that shall be inserted for a mul. */
unsigned highest_shift_amount; /**< The highest shift amount you want to
tolerate. Muls which would require a higher
......@@ -51,17 +56,9 @@ struct ir_settings_arch_dep_t {
evaluate_costs_func evaluate; /**< Evaluate the costs of a generated instruction. */
/* Div/Mod optimization */
unsigned allow_mulhs : 1; /**< Use the Mulhs operation for division by constant */
unsigned allow_mulhu : 1; /**< Use the Mulhu operation for division by constant */
unsigned max_bits_for_mulh; /**< Maximum number of bits the Mulh operation can take.
Modes with higher amount of bits will use Mulh */
};
/**
* A factory function, that provides architecture parameters for
* machine dependent optimizations.
*/
typedef const ir_settings_arch_dep_t *(*arch_dep_params_factory_t)(void);
} ir_settings_arch_dep_t;
/**
* Replaces Muls with Lea/Shifts/Add/Subs if these
......@@ -106,4 +103,10 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn);
*/
ir_node *arch_dep_replace_mod_by_const(ir_node *irn);
/**
* Initialize machine dependent mul/div/mod with constant localopts and
* run optimize_graph_df() once to do the replacements.
*/
void ir_arch_lower(ir_settings_arch_dep_t const *settings);
#endif
......@@ -27,7 +27,7 @@
#include "iropt_dbg.h"
#include "irflag_t.h"
#include "irhooks.h"
#include "irarch_t.h"
#include "irarch.h"
#include "hashptr.h"
#include "irtools.h"
#include "irhooks.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment