The first adjustment ensures that the compiler doesn't inline back into the
main unit subprograms coming from subunits, since they are already compiled.
The second adjustment ensures that the transitive closure algorithm keeps
excluding the subprograms not handled by Add_Inlined_Body.

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

2012-05-15  Eric Botcazou  <ebotca...@adacore.com>

        * inline.adb (Scope_In_Main_Unit): Rename into...
        (In_Main_Unit_Or_Subunit): ...this.  Also return
        true if the subprogram is within a subunit of the
        main unit.
        (Add_Inlined_Body): Adjust for above renaming.
        (Add_Inlined_Subprogram): Likewise.  Pass the subprogram directly.
        (Analyze_Inlined_Bodies): Really set aside inlined subprograms
        not handled by Add_Inlined_Body.

Index: inline.adb
===================================================================
--- inline.adb  (revision 187526)
+++ inline.adb  (working copy)
@@ -138,8 +138,8 @@
    --  Return the entity node for the unit containing E. Always return
    --  the spec for a package.
 
-   function Scope_In_Main_Unit (Scop : Entity_Id) return Boolean;
-   --  Return True if Scop is in the main unit or its spec
+   function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean;
+   --  Return True if E is in the main unit or its spec or in a subunit
 
    procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty);
    --  Make two entries in Inlined table, for an inlined subprogram being
@@ -341,7 +341,7 @@
 
                elsif not Is_Inlined (Pack)
                  and then Comes_From_Source (E)
-                 and then not Scope_In_Main_Unit (Pack)
+                 and then not In_Main_Unit_Or_Subunit (Pack)
                then
                   Set_Is_Inlined (Pack);
                   Inlined_Bodies.Increment_Last;
@@ -433,7 +433,7 @@
         and then (Is_Inlined (Pack)
                     or else Is_Generic_Instance (Pack)
                     or else Is_Internal (E))
-        and then not Scope_In_Main_Unit (Pack)
+        and then not In_Main_Unit_Or_Subunit (E)
         and then not Is_Nested (E)
         and then not Has_Initialized_Type (E)
       then
@@ -746,7 +746,7 @@
                --  This means that Add_Inlined_Body added the subprogram to the
                --  table but wasn't able to handle its code unit. Do nothing.
 
-               null;
+               Inlined.Table (Index).Processed := True;
             elsif Inlined.Table (Index).Main_Call then
                Pending_Inlined.Increment_Last;
                Pending_Inlined.Table (Pending_Inlined.Last) := Index;
@@ -767,9 +767,9 @@
 
             while S /= No_Succ loop
                Subp := Successors.Table (S).Subp;
-               Set_Is_Called (Inlined.Table (Subp).Name);
 
                if not Inlined.Table (Subp).Processed then
+                  Set_Is_Called (Inlined.Table (Subp).Name);
                   Pending_Inlined.Increment_Last;
                   Pending_Inlined.Table (Pending_Inlined.Last) := Subp;
                   Inlined.Table (Subp).Processed := True;
@@ -1156,23 +1156,27 @@
       end loop;
    end Remove_Dead_Instance;
 
-   ------------------------
-   -- Scope_In_Main_Unit --
-   ------------------------
+   -----------------------------
+   -- In_Main_Unit_Or_Subunit --
+   -----------------------------
 
-   function Scope_In_Main_Unit (Scop : Entity_Id) return Boolean is
-      Comp : constant Node_Id := Cunit (Get_Code_Unit (Scop));
+   function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean is
+      Comp : Node_Id := Cunit (Get_Code_Unit (E));
 
    begin
-      --  Check whether the scope of the subprogram to inline is within the
-      --  main unit or within its spec. In either case there are no additional
-      --  bodies to process. If the subprogram appears in a parent of the
-      --  current unit, the check on whether inlining is possible is done in
-      --  Analyze_Inlined_Bodies.
+      --  Check whether the subprogram or package to inline is within the main
+      --  unit or its spec or within a subunit. In either case there are no
+      --  additional bodies to process. If the subprogram appears in a parent
+      --  of the current unit, the check on whether inlining is possible is
+      --  done in Analyze_Inlined_Bodies.
 
+      while Nkind (Unit (Comp)) = N_Subunit loop
+         Comp := Library_Unit (Comp);
+      end loop;
+
       return
         Comp = Cunit (Main_Unit)
           or else Comp = Library_Unit (Cunit (Main_Unit));
-   end Scope_In_Main_Unit;
+   end In_Main_Unit_Or_Subunit;
 
 end Inline;

Reply via email to