tree-ssa-live.h (find_replaceable_exprs, [...]): Move prototypes to...

2013-09-26  Andrew MacLeod  <amacleod@redhat.com>

	* tree-ssa-live.h (find_replaceable_exprs, dump_replaceable_exprs): Move
	prototypes to...
	* tree-ssa-ter.h: New File.  Move prototypes here.
	* tree-flow.h (stmt_is_replaceable_p): Remove prototype.
	* tree-outof-ssa.h: New. Rename ssaexpand.h, include tree-ssa-ter.h.
	* tree-outof-ssa.c (ssa_is_replaceable_p): New.  Refactor common bits
	from is_replaceable_p. 
	* tree-ssa-ter.c (is_replaceable_p, stmt_is_replaceable_p): Delete.
	(ter_is_replaceable_p): New.  Use new refactored ssa_is_replaceable_p.
	(process_replaceable): Use ter_is_replaceable_p.
	(find_replaceable_in_bb): Use ter_is_replaceable_p.
	* expr.c (stmt_is_replaceable_p): Relocate from tree-ssa-ter.c.  Use
	newly refactored ssa_is_replaceable_p.
	* cfgexpand.c: Include tree-outof-ssa.h.
	* ssaexpand.h: Delete.

From-SVN: r202946
This commit is contained in:
Andrew MacLeod 2013-09-26 13:38:54 +00:00 committed by Andrew Macleod
parent ff2a63a749
commit 78bca40d1d
9 changed files with 211 additions and 125 deletions

View File

@ -1,3 +1,21 @@
2013-09-26 Andrew MacLeod <amacleod@redhat.com>
* tree-ssa-live.h (find_replaceable_exprs, dump_replaceable_exprs): Move
prototypes to...
* tree-ssa-ter.h: New File. Move prototypes here.
* tree-flow.h (stmt_is_replaceable_p): Remove prototype.
* tree-outof-ssa.h: New. Rename ssaexpand.h, include tree-ssa-ter.h.
* tree-outof-ssa.c (ssa_is_replaceable_p): New. Refactor common bits
from is_replaceable_p.
* tree-ssa-ter.c (is_replaceable_p, stmt_is_replaceable_p): Delete.
(ter_is_replaceable_p): New. Use new refactored ssa_is_replaceable_p.
(process_replaceable): Use ter_is_replaceable_p.
(find_replaceable_in_bb): Use ter_is_replaceable_p.
* expr.c (stmt_is_replaceable_p): Relocate from tree-ssa-ter.c. Use
newly refactored ssa_is_replaceable_p.
* cfgexpand.c: Include tree-outof-ssa.h.
* ssaexpand.h: Delete.
2013-09-26 Andrew MacLeod <amacleod@redhat.com> 2013-09-26 Andrew MacLeod <amacleod@redhat.com>
* gimple.c (gimple_replace_lhs): Move to tree-ssa.c and rename. * gimple.c (gimple_replace_lhs): Move to tree-ssa.c and rename.

View File

@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h" #include "tree-inline.h"
#include "value-prof.h" #include "value-prof.h"
#include "target.h" #include "target.h"
#include "ssaexpand.h" #include "tree-outof-ssa.h"
#include "bitmap.h" #include "bitmap.h"
#include "sbitmap.h" #include "sbitmap.h"
#include "cfgloop.h" #include "cfgloop.h"

View File

@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h" #include "timevar.h"
#include "df.h" #include "df.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "ssaexpand.h" #include "tree-outof-ssa.h"
#include "target-globals.h" #include "target-globals.h"
#include "params.h" #include "params.h"
@ -9126,6 +9126,24 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
} }
#undef REDUCE_BIT_FIELD #undef REDUCE_BIT_FIELD
/* Return TRUE if expression STMT is suitable for replacement.
Never consider memory loads as replaceable, because those don't ever lead
into constant expressions. */
static bool
stmt_is_replaceable_p (gimple stmt)
{
if (ssa_is_replaceable_p (stmt))
{
/* Don't move around loads. */
if (!gimple_assign_single_p (stmt)
|| is_gimple_val (gimple_assign_rhs1 (stmt)))
return true;
}
return false;
}
rtx rtx
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl) enum expand_modifier modifier, rtx *alt_rtl)

