+2011-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/51315
+ * 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.
+
2011-12-06 Martin Jambor <mjambor@suse.cz>
Backport from mainline:
+2011-12-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/51315
+ Backport from mainline
+ 2011-09-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <object>: Do not promote
+ the alignment if this doesn't prevent BLKmode access to the object.
+
2011-11-13 Iain Sandoe <iains@gcc.gnu.org>
Backport from mainline r181474
&& No (Address_Clause (gnat_entity))))
&& TREE_CODE (TYPE_SIZE (gnu_type)) == INTEGER_CST)
{
- /* No point in jumping through all the hoops needed in order
+ unsigned int size_cap, align_cap;
+
+ /* No point in promoting the alignment if this doesn't prevent
+ BLKmode access to the object, in particular block copy, as
+ this will for example disable the NRV optimization for it.
+ No point in jumping through all the hoops needed in order
to support BIGGEST_ALIGNMENT if we don't really have to.
So we cap to the smallest alignment that corresponds to
a known efficient memory access pattern of the target. */
- unsigned int align_cap = Is_Atomic (gnat_entity)
- ? BIGGEST_ALIGNMENT
- : get_mode_alignment (ptr_mode);
+ if (Is_Atomic (gnat_entity))
+ {
+ size_cap = UINT_MAX;
+ align_cap = BIGGEST_ALIGNMENT;
+ }
+ else
+ {
+ size_cap = MAX_FIXED_MODE_SIZE;
+ align_cap = get_mode_alignment (ptr_mode);
+ }
if (!host_integerp (TYPE_SIZE (gnu_type), 1)
- || compare_tree_int (TYPE_SIZE (gnu_type), align_cap) >= 0)
+ || compare_tree_int (TYPE_SIZE (gnu_type), size_cap) > 0)
+ align = 0;
+ else if (compare_tree_int (TYPE_SIZE (gnu_type), align_cap) > 0)
align = align_cap;
else
align = ceil_alignment (tree_low_cst (TYPE_SIZE (gnu_type), 1));
+2011-12-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20111208-1.c: New test.
+
+ Backport from mainline
+ 2011-09-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/frame_overflow.ads: New.
+ * gnat.dg/frame_overflow.adb: Adjust.
+ * gnat.dg/specs/addr1.ads: Likewise.
+
2011-12-06 Tobias Burnus <burnus@net-b.de>
PR fortran/51435
--- /dev/null
+/* PR tree-optimization/51315 */
+/* Reported by Jurij Smakov <jurij@wooyd.org> */
+
+typedef unsigned int size_t;
+
+extern void *memcpy (void *__restrict __dest,
+ __const void *__restrict __src, size_t __n)
+ __attribute__ ((__nothrow__)) __attribute__ ((__nonnull__ (1, 2)));
+
+extern size_t strlen (__const char *__s)
+ __attribute__ ((__nothrow__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
+
+typedef short int int16_t;
+typedef int int32_t;
+
+extern void abort (void);
+
+int a;
+
+static void __attribute__ ((noinline,noclone))
+do_something (int item)
+{
+ a = item;
+}
+
+int
+pack_unpack (char *s, char *p)
+{
+ char *send, *pend;
+ char type;
+ int integer_size;
+
+ send = s + strlen (s);
+ pend = p + strlen (p);
+
+ while (p < pend)
+ {
+ type = *p++;
+
+ switch (type)
+ {
+ case 's':
+ integer_size = 2;
+ goto unpack_integer;
+
+ case 'l':
+ integer_size = 4;
+ goto unpack_integer;
+
+ unpack_integer:
+ switch (integer_size)
+ {
+ case 2:
+ {
+ union
+ {
+ int16_t i;
+ char a[sizeof (int16_t)];
+ }
+ v;
+ memcpy (v.a, s, sizeof (int16_t));
+ s += sizeof (int16_t);
+ do_something (v.i);
+ }
+ break;
+
+ case 4:
+ {
+ union
+ {
+ int32_t i;
+ char a[sizeof (int32_t)];
+ }
+ v;
+ memcpy (v.a, s, sizeof (int32_t));
+ s += sizeof (int32_t);
+ do_something (v.i);
+ }
+ break;
+ }
+ break;
+ }
+ }
+ return (int) *s;
+}
+
+int
+main (void)
+{
+ int n = pack_unpack ("\200\001\377\376\035\300", "sl");
+ if (n != 0)
+ abort ();
+ return 0;
+}
-- { dg-do compile }
-with System;
+package body Frame_Overflow is
-procedure frame_overflow is
-
- type Bitpos_Range_T is range 1..2**(System.Word_Size-1)-1;
- type Bitmap_Array_T is array (Bitpos_Range_T) of Boolean;
-
- type Bitmap_T is record
- Bits : Bitmap_Array_T := (others => False);
- end record;
-
- function
+ function -- { dg-error "too large" }
Set_In (Bitmap : Bitmap_T; Bitpos : Bitpos_Range_T) return Bitmap_T
is
- Result: Bitmap_T := Bitmap; -- { dg-error "Storage_Error" }
+ Result: Bitmap_T := Bitmap;
begin
Result.Bits (Bitpos) := True;
return Result;
end;
- function Negate (Bitmap : Bitmap_T) return Bitmap_T is
- Result: Bitmap_T; -- { dg-error "Storage_Error" }
+ function -- { dg-error "too large" }
+ Negate (Bitmap : Bitmap_T) return Bitmap_T
+ is
+ Result: Bitmap_T;
begin
for E in Bitpos_Range_T loop
Result.Bits (E) := not Bitmap.Bits (E);
return Result;
end;
-begin
- null;
-end;
+end Frame_Overflow;
--- /dev/null
+with System;
+
+package Frame_Overflow is
+
+ type Bitpos_Range_T is range 1..2**(System.Word_Size-1)-1;
+ type Bitmap_Array_T is array (Bitpos_Range_T) of Boolean;
+
+ type Bitmap_T is record
+ Bits : Bitmap_Array_T := (others => False);
+ end record;
+
+ function
+ Set_In (Bitmap : Bitmap_T; Bitpos : Bitpos_Range_T) return Bitmap_T;
+
+ function Negate (Bitmap : Bitmap_T) return Bitmap_T;
+
+end Frame_Overflow;
end record;
for Rec2'Size use 64;
- A: Arr (1 .. 12);
+ A: Arr (1 .. 4);
Obj1: Rec1;
for Obj1'Address use A'Address; -- { dg-bogus "alignment" }
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, BIGGEST_ALIGNMENT);
- 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. */
+ exp_align = get_object_alignment (exp, BIGGEST_ALIGNMENT);
+ if (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF)
+ exp_align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), exp_align);
+
+ if (exp_align < align)
return true;
return false;
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,
+ BIGGEST_ALIGNMENT)))
+ lacc->grp_unscalarizable_region = 1;
}
if (racc)
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,
+ BIGGEST_ALIGNMENT)))
+ racc->grp_unscalarizable_region = 1;
}
if (lacc && racc
|| 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;