[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