#include "langhooks.h"
#include "cfgloop.h"
#include "tree-ssa-sccvn.h"
+#include "params.h"
/* TODO:
Fourth, we eliminate fully redundant expressions.
This is a simple statement walk that replaces redundant
- calculations with the now available values. */
+ calculations with the now available values. */
/* Representations of value numbers:
DEF_VEC_ALLOC_P (vuse_vec, heap);
static VEC(vuse_vec, heap) *expression_vuses;
-
+
/* Mapping from expression to id number we can use in bitmap sets. */
static VEC(tree, heap) *expressions;
static bool bitmap_set_contains_value (bitmap_set_t, tree);
static void bitmap_insert_into_set (bitmap_set_t, tree);
static bitmap_set_t bitmap_set_new (void);
-static bool is_undefined_value (tree);
static tree create_expression_by_pieces (basic_block, tree, tree);
static tree find_or_generate_expression (basic_block, tree, tree);
static inline bool
constant_expr_p (tree v)
{
- return TREE_CODE (v) != VALUE_HANDLE &&
+ return TREE_CODE (v) != VALUE_HANDLE &&
(TREE_CODE (v) == FIELD_DECL || is_gimple_min_invariant (v));
}
the phis in PRED. SEEN is a bitmap saying which expression we have
translated since we started translation of the toplevel expression.
Return NULL if we can't find a leader for each part of the
- translated expression. */
+ translated expression. */
static tree
phi_translate_1 (tree expr, bitmap_set_t set1, bitmap_set_t set2,
{
tree val;
tree def = PHI_ARG_DEF (phi, e->dest_idx);
-
+
if (is_gimple_min_invariant (def))
return def;
-
- if (is_undefined_value (def))
+
+ if (TREE_CODE (def) == SSA_NAME && ssa_undefined_value_p (def))
return NULL;
-
+
val = get_value_handle (def);
gcc_assert (val);
return def;
}
/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
- the phis in PRED.
+ the phis in PRED.
Return NULL if we can't find a leader for each part of the
- translated expression. */
+ translated expression. */
static tree
phi_translate (tree expr, bitmap_set_t set1, bitmap_set_t set2,
bitmap_set_t PA_OUT;
edge e;
edge_iterator ei;
+ unsigned long max_pa = PARAM_VALUE (PARAM_MAX_PARTIAL_ANTIC_LENGTH);
old_PA_IN = PA_OUT = NULL;
if (block_has_abnormal_pred_edge)
goto maybe_dump_sets;
+ /* If there are too many partially anticipatable values in the
+ block, phi_translate_set can take an exponential time: stop
+ before the translation starts. */
+ if (max_pa
+ && single_succ_p (block)
+ && bitmap_count_bits (PA_IN (single_succ (block))->values) > max_pa)
+ goto maybe_dump_sets;
+
old_PA_IN = PA_IN (block);
PA_OUT = bitmap_set_new ();
}
/* Return true if OP is an exception handler related operation, such as
- FILTER_EXPRor EXC_PTR_EXPR. */
+ FILTER_EXPR or EXC_PTR_EXPR. */
static bool
is_exception_related (tree op)
static bool
can_value_number_operation (tree op)
{
- return (UNARY_CLASS_P (op)
+ return (UNARY_CLASS_P (op)
&& !is_exception_related (TREE_OPERAND (op, 0)))
|| BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op)
NECESSARY (temp) = 0;
VN_INFO_GET (PHI_RESULT (temp))->valnum = PHI_RESULT (temp);
-
+
VEC_safe_push (tree, heap, inserted_exprs, temp);
FOR_EACH_EDGE (pred, ei, block->preds)
add_phi_arg (temp, avail[pred->src->index], pred);
}
-/* Return true if VAR is an SSA variable with no defining statement in
- this procedure, *AND* isn't a live-on-entry parameter. */
-
-static bool
-is_undefined_value (tree expr)
-{
- return (TREE_CODE (expr) == SSA_NAME
- && IS_EMPTY_STMT (SSA_NAME_DEF_STMT (expr))
- /* PARM_DECLs and hard registers are always defined. */
- && TREE_CODE (SSA_NAME_VAR (expr)) != PARM_DECL);
-}
-
/* Add OP to EXP_GEN (block), and possibly to the maximal set if it is
- not defined by a phi node.
+ not defined by a phi node.
PHI nodes can't go in the maximal sets because they are not in
TMP_GEN, so it is possible to get into non-monotonic situations
during ANTIC calculation, because it will *add* bits. */
{
if (!in_fre)
{
- if (TREE_CODE (op) == SSA_NAME && is_undefined_value (op))
+ if (TREE_CODE (op) == SSA_NAME && ssa_undefined_value_p (op))
return;
bitmap_value_insert_into_set (EXP_GEN (block), op);
if (TREE_CODE (op) != SSA_NAME
vh = vn_lookup_with_vuses (t, vuses);
else
vh = vn_lookup (t);
-
+
if (!vh)
return NULL;
exprset = VALUE_HANDLE_EXPR_SET (vh);
}
if (TREE_CODE (op) != TREE_LIST)
add_to_exp_gen (block, op);
-
+
if (TREE_CODE (val) == VALUE_HANDLE)
TREE_TYPE (val) = TREE_TYPE (TREE_OPERAND (vexpr, i));
lhs = make_ssa_name (storetemp, new_tree);
GIMPLE_STMT_OPERAND (new_tree, 0) = lhs;
- create_ssa_artificial_load_stmt (new_tree, stmt);
+ create_ssa_artificial_load_stmt (new_tree, stmt, false);
NECESSARY (new_tree) = 0;
VEC_safe_push (tree, heap, inserted_exprs, new_tree);
if (!valvh && !is_invariant)
{
tree defstmt = SSA_NAME_DEF_STMT (val);
-
+
gcc_assert (VN_INFO (val)->valnum == val);
/* PHI nodes can't have vuses and attempts to iterate over
their VUSE operands will crash. */
!ZERO_SSA_OPERANDS (defstmt2, SSA_OP_ALL_VIRTUALS))
gcc_assert (defstmt);
}
- valvh = vn_lookup_or_add_with_stmt (val, defstmt);
+ /* We lookup with the LHS, so do not use vn_lookup_or_add_with_stmt
+ here, as that will result in useless reference lookups. */
+ valvh = vn_lookup_or_add (val);
}
-
+
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "SCCVN says ");
fprintf (dump_file, ")\n");
}
else
- print_generic_stmt (dump_file, val, 0);
+ print_generic_stmt (dump_file, val, 0);
}
if (valvh)
return valvh;
tree valvh = NULL_TREE;
tree lhsval;
VEC (tree, gc) *vuses = NULL;
-
+
valvh = get_sccvn_value (lhs);
if (valvh)
{
vn_add (lhs, valvh);
- bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
+ bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
/* Shortcut for FRE. We have no need to create value expressions,
just want to know what values are available where. */
if (in_fre)
bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
return true;
}
-
+
lhsval = valvh ? valvh : get_value_handle (lhs);
vuses = copy_vuses_from_stmt (stmt);
STRIP_USELESS_TYPE_CONVERSION (rhs);
tree val = vn_lookup_or_add_with_vuses (newt, vuses);
vn_add (lhs, val);
}
-
+
add_to_exp_gen (block, newt);
- }
-
+ }
+
bitmap_insert_into_set (TMP_GEN (block), lhs);
bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
return true;
|| TREE_INVARIANT (rhs)
|| DECL_P (rhs))
{
-
+
if (lhsval)
{
set_expression_vuses (rhs, vuses);
AVAIL_OUT (block));
}
/* None of the rest of these can be PRE'd. */
- if (TREE_CODE (rhs) == SSA_NAME && !is_undefined_value (rhs))
+ if (TREE_CODE (rhs) == SSA_NAME && !ssa_undefined_value_p (rhs))
add_to_exp_gen (block, rhs);
return true;
}
tree def = gimple_default_def (cfun, param);
vn_lookup_or_add (def);
- if (!in_fre)
+ if (!in_fre)
{
bitmap_insert_into_set (TMP_GEN (ENTRY_BLOCK_PTR), def);
bitmap_value_insert_into_set (maximal_set, def);
}
else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
- && !ann->has_volatile_ops
- && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI
- (GIMPLE_STMT_OPERAND (stmt, 0)))
+ && !ann->has_volatile_ops
+ && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
+ && (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI
+ (GIMPLE_STMT_OPERAND (stmt, 0)))
+ && !tree_could_throw_p (stmt))
{
if (make_values_for_stmt (stmt, block))
continue;
sprime = bitmap_find_leader (AVAIL_OUT (b),
get_value_handle (lhs));
-
+
if (sprime
&& sprime != lhs
&& (TREE_CODE (*rhs_p) != SSA_NAME
init_pre (bool do_fre)
{
basic_block bb;
-
+
next_expression_id = 0;
expressions = NULL;
expression_vuses = NULL;
insert_fake_stores ();
/* Collect and value number expressions computed in each basic block. */
- run_scc_vn ();
+ if (!run_scc_vn ())
+ {
+ if (!do_fre)
+ remove_dead_inserted_code ();
+ fini_pre ();
+ return;
+ }
switch_to_PRE_table ();
compute_avail ();
do_pre (void)
{
execute_pre (false);
- return 0;
+ return TODO_rebuild_alias;
}
static bool