[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Tue, 12 Jun 2012 12:11:50 +0000 (14:11 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Tue, 12 Jun 2012 12:11:50 +0000 (14:11 +0200)
2012-06-12  Robert Dewar  <dewar@adacore.com>

* sem_ch12.adb: Minor reformatting.

2012-06-12  Eric Botcazou  <ebotcazou@adacore.com>

* opt.ads (Inline_Level): New variable.
* gnat1drv.adb (Adjust_Global_Switches): Set it based on optimization
level if it has not been set by the user.
* switch-c.adb (Scan_Front_End_Switches): Accept -gnatn1 and -gnatn2
and set Inline_Level accordingly.
* inline.adb (Add_Inlined_Body): Declate new Inline_Level_Type type.
(Must_Inline): Return Inline_Level_T instead of Boolean to indicate
whether the package of the inlined subprogram must be compiled.
If Inline_Level is set to 1, only compile packages of subprograms
directly called from the main unit.
* usage.adb (Usage): Adjust line for -gnatn switch.
* gnat_ugn.texi (Switches for gcc): Document -gnatn1 and -gnatn2.

From-SVN: r188451

gcc/ada/ChangeLog
gcc/ada/gnat1drv.adb
gcc/ada/gnat_ugn.texi
gcc/ada/inline.adb
gcc/ada/opt.ads
gcc/ada/sem_ch12.adb
gcc/ada/switch-c.adb
gcc/ada/usage.adb

index b4a3477..b8b8cd9 100644 (file)
@@ -1,3 +1,22 @@
+2012-06-12  Robert Dewar  <dewar@adacore.com>
+
+       * sem_ch12.adb: Minor reformatting.
+
+2012-06-12  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * opt.ads (Inline_Level): New variable.
+       * gnat1drv.adb (Adjust_Global_Switches): Set it based on optimization
+       level if it has not been set by the user.
+       * switch-c.adb (Scan_Front_End_Switches): Accept -gnatn1 and -gnatn2
+       and set Inline_Level accordingly.
+       * inline.adb (Add_Inlined_Body): Declate new Inline_Level_Type type.
+       (Must_Inline): Return Inline_Level_T instead of Boolean to indicate
+       whether the package of the inlined subprogram must be compiled.
+       If Inline_Level is set to 1, only compile packages of subprograms
+       directly called from the main unit.
+       * usage.adb (Usage): Adjust line for -gnatn switch.
+       * gnat_ugn.texi (Switches for gcc): Document -gnatn1 and -gnatn2.
+
 2012-06-12  Ed Schonberg  <schonberg@adacore.com>
 
        * sem_ch12.adb (Instantiate_Formal_Subprogram): Do not apply
index 57aacca..2416717 100644 (file)
@@ -505,6 +505,17 @@ procedure Gnat1drv is
 
          Tagged_Type_Expansion := False;
       end if;
+
+      --  If the inlining level has not been set by the user, compute it from
+      --  the optimization level: 1 at -O1/-O2 (and -Os), 2 at -O3 and above.
+
+      if Inline_Level = 0 then
+         if Optimization_Level < 3 then
+            Inline_Level := 1;
+         else
+            Inline_Level := 2;
+         end if;
+      end if;
    end Adjust_Global_Switches;
 
    --------------------
index 3f02f75..f444cf9 100644 (file)
@@ -4302,11 +4302,15 @@ reaches this limit, then a message is output and the compilation
 is abandoned. The equal sign here is optional. A value of zero
 means that no limit applies.
 
-@item -gnatn
+@item -gnatn[12]
 @cindex @option{-gnatn} (@command{gcc})
-Activate inlining for subprograms for which
-pragma @code{Inline} is specified. This inlining is performed
-by the GCC back-end.
+Activate inlining for subprograms for which pragma @code{Inline} is
+specified. This inlining is performed by the GCC back-end. An optional
+digit sets the inlining level: 1 for moderate inlining across modules,
+which is a good compromise between compilation times and performances
+at run time, and 2 for full inlining across modules, which may bring
+about longer compilation times. If no inlining level is specified,
+the compiler will pick it based on the optimization level.
 
 @item -gnatN
 @cindex @option{-gnatN} (@command{gcc})
index 2fa6054..01f8ff1 100644 (file)
@@ -229,7 +229,13 @@ package body Inline is
 
    procedure Add_Inlined_Body (E : Entity_Id) is
 
-      function Must_Inline return Boolean;
+      type Inline_Level_Type is (Dont_Inline, Inline_Call, Inline_Package);
+      --  Level of inlining for the call: Dont_Inline means no inlining,
+      --  Inline_Call means that only the call is considered for inlining,
+      --  Inline_Package means that the call is considered for inlining and
+      --  its package compiled and scanned for more inlining opportunities.
+
+      function Must_Inline return Inline_Level_Type;
       --  Inlining is only done if the call statement N is in the main unit,
       --  or within the body of another inlined subprogram.
 
@@ -237,7 +243,7 @@ package body Inline is
       -- Must_Inline --
       -----------------
 
-      function Must_Inline return Boolean is
+      function Must_Inline return Inline_Level_Type is
          Scop : Entity_Id;
          Comp : Node_Id;
 
@@ -251,7 +257,7 @@ package body Inline is
          --  trouble to try to inline at this level.
 
          if Scop = Standard_Standard then
-            return False;
+            return Dont_Inline;
          end if;
 
          --  Otherwise lookup scope stack to outer scope
@@ -267,14 +273,19 @@ package body Inline is
             Comp := Parent (Comp);
          end loop;
 
+         --  If the call is in the main unit, inline the call and compile the
+         --  package of the subprogram to find more calls to be inlined.
+
          if Comp = Cunit (Main_Unit)
            or else Comp = Library_Unit (Cunit (Main_Unit))
          then
             Add_Call (E);
-            return True;
+            return Inline_Package;
          end if;
 
-         --  Call is not in main unit. See if it's in some inlined subprogram
+         --  The call is not in the main unit. See if it is in some inlined
+         --  subprogram. If so, inline the call and, if the inlining level is
+         --  set to 1, stop there; otherwise also compile the package as above.
 
          Scop := Current_Scope;
          while Scope (Scop) /= Standard_Standard
@@ -284,15 +295,21 @@ package body Inline is
               and then Is_Inlined (Scop)
             then
                Add_Call (E, Scop);
-               return True;
+               if Inline_Level = 1 then
+                  return Inline_Call;
+               else
+                  return Inline_Package;
+               end if;
             end if;
 
             Scop := Scope (Scop);
          end loop;
 
-         return False;
+         return Dont_Inline;
       end Must_Inline;
 
+      Level : Inline_Level_Type;
+
    --  Start of processing for Add_Inlined_Body
 
    begin
@@ -309,11 +326,15 @@ package body Inline is
       --  no enclosing package to retrieve. In this case, it is the body of
       --  the function that will have to be loaded.
 
-      if not Is_Abstract_Subprogram (E)
-        and then not Is_Nested (E)
-        and then Convention (E) /= Convention_Protected
-        and then Must_Inline
+      if Is_Abstract_Subprogram (E)
+        or else Is_Nested (E)
+        or else Convention (E) = Convention_Protected
       then
+         return;
+      end if;
+
+      Level := Must_Inline;
+      if Level /= Dont_Inline then
          declare
             Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
 
@@ -339,7 +360,8 @@ package body Inline is
                --  declares the type, and that body is visible to the back end.
                --  Do not inline it either if it is in the main unit.
 
-               elsif not Is_Inlined (Pack)
+               elsif Level = Inline_Package
+                 and then not Is_Inlined (Pack)
                  and then Comes_From_Source (E)
                  and then not In_Main_Unit_Or_Subunit (Pack)
                then
index e59e67e..a44d338 100644 (file)
@@ -733,6 +733,12 @@ package Opt is
    --  Set True to activate pragma Inline processing across modules. Default
    --  for now is not to inline across module boundaries.
 
+   Inline_Level : Nat := 0;
+   --  GNAT
+   --  Set to indicate the inlining level: 0 means that an appropriate value
+   --  is to be computed by the compiler, 1 is for moderate inlining across
+   --  modules and 2 for full inlining across modules.
+
    Interface_Library_Unit : Boolean := False;
    --  GNATBIND
    --  Set to True to indicate that at least one ALI file is an interface ALI:
index fb9a451..48a4974 100644 (file)
@@ -9449,6 +9449,8 @@ package body Sem_Ch12 is
                Has_Untagged_Inc := True;
             end if;
 
+            --  Add comments for following code???
+
             if Is_Entity_Name (Actual)
               and then not Is_Overloaded (Actual)
               and then not Has_Untagged_Inc
index 7cb0ee0..cc72473 100644 (file)
@@ -732,6 +732,16 @@ package body Switch.C is
                Ptr := Ptr + 1;
                Inline_Active := True;
 
+               --  There may be a digit appended to the switch
+
+               if Ptr <= Max then
+                  C := Switch_Chars (Ptr);
+                  if C = '1' or C = '2' then
+                     Ptr := Ptr + 1;
+                     Inline_Level := Character'Pos (C) - Character'Pos ('0');
+                  end if;
+               end if;
+
             --  Processing for N switch
 
             when 'N' =>
index 637097b..292d681 100644 (file)
@@ -298,7 +298,7 @@ begin
 
    --  Line for -gnatn switch
 
-   Write_Switch_Char ("n");
+   Write_Switch_Char ("n[d]");
    Write_Line ("Enable pragma Inline (both within and across units)");
 
    --  Line for -gnatN switch