View File

@ -679,9 +679,6 @@ bool fixup_noreturn_call (gimple stmt);
/* In ipa-pure-const.c */ /* In ipa-pure-const.c */
void warn_function_noreturn (tree); void warn_function_noreturn (tree);
/* In tree-ssa-ter.c */
bool stmt_is_replaceable_p (gimple);
/* In tree-parloops.c */ /* In tree-parloops.c */
bool parallelized_function_p (tree); bool parallelized_function_p (tree);

View File

@ -30,12 +30,67 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa.h" #include "tree-ssa.h"
#include "dumpfile.h" #include "dumpfile.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "ssaexpand.h" #include "tree-outof-ssa.h"
/* FIXME: A lot of code here deals with expanding to RTL. All that code /* FIXME: A lot of code here deals with expanding to RTL. All that code
should be in cfgexpand.c. */ should be in cfgexpand.c. */
#include "expr.h" #include "expr.h"
/* Return TRUE if expression STMT is suitable for replacement. */
bool
ssa_is_replaceable_p (gimple stmt)
{
use_operand_p use_p;
tree def;
gimple use_stmt;
/* Only consider modify stmts. */
if (!is_gimple_assign (stmt))
return false;
/* If the statement may throw an exception, it cannot be replaced. */
if (stmt_could_throw_p (stmt))
return false;
/* Punt if there is more than 1 def. */
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
if (!def)
return false;
/* Only consider definitions which have a single use. */
if (!single_imm_use (def, &use_p, &use_stmt))
return false;
/* Used in this block, but at the TOP of the block, not the end. */
if (gimple_code (use_stmt) == GIMPLE_PHI)
return false;
/* There must be no VDEFs. */
if (gimple_vdef (stmt))
return false;
/* Float expressions must go through memory if float-store is on. */
if (flag_float_store
&& FLOAT_TYPE_P (gimple_expr_type (stmt)))
return false;
/* An assignment with a register variable on the RHS is not
replaceable. */
if (gimple_assign_rhs_code (stmt) == VAR_DECL
&& DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
return false;
/* No function calls can be replaced. */
if (is_gimple_call (stmt))
return false;
/* Leave any stmt with volatile operands alone as well. */
if (gimple_has_volatile_ops (stmt))
return false;
return true;
}
/* Used to hold all the components required to do SSA PHI elimination. /* Used to hold all the components required to do SSA PHI elimination.

View File

@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define _SSAEXPAND_H 1 #define _SSAEXPAND_H 1
#include "tree-ssa-live.h" #include "tree-ssa-live.h"
#include "tree-ssa-ter.h"
/* This structure (of which only a singleton SA exists) is used to /* This structure (of which only a singleton SA exists) is used to
pass around information between the outof-SSA functions, cfgexpand pass around information between the outof-SSA functions, cfgexpand
@ -71,9 +72,9 @@ get_gimple_for_ssa_name (tree exp)
return NULL; return NULL;
} }
/* In tree-outof-ssa.c. */ extern bool ssa_is_replaceable_p (gimple stmt);
void finish_out_of_ssa (struct ssaexpand *sa); extern void finish_out_of_ssa (struct ssaexpand *sa);
unsigned int rewrite_out_of_ssa (struct ssaexpand *sa); extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa);
void expand_phi_nodes (struct ssaexpand *sa); extern void expand_phi_nodes (struct ssaexpand *sa);
#endif #endif

View File

@ -325,10 +325,4 @@ make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
/* From tree-ssa-coalesce.c */ /* From tree-ssa-coalesce.c */
extern var_map coalesce_ssa_name (void); extern var_map coalesce_ssa_name (void);
/* From tree-ssa-ter.c */
extern bitmap find_replaceable_exprs (var_map);
extern void dump_replaceable_exprs (FILE *, bitmap);
#endif /* _TREE_SSA_LIVE_H */ #endif /* _TREE_SSA_LIVE_H */

