* tree-flow.h (stmt_is_replaceable_p): Remove prototype.
* tree-ssa.c (ssa_is_replaceable_p): Import common bits of
is_replaceable_p from tree-ssa-ter.c
* tree-ssa.h (ssa_is_replaceable_p): Add prototype.
* tree-ssa-ter.c (is_replaceable_p, stmt_is_replaceable_p): Delete.
(ter_is_replaceable_p): 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 new
refactored ssa_is_replaceable_p.
* tree-ssa-live.h (find_replaceable_exprs, dump_replaceable_exprs): Move
prototypes to new header file.
* tree-ssa-ter.h: New file. Move prototypes here.
* tree-outof-ssa.c: Include tree-ssa-ter.h
* Makefile.in: Change Dependencies.
===================================================================
*************** 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);
===================================================================
*************** tree_ssa_strip_useless_type_conversions
}
+ /* 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;
+ }
+
+
/* Internal helper for walk_use_def_chains. VAR, FN and DATA are as
described in walk_use_def_chains.
===================================================================
*************** extern void warn_uninit (enum opt_code,
extern unsigned int warn_uninitialized_vars (bool);
extern void execute_update_addresses_taken (void);
+ /* Check to see if a stmt contains basic replaceable expressions. */
+ extern bool ssa_is_replaceable_p (gimple stmt);
+
/* Given an edge_var_map V, return the PHI arg definition. */
static inline tree
===================================================================
*************** along with GCC; see the file COPYING3.
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
they can be replaced at their use location.
n_12 = C * 10
information is tracked.
Variables which only have one use, and whose defining stmt is considered
! 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
*************** add_dependence (temp_expr_table_p tab, i
/* 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);
}
/* 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;
}
*************** process_replaceable (temp_expr_table_p t
ssa_op_iter iter;
bitmap def_vars, use_vars;
! gcc_checking_assert (is_replaceable_p (stmt, true));
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def);
ssa_op_iter iter;
bitmap def_vars, use_vars;
! gcc_checking_assert (ter_is_replaceable_p (stmt));
def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
version = SSA_NAME_VERSION (def);
*************** find_replaceable_in_bb (temp_expr_table_
if (is_gimple_debug (stmt))
continue;
! stmt_replaceable = is_replaceable_p (stmt, true);
/* Determine if this stmt finishes an existing expression. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
if (is_gimple_debug (stmt))
continue;
! 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)
===================================================================
*************** expand_expr_real_2 (sepops ops, rtx targ
}
#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)
===================================================================
*************** make_live_on_entry (tree_live_info_p liv
/* 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 */
===================================================================
***************
+ /* 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 */
===================================================================
*************** along with GCC; see the file COPYING3.
#include "dumpfile.h"
#include "diagnostic-core.h"
#include "ssaexpand.h"
+ #include "tree-ssa-ter.h"
/* FIXME: A lot of code here deals with expanding to RTL. All that code
should be in cfgexpand.c. */
===================================================================
*************** tree-into-ssa.o : tree-into-ssa.c $(TREE
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
! $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) \
$(GIMPLE_PRETTY_PRINT_H)
tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_SSA_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
! $(TREE_SSA_LIVE_H) $(BITMAP_H) $(FLAGS_H) tree-ssa-ter.h \
$(GIMPLE_PRETTY_PRINT_H)
tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_SSA_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
*************** tree-ssa-coalesce.o : tree-ssa-coalesce.
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
$(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \
! $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_SSA_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_SSA_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
$(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \
! $(EXPR_H) $(SSAEXPAND_H) $(GIMPLE_PRETTY_PRINT_H) tree-ssa-ter.h
tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_SSA_H) $(TREE_PASS_H) domwalk.h $(FLAGS_H) \