Commit 7a9c7d01 by Zdenek Dvorak Committed by H.J. Lu

re PR tree-optimization/32183 (reassoc2 can more extra calculations into a loop)

2007-09-07  Zdenek Dvorak  <ook@ucw.cz>

	PR tree-optimization/32183
	* Makefile.in (tree-ssa-reassoc.o): Also depend on $(CFGLOOP_H).

	* tree-ssa-reassoc.c: Include cfgloop.h.
	(is_reassociable_op): Add a loop argument and return true only
	for inside loop.
	(linearize_expr): Updated.
	(should_break_up_subtract): Likewise.
	(linearize_expr_tree): Likewise.
	(init_reassoc): Call loop_optimizer_init with
	AVOID_CFG_MODIFICATIONS.  Remove calculate_dominance_info call
	with CDI_DOMINATORS.
	(fini_reassoc): Call loop_optimizer_finalize.

From-SVN: r128262
parent a7b4caa2
2007-09-07 Zdenek Dvorak <ook@ucw.cz>
PR tree-optimization/32183
* Makefile.in (tree-ssa-reassoc.o): Also depend on $(CFGLOOP_H).
* tree-ssa-reassoc.c: Include cfgloop.h.
(is_reassociable_op): Add a loop argument and return true only
for inside loop.
(linearize_expr): Updated.
(should_break_up_subtract): Likewise.
(linearize_expr_tree): Likewise.
(init_reassoc): Call loop_optimizer_init with
AVOID_CFG_MODIFICATIONS. Remove calculate_dominance_info call
with CDI_DOMINATORS.
(fini_reassoc): Call loop_optimizer_finalize.
2007-09-07 Sterling Augustine <sterling@tensilica.com> 2007-09-07 Sterling Augustine <sterling@tensilica.com>
* config/xtensa/lib2funcs.S (__xtensa_sync_caches): Use an ISYNC even * config/xtensa/lib2funcs.S (__xtensa_sync_caches): Use an ISYNC even
...@@ -2201,7 +2201,7 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \ ...@@ -2201,7 +2201,7 @@ tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \ $(SYSTEM_H) $(TREE_H) $(GGC_H) $(DIAGNOSTIC_H) errors.h $(TIMEVAR_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\ $(TM_H) coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) tree-iterator.h\
$(BASIC_BLOCK_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) vec.h \ $(BASIC_BLOCK_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) vec.h \
alloc-pool.h pointer-set.h alloc-pool.h pointer-set.h $(CFGLOOP_H)
tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h $(DIAGNOSTIC_H) \
$(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \ $(FLAGS_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h \
......
...@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "vec.h" #include "vec.h"
#include "langhooks.h" #include "langhooks.h"
#include "pointer-set.h" #include "pointer-set.h"
#include "cfgloop.h"
/* This is a simple global reassociation pass. It is, in part, based /* This is a simple global reassociation pass. It is, in part, based
on the LLVM pass of the same name (They do some things more/less on the LLVM pass of the same name (They do some things more/less
...@@ -344,13 +345,21 @@ add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op) ...@@ -344,13 +345,21 @@ add_to_ops_vec (VEC(operand_entry_t, heap) **ops, tree op)
} }
/* Return true if STMT is reassociable operation containing a binary /* Return true if STMT is reassociable operation containing a binary
operation with tree code CODE. */ operation with tree code CODE, and is inside LOOP. */
static bool static bool
is_reassociable_op (tree stmt, enum tree_code code) is_reassociable_op (tree stmt, enum tree_code code, struct loop *loop)
{ {
if (!IS_EMPTY_STMT (stmt) basic_block bb;
&& TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
if (IS_EMPTY_STMT (stmt))
return false;
bb = bb_for_stmt (stmt);
if (!flow_bb_inside_loop_p (loop, bb))
return false;
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code
&& has_single_use (GIMPLE_STMT_OPERAND (stmt, 0))) && has_single_use (GIMPLE_STMT_OPERAND (stmt, 0)))
return true; return true;
...@@ -929,9 +938,10 @@ linearize_expr (tree stmt) ...@@ -929,9 +938,10 @@ linearize_expr (tree stmt)
tree binrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1)); tree binrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
tree binlhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0)); tree binlhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
tree newbinrhs = NULL_TREE; tree newbinrhs = NULL_TREE;
struct loop *loop = loop_containing_stmt (stmt);
gcc_assert (is_reassociable_op (binlhs, TREE_CODE (rhs)) gcc_assert (is_reassociable_op (binlhs, TREE_CODE (rhs), loop)
&& is_reassociable_op (binrhs, TREE_CODE (rhs))); && is_reassociable_op (binrhs, TREE_CODE (rhs), loop));
bsinow = bsi_for_stmt (stmt); bsinow = bsi_for_stmt (stmt);
bsirhs = bsi_for_stmt (binrhs); bsirhs = bsi_for_stmt (binrhs);
...@@ -959,9 +969,8 @@ linearize_expr (tree stmt) ...@@ -959,9 +969,8 @@ linearize_expr (tree stmt)
TREE_VISITED (stmt) = 1; TREE_VISITED (stmt) = 1;
/* Tail recurse on the new rhs if it still needs reassociation. */ /* Tail recurse on the new rhs if it still needs reassociation. */
if (newbinrhs && is_reassociable_op (newbinrhs, rhscode)) if (newbinrhs && is_reassociable_op (newbinrhs, rhscode, loop))
linearize_expr (stmt); linearize_expr (stmt);
} }
/* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return /* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return
...@@ -1046,13 +1055,14 @@ should_break_up_subtract (tree stmt) ...@@ -1046,13 +1055,14 @@ should_break_up_subtract (tree stmt)
tree binlhs = TREE_OPERAND (rhs, 0); tree binlhs = TREE_OPERAND (rhs, 0);
tree binrhs = TREE_OPERAND (rhs, 1); tree binrhs = TREE_OPERAND (rhs, 1);
tree immusestmt; tree immusestmt;
struct loop *loop = loop_containing_stmt (stmt);
if (TREE_CODE (binlhs) == SSA_NAME if (TREE_CODE (binlhs) == SSA_NAME
&& is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR)) && is_reassociable_op (SSA_NAME_DEF_STMT (binlhs), PLUS_EXPR, loop))
return true; return true;
if (TREE_CODE (binrhs) == SSA_NAME if (TREE_CODE (binrhs) == SSA_NAME
&& is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), PLUS_EXPR)) && is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), PLUS_EXPR, loop))
return true; return true;
if (TREE_CODE (lhs) == SSA_NAME if (TREE_CODE (lhs) == SSA_NAME
...@@ -1096,19 +1106,20 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) ...@@ -1096,19 +1106,20 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
bool binlhsisreassoc = false; bool binlhsisreassoc = false;
bool binrhsisreassoc = false; bool binrhsisreassoc = false;
enum tree_code rhscode = TREE_CODE (rhs); enum tree_code rhscode = TREE_CODE (rhs);
struct loop *loop = loop_containing_stmt (stmt);
TREE_VISITED (stmt) = 1; TREE_VISITED (stmt) = 1;
if (TREE_CODE (binlhs) == SSA_NAME) if (TREE_CODE (binlhs) == SSA_NAME)
{ {
binlhsdef = SSA_NAME_DEF_STMT (binlhs); binlhsdef = SSA_NAME_DEF_STMT (binlhs);
binlhsisreassoc = is_reassociable_op (binlhsdef, rhscode); binlhsisreassoc = is_reassociable_op (binlhsdef, rhscode, loop);
} }
if (TREE_CODE (binrhs) == SSA_NAME) if (TREE_CODE (binrhs) == SSA_NAME)
{ {
binrhsdef = SSA_NAME_DEF_STMT (binrhs); binrhsdef = SSA_NAME_DEF_STMT (binrhs);
binrhsisreassoc = is_reassociable_op (binrhsdef, rhscode); binrhsisreassoc = is_reassociable_op (binrhsdef, rhscode, loop);
} }
/* If the LHS is not reassociable, but the RHS is, we need to swap /* If the LHS is not reassociable, but the RHS is, we need to swap
...@@ -1159,7 +1170,8 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt) ...@@ -1159,7 +1170,8 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
} }
gcc_assert (TREE_CODE (binrhs) != SSA_NAME gcc_assert (TREE_CODE (binrhs) != SSA_NAME
|| !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs), rhscode)); || !is_reassociable_op (SSA_NAME_DEF_STMT (binrhs),
rhscode, loop));
bsinow = bsi_for_stmt (stmt); bsinow = bsi_for_stmt (stmt);
bsilhs = bsi_for_stmt (SSA_NAME_DEF_STMT (binlhs)); bsilhs = bsi_for_stmt (SSA_NAME_DEF_STMT (binlhs));
bsi_move_before (&bsilhs, &bsinow); bsi_move_before (&bsilhs, &bsinow);
...@@ -1399,6 +1411,10 @@ init_reassoc (void) ...@@ -1399,6 +1411,10 @@ init_reassoc (void)
tree param; tree param;
int *bbs = XNEWVEC (int, last_basic_block + 1); int *bbs = XNEWVEC (int, last_basic_block + 1);
/* Find the loops, so that we can prevent moving calculations in
them. */
loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
memset (&reassociate_stats, 0, sizeof (reassociate_stats)); memset (&reassociate_stats, 0, sizeof (reassociate_stats));
operand_entry_pool = create_alloc_pool ("operand entry pool", operand_entry_pool = create_alloc_pool ("operand entry pool",
...@@ -1435,7 +1451,6 @@ init_reassoc (void) ...@@ -1435,7 +1451,6 @@ init_reassoc (void)
bb_rank[bbs[i]] = ++rank << 16; bb_rank[bbs[i]] = ++rank << 16;
free (bbs); free (bbs);
calculate_dominance_info (CDI_DOMINATORS);
calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS);
broken_up_subtracts = NULL; broken_up_subtracts = NULL;
} }
...@@ -1446,7 +1461,6 @@ init_reassoc (void) ...@@ -1446,7 +1461,6 @@ init_reassoc (void)
static void static void
fini_reassoc (void) fini_reassoc (void)
{ {
if (dump_file && (dump_flags & TDF_STATS)) if (dump_file && (dump_flags & TDF_STATS))
{ {
fprintf (dump_file, "Reassociation stats:\n"); fprintf (dump_file, "Reassociation stats:\n");
...@@ -1465,6 +1479,7 @@ fini_reassoc (void) ...@@ -1465,6 +1479,7 @@ fini_reassoc (void)
free (bb_rank); free (bb_rank);
VEC_free (tree, heap, broken_up_subtracts); VEC_free (tree, heap, broken_up_subtracts);
free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS);
loop_optimizer_finalize ();
} }
/* Gate and execute functions for Reassociation. */ /* Gate and execute functions for Reassociation. */
......
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