[Ada] In-place initialization for Initialize_Scalars
This patch optimizes the initialization and allocation of scalar array objects
when pragma Initialize_Scalars is in effect. The patch also extends the syntax
and semantics of pragma Initialize_Scalars to allow for the specification of
invalid values pertaining to families of scalar types. The new syntax is as
follows:
pragma Initialize_Scalars
[ ( TYPE_VALUE_PAIR {, TYPE_VALUE_PAIR} ) ];
TYPE_VALUE_PAIR ::=
SCALAR_TYPE => static_EXPRESSION
SCALAR_TYPE :=
Short_Float
| Float
| Long_Float
| Long_Long_Flat
| Signed_8
| Signed_16
| Signed_32
| Signed_64
| Unsigned_8
| Unsigned_16
| Unsigned_32
| Unsigned_64
Depending on the value specified by pragma Initialize_Scalars, the backend may
optimize the creation of the scalar array object into a fast memset.
------------
-- Source --
------------
-- gnat.adc
pragma Initialize_Scalars
(Short_Float => 0.0,
Float => 0.0,
Long_Float => 0.0,
Long_Long_Float => 0.0,
Signed_8 => 0,
Signed_16 => 0,
Signed_32 => 0,
Signed_64 => 0,
Unsigned_8 => 0,
Unsigned_16 => 0,
Unsigned_32 => 0,
Unsigned_64 => 0);
-- types.ads
with System;
package Types is
Max : constant := 10_000;
subtype Big is Integer range 1 .. Max;
type Byte is range 0 .. 255;
for Byte'Size use System.Storage_Unit;
type Byte_Arr_1 is array (1 .. Max) of Byte;
type Byte_Arr_2 is array (Big) of Byte;
type Byte_Arr_3 is array (Integer range <>) of Byte;
type Byte_Arr_4 is array (Integer range <>,
Integer range <>) of Byte;
type Constr_Arr_1 is array (1 .. Max) of Integer;
type Constr_Arr_2 is array (Big) of Integer;
type Constr_Arr_3 is array (1 .. Max, 1 .. Max) of Integer;
type Constr_Arr_4 is array (Big, Big) of Integer;
type Unconstr_Arr_1 is array (Integer range <>) of Integer;
type Unconstr_Arr_2 is array (Integer range <>,
Integer range <>) of Integer;
subtype Subt_Arr_1 is Unconstr_Arr_1 (1 .. Max);
subtype Subt_Arr_2 is Unconstr_Arr_1 (Big);
subtype Subt_Arr_3 is Unconstr_Arr_2 (1 .. Max, 1 .. Max);
subtype Subt_Arr_4 is Unconstr_Arr_2 (Big, Big);
subtype Subt_Str_1 is String (1 .. Max);
subtype Subt_Str_2 is String (Big);
type Byte_Arr_1_Ptr is access Byte_Arr_1;
type Byte_Arr_2_Ptr is access Byte_Arr_2;
type Byte_Arr_3_Ptr is access Byte_Arr_3;
type Byte_Arr_4_Ptr is access Byte_Arr_4;
type Constr_Arr_1_Ptr is access Constr_Arr_1;
type Constr_Arr_2_Ptr is access Constr_Arr_2;
type Constr_Arr_3_Ptr is access Constr_Arr_3;
type Constr_Arr_4_Ptr is access Constr_Arr_4;
type Unconstr_Arr_1_Ptr is access Unconstr_Arr_1;
type Unconstr_Arr_2_Ptr is access Unconstr_Arr_2;
type Subt_Arr_1_Ptr is access Subt_Arr_1;
type Subt_Arr_2_Ptr is access Subt_Arr_2;
type Subt_Arr_3_Ptr is access Subt_Arr_3;
type Subt_Arr_4_Ptr is access Subt_Arr_4;
type Str_Ptr is access String;
type Subt_Str_1_Ptr is access Subt_Str_1;
type Subt_Str_2_Ptr is access Subt_Str_2;
end Types;
-- main.adb
with Types; use Types;
procedure Main is
Byte_Arr_1_Obj : Byte_Arr_1;
Byte_Arr_2_Obj : Byte_Arr_2;
Byte_Arr_3_Obj : Byte_Arr_3 (1 .. Max);
Byte_Arr_4_Obj : Byte_Arr_3 (Big);
Byte_Arr_5_Obj : Byte_Arr_4 (1 .. Max, 1 .. Max);
Byte_Arr_6_Obj : Byte_Arr_4 (Big, Big);
Constr_Arr_1_Obj : Constr_Arr_1;
Constr_Arr_2_Obj : Constr_Arr_2;
Constr_Arr_3_Obj : Constr_Arr_3;
Constr_Arr_4_Obj : Constr_Arr_4;
Unconstr_Arr_1_Obj : Unconstr_Arr_1 (1 .. Max);
Unconstr_Arr_2_Obj : Unconstr_Arr_1 (Big);
Unconstr_Arr_3_Obj : Unconstr_Arr_2 (1 .. Max, 1 .. Max);
Unconstr_Arr_4_Obj : Unconstr_Arr_2 (Big, Big);
Subt_Arr_1_Obj : Subt_Arr_1;
Subt_Arr_2_Obj : Subt_Arr_2;
Subt_Arr_3_Obj : Subt_Arr_3;
Subt_Arr_4_Obj : Subt_Arr_4;
Str_1_Obj : String (1 .. Max);
Str_2_Obj : String (Big);
Subt_Str_1_Obj : Subt_Str_1;
Subt_Str_2_Obj : Subt_Str_2;
Byte_Arr_1_Ptr_Obj : Byte_Arr_1_Ptr := new Byte_Arr_1;
Byte_Arr_2_Ptr_Obj : Byte_Arr_2_Ptr := new Byte_Arr_2;
Byte_Arr_3_Ptr_Obj : Byte_Arr_3_Ptr := new Byte_Arr_3 (1 .. Max);
Byte_Arr_4_Ptr_Obj : Byte_Arr_3_Ptr := new Byte_Arr_3 (Big);
Byte_Arr_5_Ptr_Obj : Byte_Arr_4_Ptr :=
new Byte_Arr_4 (1 .. Max, 1 .. Max);
Byte_Arr_6_Ptr_Obj : Byte_Arr_4_Ptr := new Byte_Arr_4 (Big, Big);
Constr_Arr_1_Ptr_Obj : Constr_Arr_1_Ptr := new Constr_Arr_1;
Constr_Arr_2_Ptr_Obj : Constr_Arr_2_Ptr := new Constr_Arr_2;
Constr_Arr_3_Ptr_Obj : Constr_Arr_3_Ptr := new Constr_Arr_3;
Constr_Arr_4_Ptr_Obj : Constr_Arr_4_Ptr := new Constr_Arr_4;
Unconstr_Arr_1_Ptr_Obj : Unconstr_Arr_1_Ptr :=
new Unconstr_Arr_1 (1 .. Max);
Unconstr_Arr_2_Ptr_Obj : Unconstr_Arr_1_Ptr := new Unconstr_Arr_1 (Big);
Unconstr_Arr_3_Ptr_Obj : Unconstr_Arr_2_Ptr :=
new Unconstr_Arr_2 (1 .. Max, 1 .. Max);
Unconstr_Arr_4_Ptr_Obj : Unconstr_Arr_2_Ptr :=
new Unconstr_Arr_2 (Big, Big);
Subt_Arr_1_Ptr_Obj : Subt_Arr_1_Ptr := new Subt_Arr_1;
Subt_Arr_2_Ptr_Obj : Subt_Arr_2_Ptr := new Subt_Arr_2;
Subt_Arr_3_Ptr_Obj : Subt_Arr_3_Ptr := new Subt_Arr_3;
Subt_Arr_4_Ptr_Obj : Subt_Arr_4_Ptr := new Subt_Arr_4;
Str_Ptr_1_Obj : Str_Ptr := new String (1 .. Max);
Str_Ptr_2_Obj : Str_Ptr := new String (Big);
Subt_Str_1_Ptr_Obj : Subt_Str_1_Ptr := new Subt_Str_1;
Subt_Str_2_Ptr_Obj : Subt_Str_2_Ptr := new Subt_Str_2;
begin null; end Main;
----------------------------
-- Compilation and output --
----------------------------
$ gcc -c -S -gnatDG -gnatws main.adb
$ grep -c "others => types__TbyteB!(0));" main.adb.dg
$ grep -c "others => integer!(0));" main.adb.dg
$ grep -c "others => character!(0));" main.adb.dg
$ grep -c "others => types__TbyteB!(0));" main.adb.dg
$ grep -c "memset" main.s
8
12
8
8
44
2018-05-22 Hristian Kirtchev <kirtchev@adacore.com>
gcc/ada/
* exp_aggr.adb (Aggr_Assignment_OK_For_Backend): Strip away any
conversions before extracting the value of the expression.
* exp_ch3.adb (Default_Initialize_Object): Optimize the default
initialization of an array of scalars.
(Get_Simple_Init_Val): Add processing for array types. Remove the
processing of strings because this case is already handled by the array
case.
(Needs_Simple_Initialization): Moved to Sem_Util.
(Simple_Init_Array_Type): New routine.
(Simple_Init_Initialize_Scalars_Type): Reimplemented to use the new
facilities from Sem_Util.
(Simple_Initialization_OK): New routine.
* exp_ch3.ads (Needs_Simple_Initialization): Moved to Sem_Util.
* exp_ch4.adb (Expand_N_Allocator): Optimize the default allocation of
an array of scalars.
* sem_prag.adb (Analyze_Float_Value): New routine.
(Analyze_Integer_Value): New routine.
(Analyze_Pragma): Reimplement the analysis of pragma Initialize_Scalars
to handled the extended form of the pragma.
(Analyze_Type_Value_Pair): New routine.
* sem_util.adb: Add invalid value-related data structures.
(Examine_Array_Bounds): New routine.
(Has_Static_Array_Bounds): Reimplemented.
(Has_Static_Non_Empty_Array_Bounds): New routine.
(Invalid_Scalar_Value): New routine.
(Needs_Simple_Initialization): Moved from Exp_Ch3.
(Set_Invalid_Scalar_Value): New routines.
* sem_util.ads (Has_Static_Non_Empty_Array_Bounds): New routine.
(Invalid_Scalar_Value): New routine.
(Needs_Simple_Initialization): Moved from Exp_Ch3.
(Set_Invalid_Scalar_Value): New routines.
* snames.ads-tmpl: Add names for the salar type families used by pragma
Initialize_Scalars.
From-SVN: r260529