aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-sra.cc')
-rw-r--r--gcc/tree-sra.cc51
1 files changed, 31 insertions, 20 deletions
diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
index 302b73e..cb0f518 100644
--- a/gcc/tree-sra.cc
+++ b/gcc/tree-sra.cc
@@ -1291,19 +1291,16 @@ build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
return NULL;
}
- /* We need to dive through V_C_Es in order to get the size of its parameter
- and not the result type. Ada produces such statements. We are also
- capable of handling the topmost V_C_E but not any of those buried in other
- handled components. */
- if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
- expr = TREE_OPERAND (expr, 0);
-
- if (contains_view_convert_expr_p (expr))
+ /* We are capable of handling the topmost V_C_E but not any of those
+ buried in other handled components. */
+ if (contains_view_convert_expr_p (TREE_CODE (expr) == VIEW_CONVERT_EXPR
+ ? TREE_OPERAND (expr, 0) : expr))
{
disqualify_base_of_expr (expr, "V_C_E under a different handled "
"component.");
return NULL;
}
+
if (TREE_THIS_VOLATILE (expr))
{
disqualify_base_of_expr (expr, "part of a volatile reference.");
@@ -1323,6 +1320,7 @@ build_access_from_expr_1 (tree expr, gimple *stmt, bool write)
case ARRAY_REF:
case ARRAY_RANGE_REF:
case BIT_FIELD_REF:
+ case VIEW_CONVERT_EXPR:
ret = create_access (expr, stmt, write);
break;
@@ -1680,7 +1678,13 @@ scan_function (void)
/* If the STMT is a call to DEFERRED_INIT, avoid setting
cannot_scalarize_away_bitmap. */
if (gimple_call_internal_p (stmt, IFN_DEFERRED_INIT))
- ret |= !!build_access_from_expr_1 (t, stmt, true);
+ {
+ struct access *access
+ = build_access_from_expr_1 (t, stmt, true);
+ if (access)
+ access->grp_assignment_write = 1;
+ ret |= access != NULL;
+ }
else
ret |= build_access_from_expr (t, stmt, true);
}
@@ -1884,7 +1888,7 @@ make_fancy_name (tree expr)
the current one as specified by INSERT_AFTER. This function is not capable
of handling bitfields. */
-tree
+static tree
build_ref_for_offset (location_t loc, tree base, poly_int64 offset,
bool reverse, tree exp_type, gimple_stmt_iterator *gsi,
bool insert_after)
@@ -2504,6 +2508,12 @@ sort_and_splice_var_accesses (tree var)
}
unscalarizable_region = true;
}
+ /* If there the same place is accessed with two incompatible
+ aggregate types, trying to base total scalarization on either of
+ them can be wrong. */
+ if (!first_scalar && !types_compatible_p (access->type, ac2->type))
+ bitmap_set_bit (cannot_scalarize_away_bitmap,
+ DECL_UID (access->base));
if (grp_same_access_path
&& (!ac2->grp_same_access_path
@@ -2889,7 +2899,10 @@ analyze_access_subtree (struct access *root, struct access *parent,
for (child = root->first_child; child; child = child->next_sibling)
{
- hole |= covered_to < child->offset;
+ if (totally)
+ covered_to = child->offset;
+ else
+ hole |= covered_to < child->offset;
sth_created |= analyze_access_subtree (child, root,
allow_replacements && !scalar
&& !root->grp_partial_lhs,
@@ -2900,6 +2913,8 @@ analyze_access_subtree (struct access *root, struct access *parent,
covered_to += child->size;
else
hole = true;
+ if (totally && !hole)
+ covered_to = limit;
}
if (allow_replacements && scalar && !root->first_child
@@ -2972,7 +2987,7 @@ analyze_access_subtree (struct access *root, struct access *parent,
root->grp_total_scalarization = 0;
}
- if (!hole || totally)
+ if (!hole)
root->grp_covered = 1;
else if (root->grp_write || comes_initialized_p (root->base))
root->grp_unscalarized_data = 1; /* not covered and written to */
@@ -3760,7 +3775,7 @@ sra_get_max_scalarization_size (void)
/* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
fall back to a target default. */
unsigned HOST_WIDE_INT max_scalarization_size
- = get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
+ = get_move_ratio (optimize_speed_p) * MOVE_MAX;
if (optimize_speed_p)
{
@@ -4075,12 +4090,6 @@ get_access_for_expr (tree expr)
tree base;
bool reverse;
- /* FIXME: This should not be necessary but Ada produces V_C_Es with a type of
- a different size than the size of its argument and we need the latter
- one. */
- if (TREE_CODE (expr) == VIEW_CONVERT_EXPR)
- expr = TREE_OPERAND (expr, 0);
-
base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size,
&reverse);
if (!known_size_p (pmax_size)
@@ -4205,8 +4214,10 @@ sra_modify_expr (tree *expr, bool write, gimple_stmt_iterator *stmt_gsi,
}
else
{
- gassign *stmt;
+ if (TREE_READONLY (access->base))
+ return false;
+ gassign *stmt;
if (access->grp_partial_lhs)
repl = force_gimple_operand_gsi (stmt_gsi, repl, true,
NULL_TREE, true,