/* Scalar Replacement of Aggregates (SRA) converts some structure
references into scalar references, exposing them to the scalar
optimizers.
- Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
/* True if this is the "early" pass, before inlining. */
static bool early_sra;
-/* The set of todo flags to return from tree_sra. */
-static unsigned int todoflags;
-
/* The set of aggregate variables that are candidates for scalarization. */
static bitmap sra_candidates;
static tree generate_element_ref (struct sra_elt *);
static gimple_seq sra_build_assignment (tree dst, tree src);
static void mark_all_v_defs_seq (gimple_seq);
-static void mark_all_v_defs_stmt (gimple);
\f
/* Return true if DECL is an SRA candidate. */
we'd been passed the constructor directly. Invoke INIT. */
else if (TREE_CODE (rhs) == VAR_DECL
&& TREE_STATIC (rhs)
+ && !DECL_EXTERNAL (rhs)
&& TREE_READONLY (rhs)
&& targetm.binds_local_p (rhs))
fns->init (lhs_elt, DECL_INITIAL (rhs), gsi);
ni = si;
gsi_next (&ni);
- /* If the statement has no virtual operands, then it doesn't
+ /* If the statement does not reference memory, then it doesn't
make any structure references that we care about. */
- if (gimple_aliases_computed_p (cfun)
- && ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
- continue;
+ if (!gimple_references_memory_p (stmt))
+ continue;
switch (gimple_code (stmt))
{
gcc_assert (block && block->is_scalar);
var = block->replacement;
-
- if ((bit & ~alchk)
- || (HOST_WIDE_INT)size != tree_low_cst (DECL_SIZE (var), 1))
- {
- block->replacement = fold_build3 (BIT_FIELD_REF,
- TREE_TYPE (block->element), var,
- bitsize_int (size),
- bitsize_int (bit & ~alchk));
- }
-
block->in_bitfld_block = 2;
/* Add the member fields to the group, such that they access
gcc_assert (fld && fld->is_scalar && !fld->replacement);
fld->replacement = fold_build3 (BIT_FIELD_REF, field_type, var,
- DECL_SIZE (f),
+ bitsize_int (TYPE_PRECISION (field_type)),
bitsize_int
((TREE_INT_CST_LOW (DECL_FIELD_OFFSET (f))
* BITS_PER_UNIT
+ (TREE_INT_CST_LOW
- (DECL_FIELD_BIT_OFFSET (f))))
+ (DECL_FIELD_BIT_OFFSET (f)))
+ - (TREE_INT_CST_LOW
+ (TREE_OPERAND (block->element, 2))))
& ~alchk));
fld->in_bitfld_block = 1;
}
\f
/* Phase Four: Update the function to match the replacements created. */
-/* Mark all the variables in VDEF/VUSE operators for STMT for
- renaming. This becomes necessary when we modify all of a
- non-scalar. */
-
-static void
-mark_all_v_defs_stmt (gimple stmt)
-{
- tree sym;
- ssa_op_iter iter;
-
- update_stmt_if_modified (stmt);
-
- FOR_EACH_SSA_TREE_OPERAND (sym, stmt, iter, SSA_OP_ALL_VIRTUALS)
- {
- if (TREE_CODE (sym) == SSA_NAME)
- sym = SSA_NAME_VAR (sym);
- mark_sym_for_renaming (sym);
- }
-}
-
-
/* Mark all the variables in virtual operands in all the statements in
LIST for renaming. */
gimple_stmt_iterator gsi;
for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
- mark_all_v_defs_stmt (gsi_stmt (gsi));
+ update_stmt_if_modified (gsi_stmt (gsi));
}
/* Mark every replacement under ELT with TREE_NO_WARNING. */
tmp = var;
if (!is_gimple_variable (tmp))
tmp = unshare_expr (var);
+ else
+ TREE_NO_WARNING (var) = true;
tmp2 = make_rename_temp (utype, "SR");
if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
- stmt = gimple_build_assign (tmp2, fold_convert (utype, tmp));
+ tmp = fold_convert (utype, tmp);
else
- stmt = gimple_build_assign (tmp2, fold_build1 (VIEW_CONVERT_EXPR,
- utype, tmp));
+ tmp = fold_build1 (VIEW_CONVERT_EXPR, utype, tmp);
+
+ stmt = gimple_build_assign (tmp2, tmp);
gimple_seq_add_stmt (&seq, stmt);
}
else
sra_replace (gimple_stmt_iterator *gsi, gimple_seq seq)
{
sra_insert_before (gsi, seq);
+ unlink_stmt_vdef (gsi_stmt (*gsi));
gsi_remove (gsi, false);
if (gsi_end_p (*gsi))
*gsi = gsi_last (gsi_seq (*gsi));
replacement = tmp;
}
if (is_output)
- mark_all_v_defs_stmt (stmt);
+ update_stmt_if_modified (stmt);
*expr_p = REPLDUP (replacement);
update_stmt (stmt);
}
if (!elt->use_block_copy)
{
tree type = TREE_TYPE (bfexpr);
- tree var, vpos;
+ tree var = make_rename_temp (type, "SR"), tmp, vpos;
+ gimple st = NULL;
- if (!TYPE_UNSIGNED (type))
- type = unsigned_type_for (type);
+ gimple_assign_set_rhs1 (stmt, var);
+ update = true;
- var = make_rename_temp (type, "SR");
+ if (!TYPE_UNSIGNED (type))
+ {
+ type = unsigned_type_for (type);
+ tmp = make_rename_temp (type, "SR");
+ st = gimple_build_assign (var,
+ fold_convert (TREE_TYPE (var), tmp));
+ var = tmp;
+ }
gimple_seq_add_stmt (&seq,
gimple_build_assign
sra_explode_bitfield_assignment
(var, vpos, true, &seq, blen, bpos, elt);
- gimple_assign_set_rhs1 (stmt, var);
- update = true;
+ if (st)
+ gimple_seq_add_stmt (&seq, st);
}
else
sra_sync_for_bitfield_assignment
original block copy statement. */
stmt = gsi_stmt (*gsi);
- mark_all_v_defs_stmt (stmt);
+ update_stmt_if_modified (stmt);
seq = NULL;
generate_element_copy (lhs_elt, rhs_elt, &seq);
/* The LHS is fully instantiated. The list of initializations
replaces the original structure assignment. */
gcc_assert (seq);
- mark_all_v_defs_stmt (gsi_stmt (*gsi));
+ update_stmt_if_modified (gsi_stmt (*gsi));
mark_all_v_defs_seq (seq);
sra_replace (gsi, seq);
}
gimple_seq seq = NULL;
gimple stmt = gsi_stmt (*gsi);
- mark_all_v_defs_stmt (stmt);
+ update_stmt_if_modified (stmt);
generate_copy_inout (elt, is_output, other, &seq);
gcc_assert (seq);
mark_all_v_defs_seq (seq);
tree_sra (void)
{
/* Initialize local variables. */
- todoflags = 0;
gcc_obstack_init (&sra_obstack);
sra_candidates = BITMAP_ALLOC (NULL);
needs_copy_in = BITMAP_ALLOC (NULL);
scan_function ();
decide_instantiations ();
scalarize_function ();
- if (!bitmap_empty_p (sra_candidates))
- todoflags |= TODO_rebuild_alias;
}
/* Free allocated memory. */
BITMAP_FREE (sra_type_decomp_cache);
BITMAP_FREE (sra_type_inst_cache);
obstack_free (&sra_obstack, NULL);
- return todoflags;
+ return 0;
}
static unsigned int
ret = tree_sra ();
early_sra = false;
- return ret & ~TODO_rebuild_alias;
+ return ret;
}
static bool
PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
- 0, /* todo_flags_start */
+ TODO_update_address_taken, /* todo_flags_start */
TODO_dump_func
| TODO_update_ssa
| TODO_ggc_collect