if (expr0->ops.unary.op != expr1->ops.unary.op)
return false;
- if ((expr0->ops.unary.op == NOP_EXPR
- || expr0->ops.unary.op == CONVERT_EXPR
+ if ((CONVERT_EXPR_CODE_P (expr0->ops.unary.op)
|| expr0->ops.unary.op == NON_LVALUE_EXPR)
&& TYPE_UNSIGNED (expr0->type) != TYPE_UNSIGNED (expr1->type))
return false;
Don't hash the type, that can lead to having nodes which
compare equal according to operand_equal_p, but which
have different hash codes. */
- if (expr->ops.unary.op == NOP_EXPR
- || expr->ops.unary.op == CONVERT_EXPR
+ if (CONVERT_EXPR_CODE_P (expr->ops.unary.op)
|| expr->ops.unary.op == NON_LVALUE_EXPR)
val += TYPE_UNSIGNED (expr->type);
gimple_assign_unary_useless_conversion_p (gimple gs)
{
if (is_gimple_assign (gs)
- && (gimple_assign_rhs_code (gs) == NOP_EXPR
- || gimple_assign_rhs_code (gs) == CONVERT_EXPR
+ && (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))
{
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, old_stmt;
bool may_optimize_p;
- bool may_have_exposed_new_symbols = false;
+ bool may_have_exposed_new_symbols;
+ bool modified_p = false;
old_stmt = stmt = gsi_stmt (si);
update_stmt_if_modified (stmt);
opt_stats.num_stmts++;
- may_have_exposed_new_symbols = false;
push_stmt_changes (gsi_stmt_ptr (&si));
if (dump_file && (dump_flags & TDF_DETAILS))
Indicate we will need to rescan and rewrite the statement. */
may_have_exposed_new_symbols = true;
+ /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called,
+ even if fold_stmt updated the stmt already and thus cleared
+ gimple_modified_p flag on it. */
+ modified_p = true;
}
/* Check for redundant computations. Do this optimization only
Ultimately I suspect we're going to need to change the interface
into the SSA_NAME manager. */
- if (gimple_modified_p (stmt))
+ if (gimple_modified_p (stmt) || modified_p)
{
tree val = NULL;