diff options
Diffstat (limited to 'gcc/tree-ssa-alias.c')
-rw-r--r-- | gcc/tree-ssa-alias.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 353e7bd..5370747 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -2424,6 +2424,8 @@ typedef struct used_part variable. Implicit uses occur when we can't tell what part we are referencing, and have to make conservative assumptions. */ bool implicit_uses; + /* True if the structure is only written to or taken its address. */ + bool write_only; } *used_part_t; /* An array of used_part structures, indexed by variable uid. */ @@ -2509,6 +2511,7 @@ get_or_create_used_part_for (size_t uid) up->maxused = 0; up->explicit_uses = false; up->implicit_uses = false; + up->write_only = true; } return up; @@ -2552,10 +2555,11 @@ create_overlap_variables_for (tree var) used_part_t up; size_t uid = DECL_UID (var); - if (!up_lookup (uid)) + up = up_lookup (uid); + if (!up + || up->write_only) return; - up = up_lookup (uid); push_fields_onto_fieldstack (TREE_TYPE (var), &fieldstack, 0, NULL); if (VEC_length (fieldoff_s, fieldstack) != 0) { @@ -2691,10 +2695,15 @@ create_overlap_variables_for (tree var) entire structure. */ static tree -find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) +find_used_portions (tree *tp, int *walk_subtrees, void *lhs_p) { switch (TREE_CODE (*tp)) { + case MODIFY_EXPR: + /* Recurse manually here to track whether the use is in the + LHS of an assignment. */ + find_used_portions (&TREE_OPERAND (*tp, 0), walk_subtrees, tp); + return find_used_portions (&TREE_OPERAND (*tp, 1), walk_subtrees, NULL); case REALPART_EXPR: case IMAGPART_EXPR: case COMPONENT_REF: @@ -2723,6 +2732,8 @@ find_used_portions (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) up->explicit_uses = true; else up->implicit_uses = true; + if (!lhs_p) + up->write_only = false; up_insert (uid, up); *walk_subtrees = 0; |