From 78bca40d1df75b037b946d10dc1151fffc17fbf9 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Thu, 26 Sep 2013 13:38:54 +0000 Subject: [PATCH] tree-ssa-live.h (find_replaceable_exprs, [...]): Move prototypes to... 2013-09-26 Andrew MacLeod * 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 --- gcc/ChangeLog | 18 +++ gcc/cfgexpand.c | 2 +- gcc/expr.c | 20 ++- gcc/tree-flow.h | 3 - gcc/tree-outof-ssa.c | 57 ++++++++- gcc/{ssaexpand.h => tree-outof-ssa.h} | 9 +- gcc/tree-ssa-live.h | 6 - gcc/tree-ssa-ter.c | 169 +++++++++----------------- gcc/tree-ssa-ter.h | 52 ++++++++ 9 files changed, 211 insertions(+), 125 deletions(-) rename gcc/{ssaexpand.h => tree-outof-ssa.h} (90%) create mode 100644 gcc/tree-ssa-ter.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb83ea89323..f69ae29ae1b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2013-09-26 Andrew MacLeod + + * 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 * gimple.c (gimple_replace_lhs): Move to tree-ssa.c and rename. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 88e48c2a342..f76e5f20b0e 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -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" diff --git a/gcc/expr.c b/gcc/expr.c index 5949b131e41..235cd677e3a 100644 --- a/gcc/expr.c +++ b/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) diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index ee691791aae..cf96817649c 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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); diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 5ed145db024..42c90d49a18 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -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. diff --git a/gcc/ssaexpand.h b/gcc/tree-outof-ssa.h similarity index 90% rename from gcc/ssaexpand.h rename to gcc/tree-outof-ssa.h index 0bdc8d48097..d0af95f0f3b 100644 --- a/gcc/ssaexpand.h +++ b/gcc/tree-outof-ssa.h @@ -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 diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h index 8fd1e80d549..542f6a1944e 100644 --- a/gcc/tree-ssa-live.h +++ b/gcc/tree-ssa-live.h @@ -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 */ diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c index ee18cd8f164..3659cf0c428 100644 --- a/gcc/tree-ssa-ter.c +++ b/gcc/tree-ssa-ter.c @@ -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) diff --git a/gcc/tree-ssa-ter.h b/gcc/tree-ssa-ter.h new file mode 100644 index 00000000000..4565db16b86 --- /dev/null +++ b/gcc/tree-ssa-ter.h @@ -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 +. */ + +#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 +. */ + +#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 */