Commit 94a9f13d authored by Christoph Mallon's avatar Christoph Mallon
Browse files

be: Factorise code to skip same-width conversions.

parent b772ac48
......@@ -317,29 +317,6 @@ static inline bool mode_needs_gp_reg(ir_mode *mode)
&& mode != amd64_mode_xmm; /* mode_xmm is 128bit int at the moment */
}
static bool is_sameconv(const ir_node *node)
{
if (!is_Conv(node))
return false;
ir_mode *dest_mode = get_irn_mode(node);
if (!mode_needs_gp_reg(dest_mode))
return false;
ir_mode *src_mode = get_irn_mode(get_Conv_op(node));
if (!mode_needs_gp_reg(src_mode))
return false;
return get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
}
static ir_node *skip_sameconv(ir_node *node)
{
while (is_sameconv(node)) {
if (get_irn_n_edges(node) > 1)
break;
node = get_Conv_op(node);
}
return node;
}
static ir_node *get_initial_sp(ir_graph *irg)
{
return be_get_start_proj(irg, &start_val[REG_RSP]);
......@@ -957,7 +934,7 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
in[arity++] = be_transform_node(op1);
mode = get_mode_size_bits(mode) > 32 ? mode_gp : mode_Iu;
} else {
op1 = skip_sameconv(op1);
op1 = be_skip_sameconv(op1);
/* Use 8/16bit operations instead of doing zext/upconv */
in[arity++] = be_transform_node(op1);
......
......@@ -344,26 +344,6 @@ static bool try_encode_as_immediate(const ir_node *node, arm_immediate_t *res)
return false;
}
static bool is_sameconv(const ir_node *node)
{
if (!is_Conv(node))
return false;
if (get_irn_n_edges(node) > 1)
return false;
ir_mode *src_mode = get_irn_mode(get_Conv_op(node));
ir_mode *dst_mode = get_irn_mode(node);
return get_mode_arithmetic(src_mode) == irma_twos_complement
&& get_mode_arithmetic(dst_mode) == irma_twos_complement
&& get_mode_size_bits(src_mode) == get_mode_size_bits(dst_mode);
}
static ir_node *arm_skip_sameconv(ir_node *node)
{
while (is_sameconv(node))
node = get_Conv_op(node);
return node;
}
typedef enum {
MATCH_NONE = 0,
MATCH_COMMUTATIVE = 1 << 0, /**< commutative node */
......@@ -398,8 +378,8 @@ static ir_node *gen_int_binop_ops(ir_node *node, ir_node *op1, ir_node *op2,
op2 = be_skip_downconv(op2, true);
} else {
assert(get_mode_size_bits(get_irn_mode(node)) == 32);
op1 = arm_skip_sameconv(op1);
op2 = arm_skip_sameconv(op2);
op1 = be_skip_sameconv(op1);
op2 = be_skip_sameconv(op2);
}
arm_immediate_t imm;
......
......@@ -850,3 +850,25 @@ ir_node *be_skip_downconv(ir_node *node, bool const single_user)
}
return node;
}
ir_node *be_skip_sameconv(ir_node *node)
{
assert(mode_needs_gp_reg(get_irn_mode(node)));
for (;;) {
if (get_irn_n_edges(node) > 1) {
/* we only want to skip the conv when we're the only user
* (because this test is used in the context of address-mode selection
* and we don't want to use address mode for multiple users) */
break;
} else if (is_Conv(node)) {
ir_node *const op = get_Conv_op(node);
ir_mode *const src_mode = get_irn_mode(op);
if (!mode_needs_gp_reg(src_mode) || get_mode_size_bits(get_irn_mode(node)) != get_mode_size_bits(src_mode))
break;
node = op;
} else {
break;
}
}
return node;
}
......@@ -154,4 +154,7 @@ uint32_t be_get_tv_bits32(ir_tarval *tv, unsigned offset);
*/
ir_node *be_skip_downconv(ir_node *node, bool single_user);
/** Skip all signedness convs */
ir_node *be_skip_sameconv(ir_node *node);
#endif
......@@ -874,35 +874,6 @@ static ir_node *ia32_skip_float_downconv(ir_node *node)
return node;
}
static bool is_sameconv(ir_node *node)
{
if (!is_Conv(node))
return false;
/* we only want to skip the conv when we're the only user
* (because this test is used in the context of address-mode selection
* and we don't want to use address mode for multiple users) */
if (get_irn_n_edges(node) > 1)
return false;
ir_mode *src_mode = get_irn_mode(get_Conv_op(node));
ir_mode *dest_mode = get_irn_mode(node);
return
mode_needs_gp_reg(src_mode) &&
mode_needs_gp_reg(dest_mode) &&
get_mode_size_bits(dest_mode) == get_mode_size_bits(src_mode);
}
/** Skip all signedness convs */
static ir_node *ia32_skip_sameconv(ir_node *node)
{
while (is_sameconv(node)) {
node = get_Conv_op(node);
}
return node;
}
static ir_node *transform_sext(ir_node *node, ir_node *orig_node)
{
ir_mode *mode = get_irn_mode(node);
......@@ -989,17 +960,19 @@ static void match_arguments(ia32_address_mode_t *am, ir_node *block,
use_am = false;
}
/* we can simply skip downconvs for mode neutral nodes: the upper bits
* can be random for these operations */
if (flags & match_mode_neutral) {
op2 = be_skip_downconv(op2, true);
if (op1 != NULL) {
op1 = be_skip_downconv(op1, true);
}
} else {
op2 = ia32_skip_sameconv(op2);
if (op1 != NULL) {
op1 = ia32_skip_sameconv(op1);
if (mode_needs_gp_reg(mode)) {
if (flags & match_mode_neutral) {
/* we can simply skip downconvs for mode neutral nodes: the upper bits
* can be random for these operations */
op2 = be_skip_downconv(op2, true);
if (op1 != NULL) {
op1 = be_skip_downconv(op1, true);
}
} else {
op2 = be_skip_sameconv(op2);
if (op1 != NULL) {
op1 = be_skip_sameconv(op1);
}
}
}
......@@ -1316,7 +1289,7 @@ static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
op1 = be_skip_downconv(op1, true);
new_op1 = be_transform_node(op1);
} else {
op1 = ia32_skip_sameconv(op1);
op1 = be_skip_sameconv(op1);
if (get_mode_size_bits(mode) != 32) {
if (flags & match_upconv) {
new_op1 = transform_upconv(op1, node);
......@@ -2898,7 +2871,7 @@ static ir_node *gen_Switch(ir_node *node)
assert(get_mode_size_bits(sel_mode) <= 32);
assert(!mode_is_float(sel_mode));
sel = ia32_skip_sameconv(sel);
sel = be_skip_sameconv(sel);
if (get_mode_size_bits(sel_mode) < 32)
new_sel = transform_upconv(sel, node);
......
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