Commit ce7643e4 authored by Matthias Braun's avatar Matthias Braun
Browse files

ia32: prefere != over < or > relation where possible

parent 29037764
......@@ -91,6 +91,18 @@ FIRM_API ir_tarval *computed_value(const ir_node *n);
*/
FIRM_API ir_node *optimize_in_place(ir_node *n);
/**
* checks wether 1 value is the negated other value
*/
FIRM_API int ir_is_negated_value(const ir_node *a, const ir_node *b);
/**
* (conservatively) approximates all possible relations when comparing
* the value @p left and @p right
*/
FIRM_API ir_relation ir_get_possible_cmp_relations(const ir_node *left,
const ir_node *right);
#include "end.h"
#endif
......@@ -493,7 +493,7 @@ int be_mux_is_abs(ir_node *sel, ir_node *mux_true, ir_node *mux_false)
if ((relation & ir_relation_less_greater) == 0)
return 0;
if (!is_negated_value(mux_true, mux_false))
if (!ir_is_negated_value(mux_true, mux_false))
return 0;
/* must be x cmp 0 */
......
......@@ -2007,41 +2007,49 @@ static ir_node *get_flags_node_cmp(ir_node *cmp, ia32_condition_code_t *cc_out)
{
/* must have a Cmp as input */
ir_relation relation = get_Cmp_relation(cmp);
ir_relation possible;
ir_node *l = get_Cmp_left(cmp);
ir_node *r = get_Cmp_right(cmp);
ir_mode *mode = get_irn_mode(l);
ir_node *flags;
/* check for bit-test */
if (ia32_cg_config.use_bt && (relation == ir_relation_equal
|| (mode_is_signed(mode) && relation == ir_relation_less_greater)
|| (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))) {
ir_node *l = get_Cmp_left(cmp);
ir_node *r = get_Cmp_right(cmp);
if (is_And(l)) {
ir_node *la = get_And_left(l);
ir_node *ra = get_And_right(l);
if (is_Shl(ra)) {
ir_node *tmp = la;
la = ra;
ra = tmp;
}
if (is_Shl(la)) {
ir_node *c = get_Shl_left(la);
if (is_Const_1(c) && is_Const_0(r)) {
/* (1 << n) & ra) */
ir_node *n = get_Shl_right(la);
flags = gen_bt(cmp, ra, n);
/* the bit is copied into the CF flag */
if (relation & ir_relation_equal)
*cc_out = ia32_cc_above_equal; /* test for CF=0 */
else
*cc_out = ia32_cc_below; /* test for CF=1 */
return flags;
}
|| (!mode_is_signed(mode) && ((relation & ir_relation_greater_equal) == ir_relation_greater)))
&& is_And(l)) {
ir_node *la = get_And_left(l);
ir_node *ra = get_And_right(l);
if (is_Shl(ra)) {
ir_node *tmp = la;
la = ra;
ra = tmp;
}
if (is_Shl(la)) {
ir_node *c = get_Shl_left(la);
if (is_Const_1(c) && is_Const_0(r)) {
/* (1 << n) & ra) */
ir_node *n = get_Shl_right(la);
flags = gen_bt(cmp, ra, n);
/* the bit is copied into the CF flag */
if (relation & ir_relation_equal)
*cc_out = ia32_cc_above_equal; /* test for CF=0 */
else
*cc_out = ia32_cc_below; /* test for CF=1 */
return flags;
}
}
}
/* the middle-end tries to eliminate impossible relations, so a ptr != 0
* test becomes ptr > 0. But for x86 an equal comparison is preferable to
* a >0 (we can sometimes eliminate the cmp in favor of flags produced by
* a predecessor node). So add the < bit */
possible = ir_get_possible_cmp_relations(l, r);
if (((relation & ir_relation_less) && !(possible & ir_relation_greater))
|| ((relation & ir_relation_greater) && !(possible & ir_relation_less)))
relation |= ir_relation_less_greater;
/* just do a normal transformation of the Cmp */
*cc_out = relation_to_condition_code(relation, mode);
flags = be_transform_node(cmp);
......
......@@ -447,8 +447,8 @@ static ir_tarval *computed_value_Confirm(const ir_node *n)
* gives a (conservative) estimation of possible relation when comparing
* left+right
*/
static ir_relation determine_possible_cmp_relations(const ir_node *left,
const ir_node *right)
ir_relation ir_get_possible_cmp_relations(const ir_node *left,
const ir_node *right)
{
ir_relation possible = ir_relation_true;
ir_tarval *tv_l = value_of(left);
......@@ -498,7 +498,7 @@ static ir_tarval *computed_value_Cmp(const ir_node *cmp)
{
ir_node *left = get_Cmp_left(cmp);
ir_node *right = get_Cmp_right(cmp);
ir_relation possible = determine_possible_cmp_relations(left, right);
ir_relation possible = ir_get_possible_cmp_relations(left, right);
ir_relation relation = get_Cmp_relation(cmp);
/* if none of the requested relations is possible, return false */
......@@ -3800,7 +3800,7 @@ static ir_node *transform_node_Cmp(ir_node *n)
bool changed = false;
bool changedc = false;
ir_relation relation = get_Cmp_relation(n);
ir_relation possible = determine_possible_cmp_relations(left, right);
ir_relation possible = ir_get_possible_cmp_relations(left, right);
/* mask out impossible relations */
ir_relation new_relation = relation & possible;
......@@ -4774,7 +4774,7 @@ static ir_node *transform_node_Or_Rotl(ir_node *irn_or)
/* Note: the obvious rot formulation (a << x) | (a >> (32-x)) gets
* transformed to (a << x) | (a >> -x) by transform_node_shift_modulo() */
if (!is_negated_value(c1, c2)) {
if (!ir_is_negated_value(c1, c2)) {
return irn_or;
}
......@@ -5356,7 +5356,7 @@ static ir_node *transform_node_End(ir_node *n)
return n;
} /* transform_node_End */
bool is_negated_value(ir_node *a, ir_node *b)
int ir_is_negated_value(const ir_node *a, const ir_node *b)
{
if (is_Minus(a) && get_Minus_op(a) == b)
return true;
......
......@@ -131,13 +131,6 @@ static inline ir_tarval *value_of(const ir_node *n)
*/
ir_op_ops *firm_set_default_operations(unsigned code, ir_op_ops *ops);
/**
* Returns true if a == -b
*/
bool is_negated_value(ir_node *a, ir_node *b);
/** NOTE: Survive DCE is considered a bad hack - don't use */
typedef struct survive_dce_t survive_dce_t;
......
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