Commit 95f2be29 by Olivier Hainque Committed by Pierre-Marie de Rodat

[Ada] Front-end support for OpenACC pragmas

This patch introduces the upper part of the Ada front-end support for a first
set of OpenACC directives (Acc_Kernels, Acc_Loop, Acc_Parallel, Acc_Data) and
their clauses.

The pragmas syntax is documented, pragmas are recognized and checked for
syntactic correctness, keyed on -fopenacc. A couple of new flags are defined
on loop statements in the GNAT tree.

2018-09-26  Olivier Hainque  <hainque@adacore.com>

gcc/ada/

	* opt.ads (OpenAcc_Enabled): New flag. False by default. True
	when OpenACC pragmas are requested to be honored, when -fopenacc
	is found on the command line.
	* back_end.adb (Scan_Compiler_Arguments): Set OpenACC_Enabled if
	-fopenacc is seen on the command line.
	* sinfo.adb, sinfo.ads (Is_OpenAcc_Environment): New
	flag/predicate on Loop statements which embed an Acc_Kernels,
	Acc_Parallel or Acc_Data pragma.
	(Is_OpenAcc_Loop): New flag/predicate on Loop statements which
	embed an Acc_Loop pragma.
	(Set_Is_OpenAcc_Environment, Set_Is_OpenAcc_Loop): Setters for
	the new flags.
	* par-prag.adb (Prag): Handle Acc_Data, Acc_Loop, Acc_Parallel
	and Acc_Kernels pragmas.  Nothing to do here, all handled by
	sem_prag.
	* sem_prag.adb (Acc_First, Acc_Next,
	Validate_Acc_Condition_Clause, Validate_Acc_Data_Clause,
	Validate_Acc_Int_Expr_Clause, Validate_Acc_Int_Expr_List_Clause,
	Validate_Acc_Loop_Collapse, Validate_Acc_Loop_Gang,
	Validate_Acc_Loop_Vector, Validate_Acc_Loop_Worker,
	Validate_Acc_Name_Reduction, Validate_Acc_Size_Expressions): New
	helper for Analyze_Pragma, to handle OpenACC pragmas.
	(Analyze_Pragma): Handle Acc_Data, Acc_Loop, Acc_Parallel and
	Acc_Kernels pragmas.
	* sem_ch5.adb (Disable_Constant): Unset Is_True_Constant on
	variable entity, action for ...
	(Disable_Constants): Helper for Analyze_Loop_Statement, to ...
	(Analyze_Loop_Statement): Disable True_Constant on variables
	referenced within an OpenACC environment.
	* snames.ads-tmpl: Declare Name_Ids for the OpenACC directives
	and clauses we can handle. Remove an exraneous whitespace before
	columns, preventing line length overflow in the generated spec
	with Ids now reaching beyond 999.
	* doc/gnat_rm/implementation_defined_pragmas.rst: Document
	pragma Acc_Parallel, Acc_Loop, Acc_Kernels and Acc_Data.
	* gnat_rm.texi: Regenerate.

