This patch changes the implementation of controlled types so that in simple
cases, they are just as efficient as noncontrolled types where initialization
and cleanup is done by hand.

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

2015-05-27  Bob Duff  <d...@adacore.com>

        * exp_ch3.adb (Build_Array_Init_Proc, Build_Record_Init_Proc):
        Inline init_procs when the type has controlled parts. Remove
        obsolete comments about those init_procs -- init_procs for
        such types are no longer complex. A typical init_proc just
        initializes the 'Tag field, and calls the parent init_proc
        (e.g. for Limited_Controlled), which calls the grandparent
        (for Root_Controlled), which does nothing. This all boils down
        to one instruction when inlined.
        * exp_ch7.adb (Create_Finalizer): Inline the finalizer.

Index: exp_ch7.adb
===================================================================
--- exp_ch7.adb (revision 223752)
+++ exp_ch7.adb (working copy)
@@ -1440,6 +1440,13 @@
             --  resides, there is no need for elaboration checks.
 
             Set_Kill_Elaboration_Checks (Fin_Id);
+
+            --  Inlining the finalizer produces a substantial speedup at -O2.
+            --  It is inlined by default at -O3. Either way, it is called
+            --  exactly twice (once on the normal path, and once for
+            --  exceptions/abort), so this won't bloat the code too much.
+
+            Set_Is_Inlined  (Fin_Id);
          end if;
 
          --  Step 2: Creation of the finalizer specification
Index: exp_ch3.adb
===================================================================
--- exp_ch3.adb (revision 223754)
+++ exp_ch3.adb (working copy)
@@ -311,7 +311,7 @@
    --  Predefined_Primitive_Bodies.
 
    function Has_New_Non_Standard_Rep (T : Entity_Id) return Boolean;
-   --  returns True if there are representation clauses for type T that are not
+   --  Returns True if there are representation clauses for type T that are not
    --  inherited. If the result is false, the init_proc and the discriminant
    --  checking functions of the parent can be reused by a derived type.
 
@@ -761,14 +761,12 @@
             Set_Debug_Info_Off (Proc_Id);
          end if;
 
-         --  Set inlined unless controlled stuff or tasks around, in which
-         --  case we do not want to inline, because nested stuff may cause
-         --  difficulties in inter-unit inlining, and furthermore there is
-         --  in any case no point in inlining such complex init procs.
+         --  Set inlined unless tasks are around, in which case we do not
+         --  want to inline, because nested stuff may cause difficulties in
+         --  inter-unit inlining, and furthermore there is in any case no
+         --  point in inlining such complex init procs.
 
-         if not Has_Task (Proc_Id)
-           and then not Needs_Finalization (Proc_Id)
-         then
+         if not Has_Task (Proc_Id) then
             Set_Is_Inlined (Proc_Id);
          end if;
 
@@ -3619,14 +3617,10 @@
          --  The initialization of protected records is not worth inlining.
          --  In addition, when compiled for another unit for inlining purposes,
          --  it may make reference to entities that have not been elaborated
-         --  yet. The initialization of controlled records contains a nested
-         --  clean-up procedure that makes it impractical to inline as well,
-         --  and leads to undefined symbols if inlined in a different unit.
-         --  Similar considerations apply to task types.
+         --  yet. Similar considerations apply to task types.
 
          if not Is_Concurrent_Type (Rec_Type)
            and then not Has_Task (Rec_Type)
-           and then not Needs_Finalization (Rec_Type)
          then
             Set_Is_Inlined  (Proc_Id);
          end if;

Reply via email to