From 838a6e5160c6eb4595d414742d8a1efa83b67d2a Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Thu, 6 Sep 2007 13:09:38 +0000 Subject: [PATCH] forbid the Add(x,x) -> Mul(x,2) optimization after SALS convertion [r15696] --- include/libfirm/irflag.h | 6 ++ ir/ir/irarch.c | 4 ++ ir/ir/irflag_t.def | 3 + ir/ir/iropt.c | 131 +++++++++++++++++++++------------------ 4 files changed, 83 insertions(+), 61 deletions(-) diff --git a/include/libfirm/irflag.h b/include/libfirm/irflag.h index ca907efc3..90beacc26 100644 --- a/include/libfirm/irflag.h +++ b/include/libfirm/irflag.h @@ -335,6 +335,12 @@ void set_opt_precise_exc_context(int value); */ void set_opt_alias_analysis(int value); +/** Internal Flag, set if architecture dependent Mul to SASL chain was running. + * + * If set, some local optimizations that collide with the SASL conversion are disabled. + */ +void set_opt_arch_dep_running(int value); + /** Enable/Disable closed world assumption. * * If enabled, optimizations expect to know the "whole world", i.e. no diff --git a/ir/ir/irarch.c b/ir/ir/irarch.c index 274809ac3..93472026e 100644 --- a/ir/ir/irarch.c +++ b/ir/ir/irarch.c @@ -51,6 +51,7 @@ #include "irhooks.h" #include "ircons.h" #include "irarch.h" +#include "irflag.h" #undef DEB @@ -107,6 +108,9 @@ void arch_dep_init(arch_dep_params_factory_t factory) { void arch_dep_set_opts(arch_dep_opts_t the_opts) { opts = the_opts; + + if (opts & arch_dep_mul_to_shift) + set_opt_arch_dep_running(1); } /** check, whether a mode allows a Mulh instruction. */ diff --git a/ir/ir/irflag_t.def b/ir/ir/irflag_t.def index dfc009a83..80d06db0f 100644 --- a/ir/ir/irflag_t.def +++ b/ir/ir/irflag_t.def @@ -114,5 +114,8 @@ I_FLAG(auto_create_sync , 27, OFF) /** Enable Alias-analysis. */ I_FLAG(alias_analysis , 28, ON) +/** This flag is set while architecture dependent optimizations are running */ +I_FLAG(arch_dep_running , 29, OFF) + /** Closed world assumption. */ I_FLAG(closed_world , 31, OFF) diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index f4e199c98..7d2574705 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -1912,9 +1912,8 @@ static ir_node *transform_node_Add(ir_node *n) { return n; if (mode_is_num(mode)) { -#if 0 /* the following code leads to endless recursion when Mul are replaced by a simple instruction chain */ - if (a == b && mode_is_int(mode)) { + if (!get_opt_arch_dep_running() && a == b && mode_is_int(mode)) { ir_node *block = get_irn_n(n, -1); n = new_rd_Mul( @@ -1925,9 +1924,9 @@ static ir_node *transform_node_Add(ir_node *n) { new_r_Const_long(current_ir_graph, block, mode, 2), mode); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_A); - } else -#endif - if (get_irn_op(a) == op_Minus) { + return n; + } + if (is_Minus(a)) { n = new_rd_Sub( get_irn_dbg_info(n), current_ir_graph, @@ -1936,7 +1935,9 @@ static ir_node *transform_node_Add(ir_node *n) { get_Minus_op(a), mode); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B); - } else if (get_irn_op(b) == op_Minus) { + return n; + } + if (is_Minus(b)) { n = new_rd_Sub( get_irn_dbg_info(n), current_ir_graph, @@ -1945,77 +1946,85 @@ static ir_node *transform_node_Add(ir_node *n) { get_Minus_op(b), mode); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_A_MINUS_B); + return n; } - /* do NOT execute this code if reassociation is enabled, it does the inverse! */ - else if (!get_opt_reassociation() && get_irn_op(a) == op_Mul) { - ir_node *ma = get_Mul_left(a); - ir_node *mb = get_Mul_right(a); - - if (b == ma) { - ir_node *blk = get_irn_n(n, -1); - n = new_rd_Mul( - get_irn_dbg_info(n), current_ir_graph, blk, - ma, - new_rd_Add( - get_irn_dbg_info(n), current_ir_graph, blk, - mb, - new_r_Const_long(current_ir_graph, blk, mode, 1), - mode), - mode); - DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); - } else if (b == mb) { - ir_node *blk = get_irn_n(n, -1); - n = new_rd_Mul( - get_irn_dbg_info(n), current_ir_graph, blk, - mb, - new_rd_Add( + if (! get_opt_reassociation()) { + /* do NOT execute this code if reassociation is enabled, it does the inverse! */ + if (is_Mul(a)) { + ir_node *ma = get_Mul_left(a); + ir_node *mb = get_Mul_right(a); + + if (b == ma) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Mul( get_irn_dbg_info(n), current_ir_graph, blk, ma, - new_r_Const_long(current_ir_graph, blk, mode, 1), - mode), - mode); - DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); - } - } - /* do NOT execute this code if reassociation is enabled, it does the inverse! */ - else if (!get_opt_reassociation() && get_irn_op(b) == op_Mul) { - ir_node *ma = get_Mul_left(b); - ir_node *mb = get_Mul_right(b); - - if (a == ma) { - ir_node *blk = get_irn_n(n, -1); - n = new_rd_Mul( - get_irn_dbg_info(n), current_ir_graph, blk, - ma, - new_rd_Add( + new_rd_Add( + get_irn_dbg_info(n), current_ir_graph, blk, + mb, + new_r_Const_long(current_ir_graph, blk, mode, 1), + mode), + mode); + DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); + return n; + } else if (b == mb) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Mul( get_irn_dbg_info(n), current_ir_graph, blk, mb, - new_r_Const_long(current_ir_graph, blk, mode, 1), - mode), - mode); - DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); - } else if (a == mb) { - ir_node *blk = get_irn_n(n, -1); - n = new_rd_Mul( - get_irn_dbg_info(n), current_ir_graph, blk, - mb, - new_rd_Add( + new_rd_Add( + get_irn_dbg_info(n), current_ir_graph, blk, + ma, + new_r_Const_long(current_ir_graph, blk, mode, 1), + mode), + mode); + DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); + return n; + } + } + if (is_Mul(b)) { + ir_node *ma = get_Mul_left(b); + ir_node *mb = get_Mul_right(b); + + if (a == ma) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Mul( get_irn_dbg_info(n), current_ir_graph, blk, ma, - new_r_Const_long(current_ir_graph, blk, mode, 1), - mode), - mode); - DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); + new_rd_Add( + get_irn_dbg_info(n), current_ir_graph, blk, + mb, + new_r_Const_long(current_ir_graph, blk, mode, 1), + mode), + mode); + DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); + return n; + } + if (a == mb) { + ir_node *blk = get_irn_n(n, -1); + n = new_rd_Mul( + get_irn_dbg_info(n), current_ir_graph, blk, + mb, + new_rd_Add( + get_irn_dbg_info(n), current_ir_graph, blk, + ma, + new_r_Const_long(current_ir_graph, blk, mode, 1), + mode), + mode); + DBG_OPT_ALGSIM0(oldn, n, FS_OPT_ADD_MUL_A_X_A); + return n; + } } } /* Here we rely on constants be on the RIGHT side */ - else if (get_mode_arithmetic(mode) == irma_twos_complement && + if (get_mode_arithmetic(mode) == irma_twos_complement && is_Not(a) && classify_Const(b) == CNST_ONE) { /* ~x + 1 = -x */ ir_node *op = get_Not_op(a); ir_node *blk = get_irn_n(n, -1); n = new_rd_Minus(get_irn_dbg_info(n), current_ir_graph, blk, op, mode); DBG_OPT_ALGSIM0(oldn, n, FS_OPT_NOT_PLUS_1); + return n; } } return n; -- 2.20.1