[PATCH] MALLOC_ABI_ALIGNMENT macro + malloc-alignment param
Olivier Hainque
hainque@adacore.com
Tue Jul 1 17:27:00 GMT 2008
Hello,
Following up on this topic ...
Olivier Hainque wrote:
> A possible track would then be to have an "OS_MALLOC_ALIGNMENT"
> optional target definition defaulted to STACK_BOUNDARY + a
> malloc-alignment user parameter.
STACK_BOUNDARY turns out not to be quite right (always 128 on aix
for instance). Here is refined suggestion, with a general default
to MIN (STACK_BOUNDARY, 2*BITS_PER_WORD) which I think matches or
is lower than all the static "exceptions" we had.
The default suggested here is lower than the static exception
we had on at least x86-linux, which was 8 while the default here
is 4 - in accordance with your expectations for this target.
It's certainly much safer than the current default on mainline in
any case.
This bootstraps and tests fine on x86_64-suse-linux. Bootstraps
and sanity check fine on i686-pc-linux-gnu, where it also passes
our full internal regression suite.
The difference between the new default and the former exception
on x86 is visible on this simple case:
procedure X is
type T is access Long_Long_Integer;
Ptr : T := new Long_Long_Integer;
begin
null;
end;
The new allocator now "thinks" that malloc's return value will
not be aligned enough (4 compared to 8), so this triggers gigi's
realigning_type circuitry and generates, erm, interesting code.
When it is known to be safe, the former behavior is easily
recovered by passing an extra "--param malloc-alignment=64".
Thanks in advance,
Olivier
2008-07-01 Olivier Hainque <hainque@adacore.com>
* params.def (PARAM_MALLOC_ALIGNMENT): New parameter. Alignment,
in bits, the target memory allocator is known to honor.
config/
* defaults.h (MALLOC_ABI_ALIGNMENT): New. Define to default value.
doc/
* tm.texi (MALLOC_ABI_ALIGNMENT): New macro. Alignment, in bits,
the target memory allocator is required to honor according to the
ABI.
* invoke.texi (malloc-alignment): Document new --param parameter.
ada/
* targtyps.c (MALLOC_ALIGNMENT): Refine default definition
to use MALLOC_ABI_ALIGNMENT and the malloc-alignment parameter.
testsuite/
* gnat.dg/allocator_maxalign1.adb: New test.
* gnat.dg/test_allocator_maxalign2.adb: Main caller for ...
* gnat.dg/allocator_maxalign2.ad[bs]: New test.
-------------- next part --------------
Index: doc/tm.texi
===================================================================
*** doc/tm.texi (revision 137042)
--- doc/tm.texi (working copy)
*************** bits. Note that this is not the biggest
*** 1095,1100 ****
--- 1095,1106 ----
just the biggest alignment that, when violated, may cause a fault.
@end defmac
+ @defmac MALLOC_ABI_ALIGNMENT
+ Alignment, in bits, to be honored by the target memory allocator
+ according to the ABI. If not defined, the default value is
+ @code{MIN (STACK_BOUNDARY, 2 * BITS_PER_WORD)}.
+ @end defmac
+
@defmac MINIMUM_ATOMIC_ALIGNMENT
If defined, the smallest alignment, in bits, that can be given to an
object that can be referenced in one operation, without disturbing any
Index: doc/invoke.texi
===================================================================
*** doc/invoke.texi (revision 137042)
--- doc/invoke.texi (working copy)
*************** Specifies maximal growth of large stack
*** 6944,6949 ****
--- 6944,6959 ----
The default value is 1000 which limits large stack frame growth to 11 times
the original size.
+ @item malloc-alignment
+ The maximum alignment, in bits, addresses returned by "malloc" may be
+ assumed to honor. This is intended for situations where the allocator's
+ behavior is kown to deviate from the ABI requirements.
+
+ Setting this parameter is required for correctness of e.g. Ada
+ allocators when the offered alignment is lower than what the ABI
+ mandates. It is useful performance-wise for Ada allocators as well when
+ the offered alignment is greater than what the ABI requires.
+
@item max-inline-insns-recursive
@itemx max-inline-insns-recursive-auto
Specifies maximum number of instructions out-of-line copy of self recursive inline
Index: defaults.h
===================================================================
*** defaults.h (revision 137042)
--- defaults.h (working copy)
*************** along with GCC; see the file COPYING3.
*** 551,556 ****
--- 551,562 ----
#define PUSH_ARGS_REVERSED 0
#endif
+ /* Default value for the alignment to be honored by the
+ target memory allocator according to the ABI. */
+ #ifndef MALLOC_ABI_ALIGNMENT
+ #define MALLOC_ABI_ALIGNMENT MIN (STACK_BOUNDARY, 2 * BITS_PER_WORD)
+ #endif
+
/* If PREFERRED_STACK_BOUNDARY is not defined, set it to STACK_BOUNDARY.
STACK_BOUNDARY is required. */
#ifndef PREFERRED_STACK_BOUNDARY
Index: params.def
===================================================================
*** params.def (revision 137042)
--- params.def (working copy)
*************** DEFPARAM (PARAM_DF_DOUBLE_QUEUE_THRESHOL
*** 710,715 ****
--- 710,721 ----
"Multiplier used for determining the double-queueing threshold",
2, 0, 0)
+ /* The maximum alignment 'malloc' may be assumed to offer. */
+ DEFPARAM (PARAM_MALLOC_ALIGNMENT,
+ "malloc-alignment",
+ "The maximum alignment, in bits, 'malloc' may be assumed to offer",
+ 0, 1, 2048)
+
/*
Local variables:
mode:c
Index: ada/targtyps.c
===================================================================
*** ada/targtyps.c (revision 137042)
--- ada/targtyps.c (working copy)
*************** get_target_maximum_default_alignment (vo
*** 164,171 ****
Stricter alignment requests trigger gigi's aligning_type circuitry for
objects allocated by the default allocator. */
#ifndef MALLOC_ALIGNMENT
! #define MALLOC_ALIGNMENT BIGGEST_ALIGNMENT
#endif
Pos
--- 164,178 ----
Stricter alignment requests trigger gigi's aligning_type circuitry for
objects allocated by the default allocator. */
+ #include "params.h"
+
+ /* The maximum alignment "malloc" may be assumed to offer, user specified or
+ system specific. */
#ifndef MALLOC_ALIGNMENT
! #define MALLOC_ALIGNMENT \
! (PARAM_SET_P(PARAM_MALLOC_ALIGNMENT) \
! ? PARAM_VALUE(PARAM_MALLOC_ALIGNMENT) \
! : MALLOC_ABI_ALIGNMENT)
#endif
Pos
Index: testsuite/gnat.dg/allocator_maxalign1.adb
===================================================================
*** testsuite/gnat.dg/allocator_maxalign1.adb (revision 0)
--- testsuite/gnat.dg/allocator_maxalign1.adb (revision 0)
***************
*** 0 ****
--- 1,42 ----
+ -- { dg-do run }
+
+ with System.Storage_Elements; use System.Storage_Elements;
+ with Ada.Unchecked_Deallocation;
+
+ procedure Allocator_Maxalign1 is
+
+ Max_Alignment : constant := Standard'Maximum_Alignment;
+
+ type Block is record
+ X : Integer;
+ end record;
+ for Block'Alignment use Standard'Maximum_Alignment;
+
+ type Block_Access is access all Block;
+ procedure Free is new Ada.Unchecked_Deallocation (Block, Block_Access);
+
+ N_Blocks : constant := 500;
+ Blocks : array (1 .. N_Blocks) of Block_Access;
+ begin
+ if Block'Alignment /= Max_Alignment then
+ raise Program_Error;
+ end if;
+
+ for K in 1 .. 4 loop
+
+ for I in Blocks'Range loop
+ Blocks (I) := new Block;
+ if Blocks (I).all'Address mod Block'Alignment /= 0 then
+ raise Program_Error;
+ end if;
+ Blocks(I).all.X := I;
+ end loop;
+
+ for I in Blocks'Range loop
+ Free (Blocks (I));
+ end loop;
+
+ end loop;
+
+ end;
+
Index: testsuite/gnat.dg/allocator_maxalign2.adb
===================================================================
*** testsuite/gnat.dg/allocator_maxalign2.adb (revision 0)
--- testsuite/gnat.dg/allocator_maxalign2.adb (revision 0)
***************
*** 0 ****
--- 1,33 ----
+ with System, System.Storage_Elements;
+ use System.Storage_Elements;
+
+ package body Allocator_Maxalign2 is
+
+ Max_Align : constant Storage_Offset := Standard'Maximum_Alignment;
+
+ procedure Validate is
+ use type System.Address;
+ begin
+ if Addr mod Max_Align /= 0 then
+ raise Program_Error;
+ end if;
+ end;
+
+ procedure Check is
+ I : Integer;
+ B : Block;
+ type Block_Access is access all Block;
+ A : Block_Access;
+ begin
+ Addr := I'Address;
+ Addr := B'Address;
+ Validate;
+ for I in 1 .. 50 loop
+ A := new Block;
+ Addr := A.all'Address;
+ Validate;
+ end loop;
+
+ end;
+
+ end;
Index: testsuite/gnat.dg/allocator_maxalign2.ads
===================================================================
*** testsuite/gnat.dg/allocator_maxalign2.ads (revision 0)
--- testsuite/gnat.dg/allocator_maxalign2.ads (revision 0)
***************
*** 0 ****
--- 1,12 ----
+ with System;
+
+ package Allocator_Maxalign2 is
+ type Block is record
+ X : Integer;
+ end record;
+ for Block'Alignment use Standard'Maximum_Alignment;
+
+ Addr : System.Address;
+
+ procedure Check;
+ end;
Index: testsuite/gnat.dg/test_allocator_maxalign2.adb
===================================================================
*** testsuite/gnat.dg/test_allocator_maxalign2.adb (revision 0)
--- testsuite/gnat.dg/test_allocator_maxalign2.adb (revision 0)
***************
*** 0 ****
--- 1,8 ----
+ -- { dg-do run }
+
+ with Allocator_Maxalign2;
+
+ procedure Test_Allocator_Maxalign2 is
+ begin
+ Allocator_Maxalign2.Check;
+ end;
More information about the Gcc-patches
mailing list