View File

@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "bitmap.h" #include "bitmap.h"
#include "tree-ssa.h" #include "tree-ssa.h"
#include "dumpfile.h" #include "dumpfile.h"
#include "tree-ssa-live.h" #include "tree-outof-ssa.h"
#include "flags.h" #include "flags.h"
@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see
information is tracked. information is tracked.
Variables which only have one use, and whose defining stmt is considered Variables which only have one use, and whose defining stmt is considered
a replaceable expression (see is_replaceable_p) are tracked to see whether a replaceable expression (see ssa_is_replaceable_p) are tracked to see whether
they can be replaced at their use location. they can be replaced at their use location.
n_12 = C * 10 n_12 = C * 10
@ -359,111 +359,6 @@ add_dependence (temp_expr_table_p tab, int version, tree var)
} }
/* Return TRUE if expression STMT is suitable for replacement.
TER is true if is_replaceable_p is called from within TER, false
when used from within stmt_is_replaceable_p, i.e. EXPAND_INITIALIZER
expansion. The differences are that with !TER some tests are skipped
to make it more aggressive (doesn't require the same bb, or for -O0
same locus and same BLOCK), on the other side never considers memory
loads as replaceable, because those don't ever lead into constant
expressions. */
static inline bool
is_replaceable_p (gimple stmt, bool ter)
{
use_operand_p use_p;
tree def;
gimple use_stmt;
location_t locus1, locus2;
tree block1, block2;
/* Only consider modify stmts. */
if (!is_gimple_assign (stmt))
return false;
/* If the statement may throw an exception, it cannot be replaced. */
if (stmt_could_throw_p (stmt))
return false;
/* Punt if there is more than 1 def. */
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
if (!def)
return false;
/* Only consider definitions which have a single use. */
if (!single_imm_use (def, &use_p, &use_stmt))
return false;
/* If the use isn't in this block, it wont be replaced either. */
if (ter && gimple_bb (use_stmt) != gimple_bb (stmt))
return false;
locus1 = gimple_location (stmt);
block1 = LOCATION_BLOCK (locus1);
locus1 = LOCATION_LOCUS (locus1);
if (gimple_code (use_stmt) == GIMPLE_PHI)
locus2 = gimple_phi_arg_location (use_stmt, PHI_ARG_INDEX_FROM_USE (use_p));
else
locus2 = gimple_location (use_stmt);
block2 = LOCATION_BLOCK (locus2);
locus2 = LOCATION_LOCUS (locus2);
if ((!optimize || optimize_debug)
&& ter
&& ((locus1 != UNKNOWN_LOCATION
&& locus1 != locus2)
|| (block1 != NULL_TREE
&& block1 != block2)))
return false;
/* Used in this block, but at the TOP of the block, not the end. */
if (gimple_code (use_stmt) == GIMPLE_PHI)
return false;
/* There must be no VDEFs. */
if (gimple_vdef (stmt))
return false;
/* Without alias info we can't move around loads. */
if ((!optimize || !ter)
&& gimple_assign_single_p (stmt)
&& !is_gimple_val (gimple_assign_rhs1 (stmt)))
return false;
/* Float expressions must go through memory if float-store is on. */
if (flag_float_store
&& FLOAT_TYPE_P (gimple_expr_type (stmt)))
return false;
/* An assignment with a register variable on the RHS is not
replaceable. */
if (gimple_assign_rhs_code (stmt) == VAR_DECL
&& DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
return false;
/* No function calls can be replaced. */
if (is_gimple_call (stmt))
return false;
/* Leave any stmt with volatile operands alone as well. */
if (gimple_has_volatile_ops (stmt))
return false;
return true;
}
/* Variant of is_replaceable_p test for use in EXPAND_INITIALIZER
expansion. */
bool
stmt_is_replaceable_p (gimple stmt)
{
return is_replaceable_p (stmt, false);
}
/* This function will remove the expression for VERSION from replacement /* This function will remove the expression for VERSION from replacement
consideration in table TAB. If FREE_EXPR is true, then remove the consideration in table TAB. If FREE_EXPR is true, then remove the
expression from consideration as well by freeing the decl uid bitmap. */ expression from consideration as well by freeing the decl uid bitmap. */
@ -487,6 +382,62 @@ finished_with_expr (temp_expr_table_p tab, int version, bool free_expr)
} }
/* Return TRUE if expression STMT is suitable for replacement.
In addition to ssa_is_replaceable_p, require the same bb, and for -O0
same locus and same BLOCK), Considers memory loads as replaceable if aliasing
is available. */
static inline bool
ter_is_replaceable_p (gimple stmt)
{
if (ssa_is_replaceable_p (stmt))
{
use_operand_p use_p;
tree def;
gimple use_stmt;
location_t locus1, locus2;
tree block1, block2;
/* Only consider definitions which have a single use. ssa_is_replaceable_p
already performed this check, but the use stmt pointer is required for
further checks. */
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
if (!single_imm_use (def, &use_p, &use_stmt))
return false;
/* If the use isn't in this block, it wont be replaced either. */
if (gimple_bb (use_stmt) != gimple_bb (stmt))
return false;
locus1 = gimple_location (stmt);
block1 = LOCATION_BLOCK (locus1);
locus1 = LOCATION_LOCUS (locus1);
if (gimple_code (use_stmt) == GIMPLE_PHI)
locus2 = gimple_phi_arg_location (use_stmt,
PHI_ARG_INDEX_FROM_USE (use_p));
else
locus2 = gimple_location (use_stmt);
block2 = LOCATION_BLOCK (locus2);
locus2 = LOCATION_LOCUS (locus2);
if ((!optimize || optimize_debug)
&& ((locus1 != UNKNOWN_LOCATION && locus1 != locus2)
|| (block1 != NULL_TREE && block1 != block2)))
return false;
/* Without alias info we can't move around loads. */
if (!optimize && gimple_assign_single_p (stmt)
&& !is_gimple_val (gimple_assign_rhs1 (stmt)))
return false;
return true;
}
return false;
}
/* Create an expression entry for a replaceable expression. */ /* Create an expression entry for a replaceable expression. */
static void static void
@ -497,7 +448,7 @@ process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt)
ssa_op_iter iter; ssa_op_iter iter;
bitmap def_vars, use_vars; bitmap def_vars, use_vars;
gcc_checking_assert (is_replaceable_p (stmt, true)); gcc_checking_assert (ter_is_replaceable_p (stmt));
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def); version = SSA_NAME_VERSION (def);
@ -612,7 +563,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
if (is_gimple_debug (stmt)) if (is_gimple_debug (stmt))
continue; continue;
stmt_replaceable = is_replaceable_p (stmt, true); stmt_replaceable = ter_is_replaceable_p (stmt);
/* Determine if this stmt finishes an existing expression. */ /* Determine if this stmt finishes an existing expression. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE) FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)

52
gcc/tree-ssa-ter.h Normal file
View File

@ -0,0 +1,52 @@
/* Header file for tree-ssa-ter.c exports.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TREE_SSA_TER_H
#define GCC_TREE_SSA_TER_H
extern bitmap find_replaceable_exprs (var_map);
extern void dump_replaceable_exprs (FILE *, bitmap);
#endif /* GCC_TREE_SSA_TER_H */
/* Header file for tree-ssa-ter.c exports.
Copyright (C) 2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_TREE_SSA_TER_H
#define GCC_TREE_SSA_TER_H
extern bitmap find_replaceable_exprs (var_map);
extern void dump_replaceable_exprs (FILE *, bitmap);
#endif /* GCC_TREE_SSA_TER_H */