* [Ada] Do not overly promote alignment of local variable
@ 2011-09-25 17:06 Eric Botcazou
0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2011-09-25 17:06 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 565 bytes --]
This limits the alignment promotion we do for local aggregate variables in Ada,
which doesn't play nice with the NRV optimization.
Tested on i586-suse-linux, applied on the 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-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.
--
Eric Botcazou
[-- Attachment #2: p.diff --]
[-- Type: text/x-diff, Size: 4113 bytes --]
Index: ada/gcc-interface/decl.c
===================================================================
--- ada/gcc-interface/decl.c (revision 179163)
+++ ada/gcc-interface/decl.c (working copy)
@@ -817,16 +817,30 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
&& 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));
Index: testsuite/gnat.dg/frame_overflow.adb
===================================================================
--- testsuite/gnat.dg/frame_overflow.adb (revision 179017)
+++ testsuite/gnat.dg/frame_overflow.adb (working copy)
@@ -1,27 +1,20 @@
-- { 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);
@@ -29,6 +22,4 @@ procedure frame_overflow is
return Result;
end;
-begin
- null;
-end;
+end Frame_Overflow;
Index: testsuite/gnat.dg/frame_overflow.ads
===================================================================
--- testsuite/gnat.dg/frame_overflow.ads (revision 0)
+++ testsuite/gnat.dg/frame_overflow.ads (revision 0)
@@ -0,0 +1,17 @@
+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;
Index: testsuite/gnat.dg/specs/addr1.ads
===================================================================
--- testsuite/gnat.dg/specs/addr1.ads (revision 179017)
+++ testsuite/gnat.dg/specs/addr1.ads (working copy)
@@ -15,7 +15,7 @@ package Addr1 is
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" }
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2011-09-25 15:50 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-25 17:06 [Ada] Do not overly promote alignment of local variable Eric Botcazou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).