summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-ter.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-ter.c')
-rw-r--r--gcc/tree-ssa-ter.c175
1 files changed, 66 insertions, 109 deletions
diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c
index ee18cd8f164..6090c5ff5f5 100644
--- a/gcc/tree-ssa-ter.c
+++ b/gcc/tree-ssa-ter.c
@@ -26,9 +26,15 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "gimple-pretty-print.h"
#include "bitmap.h"
-#include "tree-ssa.h"
+#include "gimple.h"
+#include "gimple-ssa.h"
+#include "tree-phinodes.h"
+#include "ssa-iterators.h"
+#include "tree-ssanames.h"
#include "dumpfile.h"
#include "tree-ssa-live.h"
+#include "tree-ssa-ter.h"
+#include "tree-outof-ssa.h"
#include "flags.h"
@@ -46,7 +52,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 +365,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 +388,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 +454,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 +569,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)