Patchwork [Ada] Preliminary work to implement pragma Loop_Optimize

login
register
mail settings
Submitter Arnaud Charlet
Date Feb. 6, 2013, 10:47 a.m.
Message ID <20130206104735.GA20595@adacore.com>
Download mbox | patch
Permalink /patch/218543/
State New
Headers show

Comments

Arnaud Charlet - Feb. 6, 2013, 10:47 a.m.
This is the front-end implementation of the new Loop_Optimize pragma, which
makes it possible for the programmer to control the optimizations applied to
loops on an individual basis.

Tested on x86_64-pc-linux-gnu, committed on trunk

2013-02-06  Eric Botcazou  <ebotcazou@adacore.com>

	* snames.ads-tmpl (Name_Loop_Optimize, Name_No_Unroll,
	Name_Unroll, Name_No_Vector, Name_Vector): New pragma-related
	names.
	(Pragma_Id): Add Pragma_Loop_Optimize value.
	* par-prag.adb (Prag): Handle Pragma_Loop_Optimize.
	* sem_prag.adb (Check_Loop_Invariant_Variant_Placement): Rename to...
	(Check_Loop_Pragma_Placement): ...this.
	(Analyze_Pragma)
	<Pragma_Loop_Invariant>: Adjust to above renaming.
	<Loop_Variant>: Likewise.
	 <Pragma_Loop_Optimize>: Implement new pragma Loop_Optimize.
	(Sig_Flags): Add Pragma_Loop_Optimize.
	* gnat_rm.texi (Implementation Defined Pragmas): Add Loop_Optimize.
	* gnat_ugn.texi (Vectorization of loops): Mention Loop_Optimize.

Patch

Index: gnat_rm.texi
===================================================================
--- gnat_rm.texi	(revision 195794)
+++ gnat_rm.texi	(working copy)
@@ -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
Index: gnat_ugn.texi
===================================================================
--- gnat_ugn.texi	(revision 195798)
+++ gnat_ugn.texi	(working copy)
@@ -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
Index: par-prag.adb
===================================================================
--- par-prag.adb	(revision 195798)
+++ par-prag.adb	(working copy)
@@ -1203,6 +1203,7 @@ 
            Pragma_Locking_Policy                 |
            Pragma_Long_Float                     |
            Pragma_Loop_Invariant                 |
+           Pragma_Loop_Optimize                  |
            Pragma_Loop_Variant                   |
            Pragma_Machine_Attribute              |
            Pragma_Main                           |
Index: sem_prag.adb
===================================================================
--- sem_prag.adb	(revision 195798)
+++ sem_prag.adb	(working copy)
@@ -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,
Index: snames.ads-tmpl
===================================================================
--- snames.ads-tmpl	(revision 195798)
+++ snames.ads-tmpl	(working copy)
@@ -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,