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