Commit 2525d4c5 authored by Matthias Braun's avatar Matthias Braun
Browse files

use operands_are_normalized when permuting Not operations on Xor inputs to...

use operands_are_normalized when permuting Not operations on Xor inputs to avoid commutative normalisation turning it back

[r27947]
parent e2a76a3b
......@@ -578,13 +578,19 @@ static ir_node *gen_Eor(ir_node *node)
ir_node *left = get_Eor_left(node);
ir_node *right = get_Eor_right(node);
/* Note: firm normalizes Not(Eor(a,b)) and Eor(Not(a),b) to Eor(a, Not(b))*/
if (is_Not(right)) {
ir_node *not_op = get_Not_op(right);
return gen_helper_binop_args(node, left, not_op, MATCH_COMMUTATIVE,
new_bd_sparc_XNor_reg,
new_bd_sparc_XNor_imm);
}
if (is_Not(left)) {
ir_node *not_op = get_Not_op(left);
return gen_helper_binop_args(node, not_op, right,
MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL,
new_bd_sparc_XNor_reg,
new_bd_sparc_XNor_imm);
}
return gen_helper_binop(node, MATCH_COMMUTATIVE, new_bd_sparc_Xor_reg,
new_bd_sparc_Xor_imm);
......
......@@ -26,6 +26,7 @@
#include "config.h"
#include <string.h>
#include <stdbool.h>
#include "irnode_t.h"
#include "irgraph_t.h"
......@@ -3645,6 +3646,33 @@ static ir_node *transform_node_And(ir_node *n)
return n;
} /* transform_node_And */
/* the order of the values is important! */
typedef enum const_class {
const_const = 0,
const_like = 1,
const_other = 2
} const_class;
static const_class classify_const(const ir_node* n)
{
if (is_Const(n)) return const_const;
if (is_irn_constlike(n)) return const_like;
return const_other;
}
/**
* Determines whether r is more constlike or has a larger index (in that order)
* than l.
*/
static bool operands_are_normalized(const ir_node *l, const ir_node *r)
{
const const_class l_order = classify_const(l);
const const_class r_order = classify_const(r);
return
l_order > r_order ||
(l_order == r_order && get_irn_idx(l) <= get_irn_idx(r));
}
/**
* Transform an Eor.
*/
......@@ -3672,16 +3700,8 @@ static ir_node *transform_node_Eor(ir_node *n)
}
}
if (a == b) {
ir_graph *irg = get_irn_irg(n);
/* a ^ a = 0 */
n = new_rd_Const(get_irn_dbg_info(n), irg, get_mode_null(mode));
DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_A_A);
return n;
}
/* normalize not nodes... ~a ^ b => a ^ ~b */
if (is_Not(a)) {
/* normalize not nodes... ~a ^ b <=> a ^ ~b */
if (is_Not(a) && operands_are_normalized(get_Not_op(a), b)) {
dbg_info *dbg = get_irn_dbg_info(n);
ir_node *block = get_nodes_block(n);
ir_node *new_not = new_rd_Not(dbg, block, b, mode);
......@@ -3689,6 +3709,14 @@ static ir_node *transform_node_Eor(ir_node *n)
n = new_rd_Eor(dbg, block, new_left, new_not, mode);
DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
return n;
} else if (is_Not(b) && !operands_are_normalized(a, get_Not_op(b))) {
dbg_info *dbg = get_irn_dbg_info(n);
ir_node *block = get_nodes_block(n);
ir_node *new_not = new_rd_Not(dbg, block, a, mode);
ir_node *new_right = get_Not_op(b);
n = new_rd_Eor(dbg, block, new_not, new_right, mode);
DBG_OPT_ALGSIM0(oldn, n, FS_OPT_EOR_TO_NOT);
return n;
}
/* x ^ 1...1 -> ~1 */
......@@ -4204,33 +4232,6 @@ static ir_node *create_zero_const(ir_mode *mode)
return cnst;
}
/* the order of the values is important! */
typedef enum const_class {
const_const = 0,
const_like = 1,
const_other = 2
} const_class;
static const_class classify_const(const ir_node* n)
{
if (is_Const(n)) return const_const;
if (is_irn_constlike(n)) return const_like;
return const_other;
}
/**
* Determines whether r is more constlike or has a larger index (in that order)
* than l.
*/
static int operands_are_normalized(const ir_node *l, const ir_node *r)
{
const const_class l_order = classify_const(l);
const const_class r_order = classify_const(r);
return
l_order > r_order ||
(l_order == r_order && get_irn_idx(l) <= get_irn_idx(r));
}
/**
* Normalizes and optimizes Cmp nodes.
*/
......
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