From-SVN: r264617
parent 8e532681
2018-09-26 Olivier Hainque <hainque@adacore.com>
* opt.ads (OpenAcc_Enabled): New flag. False by default. True
when OpenACC pragmas are requested to be honored, when -fopenacc
is found on the command line.
* back_end.adb (Scan_Compiler_Arguments): Set OpenACC_Enabled if
-fopenacc is seen on the command line.
* sinfo.adb, sinfo.ads (Is_OpenAcc_Environment): New
flag/predicate on Loop statements which embed an Acc_Kernels,
Acc_Parallel or Acc_Data pragma.
(Is_OpenAcc_Loop): New flag/predicate on Loop statements which
embed an Acc_Loop pragma.
(Set_Is_OpenAcc_Environment, Set_Is_OpenAcc_Loop): Setters for
the new flags.
* par-prag.adb (Prag): Handle Acc_Data, Acc_Loop, Acc_Parallel
and Acc_Kernels pragmas. Nothing to do here, all handled by
sem_prag.
* sem_prag.adb (Acc_First, Acc_Next,
Validate_Acc_Condition_Clause, Validate_Acc_Data_Clause,
Validate_Acc_Int_Expr_Clause, Validate_Acc_Int_Expr_List_Clause,
Validate_Acc_Loop_Collapse, Validate_Acc_Loop_Gang,
Validate_Acc_Loop_Vector, Validate_Acc_Loop_Worker,
Validate_Acc_Name_Reduction, Validate_Acc_Size_Expressions): New
helper for Analyze_Pragma, to handle OpenACC pragmas.
(Analyze_Pragma): Handle Acc_Data, Acc_Loop, Acc_Parallel and
Acc_Kernels pragmas.
* sem_ch5.adb (Disable_Constant): Unset Is_True_Constant on
variable entity, action for ...
(Disable_Constants): Helper for Analyze_Loop_Statement, to ...
(Analyze_Loop_Statement): Disable True_Constant on variables
referenced within an OpenACC environment.
* snames.ads-tmpl: Declare Name_Ids for the OpenACC directives
and clauses we can handle. Remove an exraneous whitespace before
columns, preventing line length overflow in the generated spec
with Ids now reaching beyond 999.
* doc/gnat_rm/implementation_defined_pragmas.rst: Document
pragma Acc_Parallel, Acc_Loop, Acc_Kernels and Acc_Data.
* gnat_rm.texi: Regenerate.
2018-09-26 Ed Schonberg <schonberg@adacore.com> 2018-09-26 Ed Schonberg <schonberg@adacore.com>
* sem_ch3.adb (Is_Onown_Limited): A derived type whose parent P * sem_ch3.adb (Is_Onown_Limited): A derived type whose parent P
......
...@@ -375,6 +375,9 @@ package body Back_End is ...@@ -375,6 +375,9 @@ package body Back_End is
elsif Is_Front_End_Switch (Argv) then elsif Is_Front_End_Switch (Argv) then
Scan_Front_End_Switches (Argv, Args, Next_Arg); Scan_Front_End_Switches (Argv, Args, Next_Arg);
elsif Argv (Argv'First + 1 .. Argv'Last) = "fopenacc" then
Opt.OpenAcc_Enabled := True;
-- All non-front-end switches are back-end switches -- All non-front-end switches are back-end switches
else else
......
...@@ -89,6 +89,158 @@ Syntax: ...@@ -89,6 +89,158 @@ Syntax:
For the semantics of this pragma, see the entry for aspect ``Abstract_State`` in For the semantics of this pragma, see the entry for aspect ``Abstract_State`` in
the SPARK 2014 Reference Manual, section 7.1.4. the SPARK 2014 Reference Manual, section 7.1.4.
Pragma Acc_Parallel
===================
Syntax:
.. code-block:: ada
pragma Acc_Parallel [( ACC_PARALLEL_CLAUSE [, ACC_PARALLEL_CLAUSE... ])];
ACC_PARALLEL_CLAUSE ::=
Acc_If => boolean_EXPRESSION
| Acc_Private => IDENTIFIERS
| Async => integer_EXPRESSION
| Copy => IDENTIFIERS
| Copy_In => IDENTIFIERS
| Copy_Out => IDENTIFIERS
| Create => IDENTIFIERS
| Default => None
| Device_Ptr => IDENTIFIERS
| First_Private => IDENTIFIERS
| Num_Gangs => integer_EXPRESSION
| Num_Workers => integer_EXPRESSION
| Present => IDENTIFIERS
| Reduction => (REDUCTION_RECORD)
| Vector_Length => integer_EXPRESSION
| Wait => INTEGERS
REDUCTION_RECORD ::=
"+" => IDENTIFIERS
| "*" => IDENTIFIERS
| "min" => IDENTIFIERS
| "max" => IDENTIFIERS
| "or" => IDENTIFIERS
| "and" => IDENTIFIERS
IDENTIFIERS ::=
| IDENTIFIER
| (IDENTIFIER, IDENTIFIERS)
INTEGERS ::=
| integer_EXPRESSION
| (integer_EXPRESSION, INTEGERS)
Requires the :switch:`-fopenacc` flag.
Equivalent to the ``parallel`` directive of the OpenAcc standard. This pragma
should be placed in loops. It offloads the content of the loop to an
accelerator device.
For more information about the effect of the clauses, see the OpenAcc
specification.
Pragma Acc_Loop
===============
Syntax:
.. code-block:: ada
pragma Acc_Loop [( ACC_LOOP_CLAUSE [, ACC_LOOP_CLAUSE... ])];
ACC_LOOP_CLAUSE ::=
Auto
| Collapse => INTEGER_LITERAL
| Gang [=> GANG_ARG]
| Independent
| Private => IDENTIFIERS
| Reduction => (REDUCTION_RECORD)
| Seq
| Tile => SIZE_EXPRESSION
| Vector [=> integer_EXPRESSION]
| Worker [=> integer_EXPRESSION]
GANG_ARG ::=
integer_EXPRESSION
| Static => SIZE_EXPRESSION
SIZE_EXPRESSION ::=
*
| integer_EXPRESSION
Requires the :switch:`-fopenacc` flag.
Equivalent to the ``loop`` directive of the OpenAcc standard. This pragma
should be placed in for loops after the "Acc_Parallel" pragma. It tells the
compiler how to parallelize the loop.
For more information about the effect of the clauses, see the OpenAcc
specification.
Pragma Acc_Kernels
==================
Syntax:
.. code-block:: ada
pragma Acc_Kernels [( ACC_KERNELS_CLAUSE [, ACC_KERNELS_CLAUSE...])];
ACC_KERNELS_CLAUSE ::=
Acc_If => boolean_EXPRESSION
| Async => integer_EXPRESSION
| Copy => IDENTIFIERS
| Copy_In => IDENTIFIERS
| Copy_Out => IDENTIFIERS
| Create => IDENTIFIERS
| Default => None
| Device_Ptr => IDENTIFIERS
| Num_Gangs => integer_EXPRESSION
| Num_Workers => integer_EXPRESSION
| Present => IDENTIFIERS
| Vector_Length => integer_EXPRESSION
| Wait => INTEGERS
IDENTIFIERS ::=
| IDENTIFIER
| (IDENTIFIER, IDENTIFIERS)
INTEGERS ::=
| integer_EXPRESSION
| (integer_EXPRESSION, INTEGERS)
Requires the :switch:`-fopenacc` flag.
Equivalent to the kernels directive of the OpenAcc standard. This pragma should
be placed in loops.
For more information about the effect of the clauses, see the OpenAcc
specification.
Pragma Acc_Data
===============
Syntax:
.. code-block:: ada
pragma Acc_Data ([ ACC_DATA_CLAUSE [, ACC_DATA_CLAUSE...]]);
ACC_DATA_CLAUSE ::=
Copy => IDENTIFIERS
| Copy_In => IDENTIFIERS
| Copy_Out => IDENTIFIERS
| Create => IDENTIFIERS
| Device_Ptr => IDENTIFIERS
| Present => IDENTIFIERS
Requires the :switch:`-fopenacc` flag.
Equivalent to the ``data`` directive of the OpenAcc standard. This pragma
should be placed in loops.
For more information about the effect of the clauses, see the OpenAcc
specification.
Pragma Ada_83 Pragma Ada_83
============= =============
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -2335,6 +2335,15 @@ package Opt is ...@@ -2335,6 +2335,15 @@ package Opt is
-- The only special comment sequence allowed is --! -- The only special comment sequence allowed is --!
-------------
-- OpenAcc --
-------------
OpenAcc_Enabled : Boolean := False;
-- GNAT
-- Indicates whether OpenAcc pragmas should be taken into account.
-- Set True by use of -fopenacc.
-------------------------- --------------------------
-- Private Declarations -- -- Private Declarations --
-------------------------- --------------------------
......
...@@ -1516,6 +1516,10 @@ begin ...@@ -1516,6 +1516,10 @@ begin
| Pragma_Warning_As_Error | Pragma_Warning_As_Error
| Pragma_Weak_External | Pragma_Weak_External
| Pragma_Validity_Checks | Pragma_Validity_Checks
| Pragma_Acc_Data
| Pragma_Acc_Kernels
| Pragma_Acc_Loop
| Pragma_Acc_Parallel
=> =>
null; null;
......
...@@ -3361,6 +3361,9 @@ package body Sem_Ch5 is ...@@ -3361,6 +3361,9 @@ package body Sem_Ch5 is
procedure Analyze_Loop_Statement (N : Node_Id) is procedure Analyze_Loop_Statement (N : Node_Id) is
function Disable_Constant (N : Node_Id) return Traverse_Result;
-- If N represents an E_Variable entity, set Is_True_Constant To False
function Is_Container_Iterator (Iter : Node_Id) return Boolean; function Is_Container_Iterator (Iter : Node_Id) return Boolean;
-- Given a loop iteration scheme, determine whether it is an Ada 2012 -- Given a loop iteration scheme, determine whether it is an Ada 2012
-- container iteration. -- container iteration.
...@@ -3371,6 +3374,25 @@ package body Sem_Ch5 is ...@@ -3371,6 +3374,25 @@ package body Sem_Ch5 is
-- iterators. Prevents infinite recursion when block is analyzed. -- iterators. Prevents infinite recursion when block is analyzed.
-- Routine is a noop if loop is single statement within source block. -- Routine is a noop if loop is single statement within source block.
----------------------
-- Disable_Constant --
----------------------
function Disable_Constant (N : Node_Id) return Traverse_Result is
begin
if Is_Entity_Name (N)
and then Present (Entity (N))
and then Ekind (Entity (N)) = E_Variable
then
Set_Is_True_Constant (Entity (N), False);
end if;
return OK;
end Disable_Constant;
procedure Disable_Constants is new Traverse_Proc (Disable_Constant);
-- Helper for Analyze_Loop_Statement, to unset Is_True_Constant on
-- variables referenced within an OpenACC environment.
--------------------------- ---------------------------
-- Is_Container_Iterator -- -- Is_Container_Iterator --
--------------------------- ---------------------------
...@@ -3812,6 +3834,15 @@ package body Sem_Ch5 is ...@@ -3812,6 +3834,15 @@ package body Sem_Ch5 is
if No (Iter) and then not Has_Exit (Ent) then if No (Iter) and then not Has_Exit (Ent) then
Check_Unreachable_Code (Stmt); Check_Unreachable_Code (Stmt);
end if; end if;
-- Variables referenced within a loop subject to possible OpenACC
-- offloading may be implicitly written to as part of the OpenACC
-- transaction. Clear flags possibly conveying that they are constant,
-- set for example when the code does not explicitly assign them.
if Is_OpenAcc_Environment (Stmt) then
Disable_Constants (Stmt);
end if;
end Analyze_Loop_Statement; end Analyze_Loop_Statement;
---------------------------- ----------------------------
......
...@@ -2069,6 +2069,22 @@ package body Sinfo is ...@@ -2069,6 +2069,22 @@ package body Sinfo is
return Flag16 (N); return Flag16 (N);
end Is_Null_Loop; end Is_Null_Loop;
function Is_OpenAcc_Environment
(N : Node_Id) return Boolean is
begin
pragma Assert (False
or else NT (N).Nkind = N_Loop_Statement);
return Flag13 (N);
end Is_OpenAcc_Environment;
function Is_OpenAcc_Loop
(N : Node_Id) return Boolean is
begin
pragma Assert (False
or else NT (N).Nkind = N_Loop_Statement);
return Flag14 (N);
end Is_OpenAcc_Loop;
function Is_Overloaded function Is_Overloaded
(N : Node_Id) return Boolean is (N : Node_Id) return Boolean is
begin begin
...@@ -5527,6 +5543,22 @@ package body Sinfo is ...@@ -5527,6 +5543,22 @@ package body Sinfo is
Set_Flag16 (N, Val); Set_Flag16 (N, Val);
end Set_Is_Null_Loop; end Set_Is_Null_Loop;
procedure Set_Is_OpenAcc_Environment
(N : Node_Id; Val : Boolean := True) is
begin
pragma Assert (False
or else NT (N).Nkind = N_Loop_Statement);
Set_Flag13 (N, Val);
end Set_Is_OpenAcc_Environment;
procedure Set_Is_OpenAcc_Loop
(N : Node_Id; Val : Boolean := True) is
begin
pragma Assert (False
or else NT (N).Nkind = N_Loop_Statement);
Set_Flag14 (N, Val);
end Set_Is_OpenAcc_Loop;
procedure Set_Is_Overloaded procedure Set_Is_Overloaded
(N : Node_Id; Val : Boolean := True) is (N : Node_Id; Val : Boolean := True) is
begin begin
......
...@@ -1896,6 +1896,14 @@ package Sinfo is ...@@ -1896,6 +1896,14 @@ package Sinfo is
-- can be determined to be null at compile time. This is used to remove -- can be determined to be null at compile time. This is used to remove
-- the loop entirely at expansion time. -- the loop entirely at expansion time.
-- Is_OpenAcc_Environment (Flag13-Sem)
-- This flag is set in an N_Loop_Statement node if it contains an
-- Acc_Data, Acc_Parallel or Add_Kernels pragma.
-- Is_OpenAcc_Loop (Flag14-Sem)
-- This flag is set in an N_Loop_Statement node if it contains an
-- OpenAcc_Loop pragma.
-- Is_Overloaded (Flag5-Sem) -- Is_Overloaded (Flag5-Sem)
-- A flag present in all expression nodes. Used temporarily during -- A flag present in all expression nodes. Used temporarily during
-- overloading determination. The setting of this flag is not relevant -- overloading determination. The setting of this flag is not relevant
...@@ -5129,6 +5137,8 @@ package Sinfo is ...@@ -5129,6 +5137,8 @@ package Sinfo is
-- Has_Created_Identifier (Flag15) -- Has_Created_Identifier (Flag15)
-- Is_Null_Loop (Flag16) -- Is_Null_Loop (Flag16)
-- Suppress_Loop_Warnings (Flag17) -- Suppress_Loop_Warnings (Flag17)
-- Is_OpenAcc_Environment (Flag13-Sem)
-- Is_OpenAcc_Loop (Flag14-Sem)
-- Note: the parser fills in the Identifier field if there is an -- Note: the parser fills in the Identifier field if there is an
-- explicit loop identifier. Otherwise the parser leaves this field -- explicit loop identifier. Otherwise the parser leaves this field
...@@ -9847,6 +9857,12 @@ package Sinfo is ...@@ -9847,6 +9857,12 @@ package Sinfo is
function Is_Null_Loop function Is_Null_Loop
(N : Node_Id) return Boolean; -- Flag16 (N : Node_Id) return Boolean; -- Flag16
function Is_OpenAcc_Environment
(N : Node_Id) return Boolean; -- Flag13
function Is_OpenAcc_Loop
(N : Node_Id) return Boolean; -- Flag14
function Is_Overloaded function Is_Overloaded
(N : Node_Id) return Boolean; -- Flag5 (N : Node_Id) return Boolean; -- Flag5
...@@ -10945,6 +10961,12 @@ package Sinfo is ...@@ -10945,6 +10961,12 @@ package Sinfo is
procedure Set_Is_Null_Loop procedure Set_Is_Null_Loop
(N : Node_Id; Val : Boolean := True); -- Flag16 (N : Node_Id; Val : Boolean := True); -- Flag16
procedure Set_Is_OpenAcc_Environment
(N : Node_Id; Val : Boolean := True); -- Flag13
procedure Set_Is_OpenAcc_Loop
(N : Node_Id; Val : Boolean := True); -- Flag14
procedure Set_Is_Overloaded procedure Set_Is_Overloaded
(N : Node_Id; Val : Boolean := True); -- Flag5 (N : Node_Id; Val : Boolean := True); -- Flag5
...@@ -13450,6 +13472,8 @@ package Sinfo is ...@@ -13450,6 +13472,8 @@ package Sinfo is
pragma Inline (Is_Known_Guaranteed_ABE); pragma Inline (Is_Known_Guaranteed_ABE);
pragma Inline (Is_Machine_Number); pragma Inline (Is_Machine_Number);
pragma Inline (Is_Null_Loop); pragma Inline (Is_Null_Loop);
pragma Inline (Is_OpenAcc_Environment);
pragma Inline (Is_OpenAcc_Loop);
pragma Inline (Is_Overloaded); pragma Inline (Is_Overloaded);
pragma Inline (Is_Power_Of_2_For_Shift); pragma Inline (Is_Power_Of_2_For_Shift);
pragma Inline (Is_Prefixed_Call); pragma Inline (Is_Prefixed_Call);
...@@ -13812,6 +13836,8 @@ package Sinfo is ...@@ -13812,6 +13836,8 @@ package Sinfo is
pragma Inline (Set_Is_Known_Guaranteed_ABE); pragma Inline (Set_Is_Known_Guaranteed_ABE);
pragma Inline (Set_Is_Machine_Number); pragma Inline (Set_Is_Machine_Number);
pragma Inline (Set_Is_Null_Loop); pragma Inline (Set_Is_Null_Loop);
pragma Inline (Set_Is_OpenAcc_Environment);
pragma Inline (Set_Is_OpenAcc_Loop);
pragma Inline (Set_Is_Overloaded); pragma Inline (Set_Is_Overloaded);
pragma Inline (Set_Is_Power_Of_2_For_Shift); pragma Inline (Set_Is_Power_Of_2_For_Shift);
pragma Inline (Set_Is_Prefixed_Call); pragma Inline (Set_Is_Prefixed_Call);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment