Commit 4be314ae authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Micro optimisation of the day: Remove ia32_Test, which tests the high result of ia32_Mul.

[r22480]
parent 8196d8e3
......@@ -72,25 +72,25 @@ static void copy_mark(const ir_node *old, ir_node *new)
set_ia32_is_remat(new);
}
typedef enum produces_flag_t {
produces_no_flag,
produces_flag_zero,
produces_flag_carry
} produces_flag_t;
/**
* Returns non-zero if the given node produces
* a zero flag.
* Return which usable flag the given node produces
*
* @param node the node to check
* @param pn if >= 0, the projection number of the used result
* @param pn the projection number of the used result
*/
static int produces_zero_flag(ir_node *node, int pn)
static produces_flag_t produces_test_flag(ir_node *node, int pn)
{
ir_node *count;
const ia32_immediate_attr_t *imm_attr;
if (!is_ia32_irn(node))
return 0;
if (pn >= 0) {
if (pn != pn_ia32_res)
return 0;
}
return produces_no_flag;
switch (get_ia32_irn_opcode(node)) {
case iro_ia32_Add:
......@@ -103,7 +103,7 @@ static int produces_zero_flag(ir_node *node, int pn)
case iro_ia32_Neg:
case iro_ia32_Inc:
case iro_ia32_Dec:
return 1;
break;
case iro_ia32_ShlD:
case iro_ia32_ShrD:
......@@ -121,19 +121,25 @@ check_shift_amount:
/* when shift count is zero the flags are not affected, so we can only
* do this for constants != 0 */
if (!is_ia32_Immediate(count))
return 0;
return produces_no_flag;
imm_attr = get_ia32_immediate_attr_const(count);
if (imm_attr->symconst != NULL)
return 0;
return produces_no_flag;
if ((imm_attr->offset & 0x1f) == 0)
return 0;
return 1;
return produces_no_flag;
break;
case iro_ia32_Mul:
return pn == pn_ia32_Mul_res_high ?
produces_flag_carry : produces_no_flag;
default:
break;
return produces_no_flag;
}
return 0;
return pn == pn_ia32_res ?
produces_flag_zero : produces_no_flag;
}
/**
......@@ -248,7 +254,7 @@ static void peephole_ia32_Test(ir_node *node)
ir_node *flags_proj;
ir_node *block;
ir_mode *flags_mode;
int pn = -1;
int pn = pn_ia32_res;
ir_node *schedpoint;
const ir_edge_t *edge;
......@@ -295,8 +301,27 @@ static void peephole_ia32_Test(ir_node *node)
}
}
if(!produces_zero_flag(left, pn))
switch (produces_test_flag(left, pn)) {
case produces_flag_zero:
break;
case produces_flag_carry:
foreach_out_edge(node, edge) {
ir_node *user = get_edge_src_irn(edge);
int pnc = get_ia32_condcode(user);
switch (pnc) {
case pn_Cmp_Eq: pnc = pn_Cmp_Ge | ia32_pn_Cmp_unsigned; break;
case pn_Cmp_Lg: pnc = pn_Cmp_Lt | ia32_pn_Cmp_unsigned; break;
default: panic("unexpected pn");
}
set_ia32_condcode(user, pnc);
}
break;
default:
return;
}
left = turn_into_mode_t(left);
......
......@@ -434,10 +434,10 @@ Mul => {
# very strict constraints
state => "exc_pinned",
reg_req => { in => [ "gp", "gp", "none", "eax", "gp" ],
out => [ "eax", "edx", "none" ] },
out => [ "eax", "flags", "edx", "none" ] },
ins => [ "base", "index", "mem", "left", "right" ],
emit => '. mul%M %unop4',
outs => [ "res_low", "res_high", "M" ],
outs => [ "res_low", "flags", "res_high", "M" ],
am => "source,binary",
latency => 10,
units => [ "GP" ],
......@@ -449,7 +449,7 @@ l_Mul => {
# very strict constraints
op_flags => "C",
cmp_attr => "return 1;",
outs => [ "EAX", "EDX", "M" ],
outs => [ "EAX", "flags", "EDX", "M" ],
arity => 2
},
......
Supports Markdown
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