aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2011-12-08 09:05:38 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-12-08 09:05:38 +0000
commit908b951938511131cf3858c75924db323de415ea (patch)
treef9866f9a7ab239814de604e3414349d48cdece0b /gcc/tree-sra.c
parentc37257a1f686bdd260a2edc445f8b3f24dceec2e (diff)
downloadgcc-908b951938511131cf3858c75924db323de415ea.zip
gcc-908b951938511131cf3858c75924db323de415ea.tar.gz
gcc-908b951938511131cf3858c75924db323de415ea.tar.bz2
re PR tree-optimization/51315 (unaligned memory accesses generated with -ftree-sra)
PR tree-optimization/51315 * tree.h (get_object_or_type_alignment): Declare. * expr.c (get_object_or_type_alignment): Move to... * builtins.c (get_object_or_type_alignment): ...here. Add assertion. * tree-sra.c (tree_non_mode_aligned_mem_p): Rename to... (tree_non_aligned_mem_p): ...this. Add ALIGN parameter. Look into MEM_REFs and use get_object_or_type_alignment for them. (build_accesses_from_assign): Adjust for above change. (access_precludes_ipa_sra_p): Likewise. From-SVN: r182102
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index dec5316..346519a 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1067,26 +1067,29 @@ disqualify_ops_if_throwing_stmt (gimple stmt, tree lhs, tree rhs)
return false;
}
-/* Return true iff type of EXP is not sufficiently aligned. */
+/* Return true if EXP is a memory reference less aligned than ALIGN. This is
+ invoked only on strict-alignment targets. */
static bool
-tree_non_mode_aligned_mem_p (tree exp)
+tree_non_aligned_mem_p (tree exp, unsigned int align)
{
- enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
- unsigned int align;
+ unsigned int exp_align;
if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
exp = TREE_OPERAND (exp, 0);
- if (TREE_CODE (exp) == SSA_NAME
- || TREE_CODE (exp) == MEM_REF
- || mode == BLKmode
- || is_gimple_min_invariant (exp)
- || !STRICT_ALIGNMENT)
+ if (TREE_CODE (exp) == SSA_NAME || is_gimple_min_invariant (exp))
return false;
- align = get_object_alignment (exp);
- if (GET_MODE_ALIGNMENT (mode) > align)
+ /* get_object_alignment will fall back to BITS_PER_UNIT if it cannot
+ compute an explicit alignment. Pretend that dereferenced pointers
+ are always aligned on strict-alignment targets. */
+ if (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF)
+ exp_align = get_object_or_type_alignment (exp);
+ else
+ exp_align = get_object_alignment (exp);
+
+ if (exp_align < align)
return true;
return false;
@@ -1120,7 +1123,9 @@ build_accesses_from_assign (gimple stmt)
if (lacc)
{
lacc->grp_assignment_write = 1;
- lacc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (rhs);
+ if (STRICT_ALIGNMENT
+ && tree_non_aligned_mem_p (rhs, get_object_alignment (lhs)))
+ lacc->grp_unscalarizable_region = 1;
}
if (racc)
@@ -1129,7 +1134,9 @@ build_accesses_from_assign (gimple stmt)
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
&& !is_gimple_reg_type (racc->type))
bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
- racc->grp_unscalarizable_region |= tree_non_mode_aligned_mem_p (lhs);
+ if (STRICT_ALIGNMENT
+ && tree_non_aligned_mem_p (lhs, get_object_alignment (rhs)))
+ racc->grp_unscalarizable_region = 1;
}
if (lacc && racc
@@ -3705,7 +3712,8 @@ access_precludes_ipa_sra_p (struct access *access)
|| gimple_code (access->stmt) == GIMPLE_ASM))
return true;
- if (tree_non_mode_aligned_mem_p (access->expr))
+ if (STRICT_ALIGNMENT
+ && tree_non_aligned_mem_p (access->expr, TYPE_ALIGN (access->type)))
return true;
return false;