expressions are removed from AVAIL_EXPRS. Else we may change the
hash code for an expression and be unable to find/remove it from
AVAIL_EXPRS. */
-typedef gimple *gimple_p;
-DEF_VEC_P(gimple_p);
-DEF_VEC_ALLOC_P(gimple_p,heap);
-
static VEC(gimple_p,heap) *stmts_to_rescan;
/* Structure for entries in the expression hash table. */
tree_ssa_dominator_optimize (void)
{
struct dom_walk_data walk_data;
- unsigned int i;
memset (&opt_stats, 0, sizeof (opt_stats));
that we update the loop info. */
loop_optimizer_init (LOOPS_HAVE_SIMPLE_LATCHES);
+ /* Initialize the value-handle array. */
+ threadedge_initialize_values ();
+
/* We need accurate information regarding back edges in the CFG
for jump threading; this may include back edges that are not part of
a single loop. */
bitmap_zero (need_eh_cleanup);
}
- /* Finally, remove everything except invariants in SSA_NAME_VALUE.
-
- Long term we will be able to let everything in SSA_NAME_VALUE
- persist. However, for now, we know this is the safe thing to do. */
- for (i = 0; i < num_ssa_names; i++)
- {
- tree name = ssa_name (i);
- tree value;
-
- if (!name)
- continue;
-
- value = SSA_NAME_VALUE (name);
- if (value && !is_gimple_min_invariant (value))
- SSA_NAME_VALUE (name) = NULL;
- }
-
statistics_counter_event (cfun, "Redundant expressions eliminated",
opt_stats.num_re);
statistics_counter_event (cfun, "Constants propagated",
VEC_free (tree, heap, const_and_copies_stack);
VEC_free (gimple_p, heap, stmts_to_rescan);
+ /* Free the value-handle array. */
+ threadedge_finalize_values ();
+ ssa_name_values = NULL;
+
return 0;
}
}
prev_value = VEC_pop (tree, const_and_copies_stack);
- SSA_NAME_VALUE (dest) = prev_value;
+ set_ssa_name_value (dest, prev_value);
}
}
inferred from a comparison. All uses of this ssa name are dominated
by this assignment, so unwinding just costs time and space. */
if (i == gimple_phi_num_args (phi) && may_propagate_copy (lhs, rhs))
- SSA_NAME_VALUE (lhs) = rhs;
+ set_ssa_name_value (lhs, rhs);
}
}
static void
record_const_or_copy_1 (tree x, tree y, tree prev_x)
{
- SSA_NAME_VALUE (x) = y;
+ set_ssa_name_value (x, y);
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (! def
|| TREE_CODE (def) != SSA_NAME
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
- || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF)
+ || gimple_vdef (stmt)
/* Do not record equivalences for increments of ivs. This would create
overlapping live ranges for a very questionable gain. */
|| simple_iv_increment_p (stmt))
return retval;
}
-/* Return true if statement GS is an assignment that peforms a useless
- type conversion. It is is intended to be a tuples analog of function
- tree_ssa_useless_type_conversion. */
-
-static bool
-gimple_assign_unary_useless_conversion_p (gimple gs)
-{
- if (is_gimple_assign (gs)
- && (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (gs))
- || gimple_assign_rhs_code (gs) == VIEW_CONVERT_EXPR
- || gimple_assign_rhs_code (gs) == NON_LVALUE_EXPR))
- {
- tree lhs_type = TREE_TYPE (gimple_assign_lhs (gs));
- tree rhs_type = TREE_TYPE (gimple_assign_rhs1 (gs));
- return useless_type_conversion_p (lhs_type, rhs_type);
- }
-
- return false;
-}
-
/* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either
the available expressions table or the const_and_copies table.
Detect and record those equivalences. */
lhs_code = TREE_CODE (lhs);
if (lhs_code == SSA_NAME
- && (gimple_assign_single_p (stmt)
- || gimple_assign_unary_useless_conversion_p (stmt)))
+ && gimple_assign_single_p (stmt))
{
tree rhs = gimple_assign_rhs1 (stmt);
- /* Strip away any useless type conversions. */
- STRIP_USELESS_TYPE_CONVERSION (rhs);
-
/* If the RHS of the assignment is a constant or another variable that
may be propagated, register it in the CONST_AND_COPIES table. We
do not need to record unwind data for this, since this is a true
fprintf (dump_file, "\n");
}
- SSA_NAME_VALUE (lhs) = rhs;
+ set_ssa_name_value (lhs, rhs);
}
}
else
new_stmt = gimple_build_assign (rhs, lhs);
- create_ssa_artificial_load_stmt (new_stmt, stmt, true);
+ gimple_set_vuse (new_stmt, gimple_vdef (stmt));
/* Finally enter the statement into the available expression
table. */
val = SSA_NAME_VALUE (op);
if (val && val != op)
{
- tree op_type, val_type;
-
/* Do not change the base variable in the virtual operand
tables. That would make it impossible to reconstruct
the renamed virtual operand if we later modify this
&& !may_propagate_copy_into_asm (op))
return false;
- /* Get the toplevel type of each operand. */
- op_type = TREE_TYPE (op);
- val_type = TREE_TYPE (val);
-
- /* While both types are pointers, get the type of the object
- pointed to. */
- while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
- {
- op_type = TREE_TYPE (op_type);
- val_type = TREE_TYPE (val_type);
- }
-
- /* Make sure underlying types match before propagating a constant by
- converting the constant to the proper type. Note that convert may
- return a non-gimple expression, in which case we ignore this
- propagation opportunity. */
- if (TREE_CODE (val) != SSA_NAME)
- {
- if (!useless_type_conversion_p (op_type, val_type))
- {
- val = fold_convert (TREE_TYPE (op), val);
- if (!is_gimple_min_invariant (val))
- return false;
- }
- }
-
/* Certain operands are not allowed to be copy propagated due
to their interaction with exception handling and some GCC
extensions. */
- else if (!may_propagate_copy (op, val))
+ if (!may_propagate_copy (op, val))
return false;
-
+
+ /* Do not propagate addresses that point to volatiles into memory
+ stmts without volatile operands. */
+ if (POINTER_TYPE_P (TREE_TYPE (val))
+ && TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (val)))
+ && gimple_has_mem_ops (stmt)
+ && !gimple_has_volatile_ops (stmt))
+ return false;
+
/* Do not propagate copies if the propagated value is at a deeper loop
depth than the propagatee. Otherwise, this may move loop variant
variables outside of their loops and prevent coalescing
gimple stmt = ((const struct expr_hash_elt *)p)->stmt;
const struct hashable_expr *expr = &((const struct expr_hash_elt *)p)->expr;
tree vuse;
- ssa_op_iter iter;
hashval_t val = 0;
val = iterative_hash_hashable_expr (expr, val);
if (!stmt)
return val;
- /* Add the SSA version numbers of every vuse operand. This is important
+ /* Add the SSA version numbers of the vuse operand. This is important
because compound variables like arrays are not renamed in the
operands. Rather, the rename is done on the virtual variable
representing all the elements of the array. */
- FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
+ if ((vuse = gimple_vuse (stmt)))
val = iterative_hash_expr (vuse, val);
return val;
&& types_compatible_p (expr1->type, expr2->type))
{
/* Note that STMT1 and/or STMT2 may be NULL. */
- bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
- return ret;
+ return ((stmt1 ? gimple_vuse (stmt1) : NULL_TREE)
+ == (stmt2 ? gimple_vuse (stmt2) : NULL_TREE));
}
return false;
/* Given PHI, return its RHS if the PHI is a degenerate, otherwise return
NULL. */
-static tree
+tree
degenerate_phi_result (gimple phi)
{
tree lhs = gimple_phi_result (phi);