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:
parent
ff2a63a749
commit
78bca40d1d
@ -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>
|
||||
|
||||
* gimple.c (gimple_replace_lhs): Move to tree-ssa.c and rename.
|
||||
|
@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "tree-inline.h"
|
||||
#include "value-prof.h"
|
||||
#include "target.h"
|
||||
#include "ssaexpand.h"
|
||||
#include "tree-outof-ssa.h"
|
||||
#include "bitmap.h"
|
||||
#include "sbitmap.h"
|
||||
#include "cfgloop.h"
|
||||
|
20
gcc/expr.c
20
gcc/expr.c
@ -49,7 +49,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "timevar.h"
|
||||
#include "df.h"
|
||||
#include "diagnostic.h"
|
||||
#include "ssaexpand.h"
|
||||
#include "tree-outof-ssa.h"
|
||||
#include "target-globals.h"
|
||||
#include "params.h"
|
||||
|
||||
@ -9126,6 +9126,24 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
|
||||
}
|
||||
#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
|
||||
expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
|
||||
enum expand_modifier modifier, rtx *alt_rtl)
|
||||
|
@ -679,9 +679,6 @@ bool fixup_noreturn_call (gimple stmt);
|
||||
/* In ipa-pure-const.c */
|
||||
void warn_function_noreturn (tree);
|
||||
|
||||
/* In tree-ssa-ter.c */
|
||||
bool stmt_is_replaceable_p (gimple);
|
||||
|
||||
/* In tree-parloops.c */
|
||||
bool parallelized_function_p (tree);
|
||||
|
||||
|
@ -30,12 +30,67 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "tree-ssa.h"
|
||||
#include "dumpfile.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
|
||||
should be in cfgexpand.c. */
|
||||
#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.
|
||||
|
@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#define _SSAEXPAND_H 1
|
||||
|
||||
#include "tree-ssa-live.h"
|
||||
#include "tree-ssa-ter.h"
|
||||
|
||||
/* This structure (of which only a singleton SA exists) is used to
|
||||
pass around information between the outof-SSA functions, cfgexpand
|
||||
@ -71,9 +72,9 @@ get_gimple_for_ssa_name (tree exp)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* In tree-outof-ssa.c. */
|
||||
void finish_out_of_ssa (struct ssaexpand *sa);
|
||||
unsigned int rewrite_out_of_ssa (struct ssaexpand *sa);
|
||||
void expand_phi_nodes (struct ssaexpand *sa);
|
||||
extern bool ssa_is_replaceable_p (gimple stmt);
|
||||
extern void finish_out_of_ssa (struct ssaexpand *sa);
|
||||
extern unsigned int rewrite_out_of_ssa (struct ssaexpand *sa);
|
||||
extern void expand_phi_nodes (struct ssaexpand *sa);
|
||||
|
||||
#endif
|
@ -325,10 +325,4 @@ make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
|
||||
/* From tree-ssa-coalesce.c */
|
||||
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 */
|
||||
|
@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "bitmap.h"
|
||||
#include "tree-ssa.h"
|
||||
#include "dumpfile.h"
|
||||
#include "tree-ssa-live.h"
|
||||
#include "tree-outof-ssa.h"
|
||||
#include "flags.h"
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
information is tracked.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
consideration in table TAB. If FREE_EXPR is true, then remove the
|
||||
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. */
|
||||
|
||||
static void
|
||||
@ -497,7 +448,7 @@ process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt)
|
||||
ssa_op_iter iter;
|
||||
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);
|
||||
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))
|
||||
continue;
|
||||
|
||||
stmt_replaceable = is_replaceable_p (stmt, true);
|
||||
stmt_replaceable = ter_is_replaceable_p (stmt);
|
||||
|
||||
/* Determine if this stmt finishes an existing expression. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
|
||||
|
52
gcc/tree-ssa-ter.h
Normal file
52
gcc/tree-ssa-ter.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user