aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2009-07-23 12:20:25 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2009-07-23 12:20:25 +0200
commit4b956d8b3b94807070186658bc664143794c897e (patch)
tree91328debdc2d744bf70f90dce39357bb331672a1
parentf8c6086ba8474e5997bec4d1f9c44e1ee6a7d601 (diff)
downloadgcc-4b956d8b3b94807070186658bc664143794c897e.zip
gcc-4b956d8b3b94807070186658bc664143794c897e.tar.gz
gcc-4b956d8b3b94807070186658bc664143794c897e.tar.bz2
[multiple changes]
2009-07-23 Olivier Hainque <hainque@adacore.com> * g-ssinty.ads: New unit. GNAT.SSE.Internal_Types. Factorize low level internal type definitions for distinct higher level binding development activities (user type definitions and operations). * gnat_rm.texi: Document it. * g-ssvety.ads: Use it. * gcc-interface/Makefile.in: (x86 32/64 linux, cygwin32 sections): Add g-ssinty.o to EXTRA_GNATRTL_NONTASKING_OBJS. * gcc-interface/utils.c (gnat_internal_attribute_table): Add entry for the "may_alias" attribute. 2009-07-23 Thomas Quinot <quinot@adacore.com> * scos.ads: Minor typo fix * gcc-interface/decl.c (validate_alignment): For the case of an implicit array base type, look for alignment clause on first subtype. Code clean up. 2009-07-23 Ed Schonberg <schonberg@adacore.com> * sem.adb (Walk_Library_Units): Handle properly the case where a unit in the context depends on the spec of the main unit, by delaying processing of the main unit body until all other units have been processed. From-SVN: r149993
-rw-r--r--gcc/ada/ChangeLog27
-rw-r--r--gcc/ada/g-ssinty.ads77
-rw-r--r--gcc/ada/g-ssvety.ads77
-rw-r--r--gcc/ada/gcc-interface/Makefile.in6
-rw-r--r--gcc/ada/gcc-interface/utils.c1
-rw-r--r--gcc/ada/gnat_rm.texi11
-rw-r--r--gcc/ada/scos.ads2
-rw-r--r--gcc/ada/sem.adb61
8 files changed, 200 insertions, 62 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index c07e719..dc4d8a5 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,30 @@
+2009-07-23 Olivier Hainque <hainque@adacore.com>
+
+ * g-ssinty.ads: New unit. GNAT.SSE.Internal_Types. Factorize
+ low level internal type definitions for distinct higher level
+ binding development activities (user type definitions and
+ operations).
+ * gnat_rm.texi: Document it.
+ * g-ssvety.ads: Use it.
+ * gcc-interface/Makefile.in: (x86 32/64 linux, cygwin32 sections): Add
+ g-ssinty.o to EXTRA_GNATRTL_NONTASKING_OBJS.
+ * gcc-interface/utils.c (gnat_internal_attribute_table): Add entry
+ for the "may_alias" attribute.
+
+2009-07-23 Thomas Quinot <quinot@adacore.com>
+
+ * scos.ads: Minor typo fix
+ * gcc-interface/decl.c (validate_alignment): For the case of an
+ implicit array base type, look for alignment clause on first subtype.
+ Code clean up.
+
+2009-07-23 Ed Schonberg <schonberg@adacore.com>
+
+ * sem.adb (Walk_Library_Units): Handle properly the case where a unit
+ in the context depends on the spec of the main unit, by delaying
+ processing of the main unit body until all other units have been
+ processed.
+
2009-07-23 Arnaud Charlet <charlet@adacore.com>
* a-convec.adb: Add comments about suspicious/subtle code.
diff --git a/gcc/ada/g-ssinty.ads b/gcc/ada/g-ssinty.ads
new file mode 100644
index 0000000..becdc76
--- /dev/null
+++ b/gcc/ada/g-ssinty.ads
@@ -0,0 +1,77 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S S E . I N T E R N A L _ T Y P E S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2009, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This unit exposes low level types to interface with the GCC vector
+-- builtins directly. These are useful for the development of higher level
+-- bindings to the reference Intel intrinsic operations.
+
+-- See GNAT.SSE for the list of targets where this facility is supported.
+
+package GNAT.SSE.Internal_Types is
+
+ type v4sf is private;
+ type v2df is private;
+ type v2di is private;
+
+private
+
+ -- GCC'wise, vector operations operate on objects of vector modes,
+ -- conveyed through vector types obtained in C by setting an attribute on
+ -- what looks like a component typedef. For example, in xmmintrin.h:
+ --
+ -- typedef float __v4sf __attribute__ ((__vector_size__ (16)));
+
+ -- Applying a 'vector_size' machine attribute in Ada, as in
+ --
+ -- type Vf is new Float;
+ -- pragma Machine_Attribute (Vf, "vector_size", 16);
+ --
+ -- makes Vf a 16bytes long V4SFmode GCC type but the effect on the type
+ -- layout is not conveyed to the front-end. The latter still sees "Vf"
+ -- as a 4bytes long single float, with numerous potential pitfalls.
+
+ -- We devised a 'vector_type' alternate machine attribute, which applies
+ -- to array types of the proper size and alignment from the front-end
+ -- perspective:
+
+ type v4sf is array (1 .. 4) of GNAT.SSE.Float32;
+ for v4sf'Alignment use GNAT.SSE.VECTOR_ALIGN;
+ pragma Machine_Attribute (v4sf, "vector_type");
+
+ type v2di is array (1 .. 2) of GNAT.SSE.Integer64;
+ for v2di'Alignment use GNAT.SSE.VECTOR_ALIGN;
+ pragma Machine_Attribute (v2di, "vector_type");
+
+ type v2df is array (1 .. 2) of GNAT.SSE.Float64;
+ for v2df'Alignment use GNAT.SSE.VECTOR_ALIGN;
+ pragma Machine_Attribute (v2df, "vector_type");
+
+end GNAT.SSE.Internal_Types;
diff --git a/gcc/ada/g-ssvety.ads b/gcc/ada/g-ssvety.ads
index eb7d590..42cd24b 100644
--- a/gcc/ada/g-ssvety.ads
+++ b/gcc/ada/g-ssvety.ads
@@ -30,7 +30,9 @@
------------------------------------------------------------------------------
-- This unit exposes the Ada __m128 like data types to represent the contents
--- of SSE registers, for use by the SSE intrinsics.
+-- of SSE registers, for use by bindings to the SSE intrinsic operations.
+
+-- See GNAT.SSE for the list of targets where this facility is supported.
package GNAT.SSE.Vector_Types is
@@ -49,32 +51,23 @@ package GNAT.SSE.Vector_Types is
-- * Use new data types only with the respective intrinsics described
-- in this documentation. >>
- type M128 is private; -- SSE >= 1
- type M128d is private; -- SSE >= 2
- type M128i is private; -- SSE >= 2
+ type m128 is private; -- SSE >= 1
+ type m128d is private; -- SSE >= 2
+ type m128i is private; -- SSE >= 2
private
- -- GCC'wise, vector operations operate on objects of vector modes,
- -- conveyed through vector types obtained by setting an attribute on what
- -- looks like a component typedef. For example, in C (xmmintrin.h):
- --
- -- typedef float __v4sf __attribute__ ((__vector_size__ (16)));
- -- We can obtain the same low level GCC effect in Ada with
- -- Machine_Attribute pragmas, as in
+ -- Each of the m128 types maps to a specific vector_type with
+ -- an extra "may_alias" attribute as in GCC's definitions for C,
+ -- for instance in xmmintrin.h:
--
- -- type Vf is new Float;
- -- pragma Machine_Attribute (Vf, "vector_size", 16);
+ -- /* The Intel API is flexible enough that we must allow aliasing
+ -- with other vector types, and their scalar components. */
+ -- typedef float __m128
+ -- __attribute__ ((__vector_size__ (16), __may_alias__));
--
- -- which makes Vf a 16bytes long V4SFmode type for GCC. The effect on the
- -- type layout is not conveyed to the front-end, however, so the latter
- -- still sees "Vf" as a 4bytes long single float. This leads to numerous
- -- potential pitfalls if this type is directly exposed user land, so we
- -- add wrapper records with rep clauses to compensate.
-
- -- The wrapper records all have a single component of the twisted low
- -- level type, so they inherit the mode while the rep clauses convey the
- -- size and alignment information to the front-end.
+ -- /* Internal data types for implementing the intrinsics. */
+ -- typedef float __v4sf __attribute__ ((__vector_size__ (16)));
------------
-- M128 --
@@ -82,44 +75,32 @@ private
-- << The __m128 data type can hold four 32-bit floating-point values. >>
- type V4sf is new Float32;
- pragma Machine_Attribute (V4sf, "vector_size", VECTOR_BYTES);
-
- type M128 is record
- Value : V4sf;
- end record;
- for M128'Size use VECTOR_BYTES * 8;
- for M128'Alignment use VECTOR_ALIGN;
+ type m128 is array (1 .. 4) of Float32;
+ for m128'Alignment use VECTOR_ALIGN;
+ pragma Machine_Attribute (m128, "vector_type");
+ pragma Machine_Attribute (m128, "may_alias");
-------------
- -- M128d --
+ -- m128d --
-------------
-- << The __m128d data type can hold two 64-bit floating-point values. >>
- type V2df is new Float64;
- pragma Machine_Attribute (V2df, "vector_size", VECTOR_BYTES);
-
- type M128d is record
- Value : V2df;
- end record;
- for M128d'Size use VECTOR_BYTES * 8;
- for M128d'Alignment use VECTOR_ALIGN;
+ type m128d is array (1 .. 2) of Float64;
+ for m128d'Alignment use VECTOR_ALIGN;
+ pragma Machine_Attribute (m128d, "vector_type");
+ pragma Machine_Attribute (m128d, "may_alias");
-------------
- -- M128i --
+ -- m128i --
-------------
-- << The __m128i data type can hold sixteen 8-bit, eight 16-bit, four
-- 32-bit, or two 64-bit integer values. >>
- type V2di is new Integer64;
- pragma Machine_Attribute (V2di, "vector_size", VECTOR_BYTES);
-
- type M128i is record
- Value : V2di;
- end record;
- for M128i'Size use VECTOR_BYTES * 8;
- for M128i'Alignment use VECTOR_ALIGN;
+ type m128i is array (1 .. 2) of Integer64;
+ for m128i'Alignment use VECTOR_ALIGN;
+ pragma Machine_Attribute (m128i, "vector_type");
+ pragma Machine_Attribute (m128i, "may_alias");
end GNAT.SSE.Vector_Types;
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index d487716..0e80808 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -1052,7 +1052,7 @@ ifeq ($(strip $(filter-out %86 linux%,$(arch) $(osys))),)
endif
THREADSLIB = -lpthread
- EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o g-ssinty.o
EXTRA_GNATRTL_TASKING_OBJS=s-linux.o
endif
@@ -1593,7 +1593,7 @@ ifeq ($(strip $(filter-out cygwin32% mingw32% pe,$(osys))),)
endif
EXTRA_GNATRTL_NONTASKING_OBJS = \
- s-win32.o s-winext.o g-regist.o g-sse.o g-ssvety.o
+ s-win32.o s-winext.o g-regist.o g-sse.o g-ssvety.o g-ssinty.o
EXTRA_GNATRTL_TASKING_OBJS = a-exetim.o
MISCLIB = -lws2_32
@@ -2003,7 +2003,7 @@ ifeq ($(strip $(filter-out %x86_64 linux%,$(arch) $(osys))),)
mlib-tgt-specific.adb<mlib-tgt-specific-linux.adb \
indepsw.adb<indepsw-gnu.adb
- EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o
+ EXTRA_GNATRTL_NONTASKING_OBJS=g-sse.o g-ssvety.o g-ssinty.o
EXTRA_GNATRTL_TASKING_OBJS=s-linux.o
EH_MECHANISM=-gcc
THREADSLIB=-lpthread
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 59d9477..1548f6d 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -122,6 +122,7 @@ const struct attribute_spec gnat_internal_attribute_table[] =
{ "type generic", 0, 0, false, true, true, handle_type_generic_attribute },
{ "vector_size", 1, 1, false, true, false, handle_vector_size_attribute },
+ { "may_alias", 0, 0, false, true, false, NULL },
/* ??? format and format_arg are heavy and not supported, which actually
prevents support for stdio builtins, which we however declare as part
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 1f26563..14a7a8f 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -382,6 +382,7 @@ The GNAT Library
* GNAT.Spitbol.Table_Integer (g-sptain.ads)::
* GNAT.Spitbol.Table_VString (g-sptavs.ads)::
* GNAT.SSE (g-sse.ads)::
+* GNAT.SSE.Internal_Types (g-ssinty.ads)::
* GNAT.SSE.Vector_Types (g-ssvety.ads)::
* GNAT.Strings (g-string.ads)::
* GNAT.String_Split (g-strspl.ads)::
@@ -13571,6 +13572,7 @@ of GNAT, and will generate a warning message.
* GNAT.Spitbol.Table_Integer (g-sptain.ads)::
* GNAT.Spitbol.Table_VString (g-sptavs.ads)::
* GNAT.SSE (g-sse.ads)::
+* GNAT.SSE.Internal_Types (g-ssinty.ads)::
* GNAT.SSE.Vector_Types (g-ssvety.ads)::
* GNAT.Strings (g-string.ads)::
* GNAT.String_Split (g-strspl.ads)::
@@ -14641,6 +14643,15 @@ the Intel(r) Streaming SIMD Extensions with GNAT on the x86 family of
targets. It exposes vector component types together with a general
introduction to the binding contents and use.
+@node GNAT.SSE.Internal_Types (g-ssinty.ads)
+@section @code{GNAT.SSE.Internal_Types} (@file{g-ssinty.ads})
+@cindex @code{GNAT.SSE.Internal_Types} (@file{g-ssinty.ads})
+
+@noindent
+Low level GCC vector types for direct use of the vector related
+builtins, required for the development of higher level bindings to SSE
+intrinsic operations.
+
@node GNAT.SSE.Vector_Types (g-ssvety.ads)
@section @code{GNAT.SSE.Vector_Types} (@file{g-ssvety.ads})
@cindex @code{GNAT.SSE.Vector_Types} (@file{g-ssvety.ads})
diff --git a/gcc/ada/scos.ads b/gcc/ada/scos.ads
index fa039a5..15c2053 100644
--- a/gcc/ada/scos.ads
+++ b/gcc/ada/scos.ads
@@ -103,7 +103,7 @@ package SCOs is
-- Statement lines
-- These lines correspond to a sequence of one or more statements which
- -- are always exeecuted in sequence, The first statement may be an entry
+ -- are always executed in sequence, The first statement may be an entry
-- point (e.g. statement after a label), and the last statement may be
-- an exit point (e.g. an exit statement), but no other entry or exit
-- points may occur within the sequence of statements. The idea is that
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index f5beda4..f60c143 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -107,7 +107,6 @@ package body Sem is
procedure Analyze (N : Node_Id) is
begin
Debug_A_Entry ("analyzing ", N);
-
-- Immediate return if already analyzed
if Analyzed (N) then
@@ -1510,6 +1509,12 @@ package body Sem is
-- after we have fully processed X, and is used only for debugging
-- printouts and assertions.
+ Do_Main : Boolean := False;
+ -- Flag to delay processing the main body until after all other units.
+ -- This is needed because the spec of the main unit may appear in the
+ -- context of some other unit. We do not want this to force processing
+ -- of the main body before all other units have been processed.
+
procedure Do_Action (CU : Node_Id; Item : Node_Id);
-- Calls Action, with some validity checks
@@ -1712,7 +1717,8 @@ package body Sem is
if not Nkind_In (Item, N_Package_Body, N_Subprogram_Body)
or else Acts_As_Spec (CU)
- or else CU = Cunit (Main_Unit)
+ or else (CU = Cunit (Main_Unit) and then Do_Main)
+
then
Do_Action (CU, Item);
@@ -1733,14 +1739,47 @@ package body Sem is
-- be possible to restrict the list to those bodies that are used
-- in the main unit. Possible optimization ???
+ -- Such bodies can also appear in a circular dependency list, where
+ -- spec A depends on spec B and the body of B depends on spec A.
+ -- This is not an elaboration issue, but body B must be excluded
+ -- from the processing.
+
if Nkind (Item) = N_Package_Declaration then
declare
Body_Unit : constant Node_Id := Library_Unit (CU);
+ function Circular_Dependence (B : Node_Id) return Boolean;
+ -- Check whether this body depends on a spec that is pending,
+ -- that is to say has been seen but not processed yet.
+
+ function Circular_Dependence (B : Node_Id) return Boolean is
+ Item : Node_Id;
+ UN : Unit_Number_Type;
+
+ begin
+ Item := First (Context_Items (B));
+ while Present (Item) loop
+ if Nkind (Item) = N_With_Clause then
+ UN := Get_Cunit_Unit_Number (Library_Unit (Item));
+
+ if Seen (UN)
+ and then not Done (UN)
+ then
+ return True;
+ end if;
+ end if;
+
+ Next (Item);
+ end loop;
+
+ return False;
+ end Circular_Dependence;
+
begin
if Present (Body_Unit)
and then Body_Unit /= Cunit (Main_Unit)
and then Unit_Num /= Get_Source_Unit (System_Aux_Id)
+ and then not Circular_Dependence (Body_Unit)
then
Do_Unit_And_Dependents (Body_Unit, Unit (Body_Unit));
Do_Action (Body_Unit, Unit (Body_Unit));
@@ -1801,16 +1840,13 @@ package body Sem is
case Nkind (N) is
- -- If it's a body, then ignore it, unless it's the main unit
- -- Otherwise bodies appear in the list because of inlining or
- -- instantiations, and they are processed immediately after
- -- the corresponding specs.
+ -- If it's a body, ignore it. Bodies appear in the list only
+ -- because of inlining/instantiations, and they are processed
+ -- immediately after the corresponding specs.
+ -- The main unit is processed separately after all other units.
when N_Package_Body | N_Subprogram_Body =>
-
- if CU = Cunit (Main_Unit) then
- Do_Unit_And_Dependents (CU, N);
- end if;
+ null;
-- It's a spec, so just do it
@@ -1822,6 +1858,11 @@ package body Sem is
Next_Elmt (Cur);
end loop;
+ if not Done (Main_Unit) then
+ Do_Main := True;
+ Do_Unit_And_Dependents (Cunit (Main_Unit), Unit (Cunit (Main_Unit)));
+ end if;
+
if Debug_Unit_Walk then
if Done /= (Done'Range => True) then
Write_Eol;