===================================================================
@@ -176,6 +176,7 @@
* Pragma Linker_Destructor::
* Pragma Linker_Section::
* Pragma Long_Float::
+* Pragma Loop_Optimize::
* Pragma Machine_Attribute::
* Pragma Main::
* Pragma Main_Storage::
@@ -925,6 +926,7 @@
* Pragma Linker_Destructor::
* Pragma Linker_Section::
* Pragma Long_Float::
+* Pragma Loop_Optimize::
* Pragma Machine_Attribute::
* Pragma Main::
* Pragma Main_Storage::
@@ -3845,6 +3848,55 @@
@cite{DEC Ada Language Reference Manual}, section 3.5.7b. Note that to use
this pragma, the standard runtime libraries must be recompiled.
+@node Pragma Loop_Optimize
+@unnumberedsec Pragma Loop_Optimize
+@findex Loop_Optimize
+@noindent
+Syntax:
+
+@smallexample @c ada
+pragma Loop_Optimize (OPTIMIZATION_HINT @{, OPTIMIZATION_HINT@});
+
+OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector
+@end smallexample
+
+@noindent
+This pragma must appear immediately within a loop statement. It allows the
+programmer to specify optimization hints for the enclosing loop. The hints
+are not mutually exclusive and can be freely mixed, but not all combinations
+will yield a sensible outcome.
+
+There are four supported optimization hints for a loop:
+@itemize @bullet
+@item No_Unroll
+
+The loop must not be unrolled. This is a strong hint: the compiler will not
+unroll a loop marked with this hint.
+
+@item Unroll
+
+The loop should be unrolled. This is a weak hint: the compiler will try to
+apply unrolling to this loop preferably to other optimizations, notably
+vectorization, but there is no guarantee that the loop will be unrolled.
+
+@item No_Vector
+
+The loop must not be vectorized. This is a strong hint: the compiler will not
+vectorize a loop marked with this hint.
+
+@item Vector
+
+The loop should be vectorized. This is a weak hint: the compiler will try to
+apply vectorization to this loop preferably to other optimizations, notably
+unrolling, but there is no guarantee that the loop will be vectorized.
+
+@end itemize
+
+These hints do not void the need to pass the appropriate switches to the
+compiler in order to enable the relevant optimizations, that is to say
+@option{-funroll-loops} for unrolling and @option{-ftree-vectorize} for
+vectorization.
+
@node Pragma Machine_Attribute
@unnumberedsec Pragma Machine_Attribute
@findex Machine_Attribute
===================================================================
@@ -10978,6 +10978,17 @@
bounds of the array, the more fallback code it needs to generate in order to
fix things up at run time.
+It is possible to specify that a given loop should be subject to vectorization
+preferably to other optimizations by means of pragma @code{Loop_Optimize}:
+
+@smallexample @c ada
+ pragma Loop_Optimize (Vector);
+@end smallexample
+
+@noindent
+placed immediately within the loop will convey the appropriate hint to the
+compiler for this loop.
+
You can obtain information about the vectorization performed by the compiler
by specifying @option{-ftree-vectorizer-verbose=N}. For more details of
this switch, see @ref{Debugging Options,,Options for Debugging Your Program
===================================================================
@@ -1203,6 +1203,7 @@
Pragma_Locking_Policy |
Pragma_Long_Float |
Pragma_Loop_Invariant |
+ Pragma_Loop_Optimize |
Pragma_Loop_Variant |
Pragma_Machine_Attribute |
Pragma_Main |
===================================================================
@@ -618,9 +618,9 @@
-- Common processing for first argument of pragma Interrupt_Handler or
-- pragma Attach_Handler.
- procedure Check_Loop_Invariant_Variant_Placement;
- -- Verify whether pragma Loop_Invariant or pragma Loop_Variant appear
- -- immediately within a construct restricted to loops.
+ procedure Check_Loop_Pragma_Placement;
+ -- Verify whether pragma Loop_Invariant or Loop_Optimize or Loop_Variant
+ -- appear immediately within a construct restricted to loops.
procedure Check_Is_In_Decl_Part_Or_Package_Spec;
-- Check that pragma appears in a declarative part, or in a package
@@ -1922,11 +1922,11 @@
end if;
end Check_Interrupt_Or_Attach_Handler;
- --------------------------------------------
- -- Check_Loop_Invariant_Variant_Placement --
- --------------------------------------------
+ ---------------------------------
+ -- Check_Loop_Pragma_Placement --
+ ---------------------------------
- procedure Check_Loop_Invariant_Variant_Placement is
+ procedure Check_Loop_Pragma_Placement is
procedure Placement_Error (Constr : Node_Id);
pragma No_Return (Placement_Error);
-- Node Constr denotes the last loop restricted construct before we
@@ -1955,7 +1955,7 @@
Prev : Node_Id;
Stmt : Node_Id;
- -- Start of processing for Check_Loop_Invariant_Variant_Placement
+ -- Start of processing for Check_Loop_Pragma_Placement
begin
Prev := N;
@@ -2011,7 +2011,7 @@
return;
end if;
end loop;
- end Check_Loop_Invariant_Variant_Placement;
+ end Check_Loop_Pragma_Placement;
-------------------------------------------
-- Check_Is_In_Decl_Part_Or_Package_Spec --
@@ -12341,7 +12341,7 @@
GNAT_Pragma;
S14_Pragma;
Check_Arg_Count (1);
- Check_Loop_Invariant_Variant_Placement;
+ Check_Loop_Pragma_Placement;
-- Completely ignore if disabled
@@ -12370,6 +12370,30 @@
Analyze (N);
end Loop_Invariant;
+ -------------------
+ -- Loop_Optimize --
+ -------------------
+
+ -- pragma Loop_Optimize ( OPTIMIZATION_HINT {, OPTIMIZATION_HINT } );
+
+ -- OPTIMIZATION_HINT ::= No_Unroll | Unroll | No_Vector | Vector
+
+ when Pragma_Loop_Optimize => Loop_Optimize : declare
+ Hint : Node_Id;
+
+ begin
+ GNAT_Pragma;
+ Check_At_Least_N_Arguments (1);
+ Check_No_Identifiers;
+ Hint := First (Pragma_Argument_Associations (N));
+ while Present (Hint) loop
+ Check_Arg_Is_One_Of (Hint, Name_No_Unroll, Name_Unroll,
+ Name_No_Vector, Name_Vector);
+ Next (Hint);
+ end loop;
+ Check_Loop_Pragma_Placement;
+ end Loop_Optimize;
+
------------------
-- Loop_Variant --
------------------
@@ -12388,7 +12412,7 @@
GNAT_Pragma;
S14_Pragma;
Check_At_Least_N_Arguments (1);
- Check_Loop_Invariant_Variant_Placement;
+ Check_Loop_Pragma_Placement;
-- Completely ignore if disabled
@@ -16598,6 +16622,7 @@
Pragma_Locking_Policy => -1,
Pragma_Long_Float => -1,
Pragma_Loop_Invariant => -1,
+ Pragma_Loop_Optimize => -1,
Pragma_Loop_Variant => -1,
Pragma_Machine_Attribute => -1,
Pragma_Main => -1,
===================================================================
@@ -408,6 +408,7 @@
Name_Locking_Policy : constant Name_Id := N + $;
Name_Long_Float : constant Name_Id := N + $; -- VMS
Name_Loop_Invariant : constant Name_Id := N + $; -- GNAT
+ Name_Loop_Optimize : constant Name_Id := N + $; -- GNAT
Name_Loop_Variant : constant Name_Id := N + $; -- GNAT
Name_No_Run_Time : constant Name_Id := N + $; -- GNAT
Name_No_Strict_Aliasing : constant Name_Id := N + $; -- GNAT
@@ -727,6 +728,8 @@
Name_No_Specification_Of_Aspect : constant Name_Id := N + $;
Name_No_Task_Attributes : constant Name_Id := N + $;
Name_No_Task_Attributes_Package : constant Name_Id := N + $;
+ Name_No_Unroll : constant Name_Id := N + $;
+ Name_No_Vector : constant Name_Id := N + $;
Name_Nominal : constant Name_Id := N + $;
Name_On : constant Name_Id := N + $;
Name_Optional : constant Name_Id := N + $;
@@ -762,10 +765,12 @@
Name_Unit_Name : constant Name_Id := N + $;
Name_Unknown : constant Name_Id := N + $;
Name_Unrestricted : constant Name_Id := N + $;
+ Name_Unroll : constant Name_Id := N + $;
Name_Uppercase : constant Name_Id := N + $;
Name_User : constant Name_Id := N + $;
Name_Variant : constant Name_Id := N + $;
Name_VAX_Float : constant Name_Id := N + $;
+ Name_Vector : constant Name_Id := N + $;
Name_VMS : constant Name_Id := N + $;
Name_Vtable_Ptr : constant Name_Id := N + $;
Name_Working_Storage : constant Name_Id := N + $;
@@ -1705,6 +1710,7 @@
Pragma_Locking_Policy,
Pragma_Long_Float,
Pragma_Loop_Invariant,
+ Pragma_Loop_Optimize,
Pragma_Loop_Variant,
Pragma_No_Run_Time,
Pragma_No_Strict_Aliasing,