Commit b443713c authored by Michael Beck's avatar Michael Beck
Browse files

add DeMorgan rules that reduce the number of instructions

[r15796]
parent b23a4330
......@@ -89,6 +89,7 @@ enum firmstat_optimizations_t {
FS_OPT_FP_INV_MUL, /**< x / y = x * (1.0/y) */
FS_OPT_CONST_PHI, /**< Constant evaluation on Phi */
FS_OPT_PREDICATE, /**< Predicate optimization */
FS_OPT_DEMORGAN, /**< optimization using DeMorgan's law */
FS_BE_IA32_LEA, /**< Lea was created */
FS_BE_IA32_LOAD_LEA, /**< Load merged with a Lea */
FS_BE_IA32_STORE_LEA, /**< Store merged with a Lea */
......
......@@ -107,6 +107,14 @@ int shrs1(unsigned x) {
return -(x >> 31);
}
int demorgan1(int a, int b) {
return (~a) & (~b);
}
int demorgan2(int a, int b) {
return (~a) | (~b);
}
int main(void)
{
#define TU(func,x,expect) \
......@@ -140,4 +148,6 @@ int main(void)
TU(add1, -3, -1);
TU(shr1, -3, 1);
TU(shrs1, -3, -1);
TB(demorgan1, 42, 17, ~(42|17));
TB(demorgan2, 42, 17, ~(42&17));
}
......@@ -2941,7 +2941,18 @@ static ir_node *transform_node_And(ir_node *n) {
}
}
}
}
if (is_Not(a) && is_Not(b)) {
/* ~a & ~b = ~(a|b) */
ir_node *block = get_nodes_block(n);
ir_mode *mode = get_irn_mode(n);
a = get_Not_op(a);
b = get_Not_op(b);
n = new_rd_Or(get_irn_dbg_info(n), current_ir_graph, block, a, b, mode);
n = new_rd_Not(get_irn_dbg_info(n), current_ir_graph, block, n, mode);
DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
return n;
}
n = transform_bitwise_distributive(n, transform_node_And);
......@@ -3982,11 +3993,24 @@ static ir_node *transform_node_Or(ir_node *n) {
ir_node *a = get_Or_left(n);
ir_node *b = get_Or_right(n);
if (is_Not(a) && is_Not(b)) {
/* ~a | ~b = ~(a&b) */
ir_node *block = get_nodes_block(n);
ir_mode *mode = get_irn_mode(n);
a = get_Not_op(a);
b = get_Not_op(b);
n = new_rd_And(get_irn_dbg_info(n), current_ir_graph, block, a, b, mode);
n = new_rd_Not(get_irn_dbg_info(n), current_ir_graph, block, n, mode);
DBG_OPT_ALGSIM0(oldn, n, FS_OPT_DEMORGAN);
return n;
}
/* we can evaluate 2 Projs of the same Cmp */
if(get_irn_mode(n) == mode_b && is_Proj(a) && is_Proj(b)) {
if (get_irn_mode(n) == mode_b && is_Proj(a) && is_Proj(b)) {
ir_node *pred_a = get_Proj_pred(a);
ir_node *pred_b = get_Proj_pred(b);
if(pred_a == pred_b) {
if (pred_a == pred_b) {
dbg_info *dbgi = get_irn_dbg_info(n);
ir_node *block = get_nodes_block(pred_a);
pn_Cmp pn_a = get_Proj_proj(a);
......
......@@ -107,6 +107,7 @@ static const struct {
{ FS_OPT_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
{ FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
{ FS_OPT_PREDICATE, "predicate optimization" },
{ FS_OPT_DEMORGAN, "optimization using DeMorgan's law" },
{ FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
{ FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
{ FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
......
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