diff mbox

[Ada] Remove superfluous use of secondary stack on object initialization

Message ID 20160427123057.GA27717@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 27, 2016, 12:30 p.m. UTC
This patch improves on the performance of an object initialization with a
build-in-place function call, when the return type is not a definite type
but has only access discriminants and no controlled components.

THe following must execute quietly:

   gcc -c -gnatDG p.adb
   grep secondary_stack p.adb.dg


---
with Discrim; use Discrim;
procedure P is
  I : aliased Integer;
  A_Obj : A_Type := Create (I'Access);
begin
  null;
end;
---
package Discrim is
  type A_Type (IA : access Integer) is limited private;
  function Create (I : access Integer) return A_Type;
private
  type A_Type (IA : access Integer) is limited record
     Not_Dependent_On_IA : Boolean;
  end record;
end;
---
package body Discrim is
  function Create (I : access Integer) return A_Type is
  begin
     return A : A_Type (I) do
        A.Not_Dependent_On_IA := False;
     end return;
  end;
end;

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

2016-04-27  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch6.adb (Make_Build_In_Place_Call_In_Object_Declaration): If the
	return type is an untagged limited record with only access
	discriminants and no controlled components, the return value does not
	need to use the secondary stack.
diff mbox

Patch

Index: exp_ch6.adb
===================================================================
--- exp_ch6.adb	(revision 235482)
+++ exp_ch6.adb	(working copy)
@@ -7783,7 +7783,12 @@ 
       Result_Subt     : Entity_Id;
 
       Definite : Boolean;
-      --  True for definite function result subtype
+      --  True if result subtype is definite, or has a size that does not
+      --  require secondary stack usage (i.e. no variant part or components
+      --  whose type depends on discriminants). In particular, untagged types
+      --  with only access discriminants do not require secondary stack use.
+      --  Note that if the return type is tagged we must always use the sec.
+      --  stack because the call may dispatch on result.
 
    begin
       --  Step past qualification or unchecked conversion (the latter can occur
@@ -7818,7 +7823,10 @@ 
       end if;
 
       Result_Subt := Etype (Function_Id);
-      Definite    := Is_Definite_Subtype (Underlying_Type (Result_Subt));
+      Definite :=
+        (Is_Definite_Subtype (Underlying_Type (Result_Subt))
+             and then not Is_Tagged_Type (Result_Subt))
+          or else not Requires_Transient_Scope (Underlying_Type (Result_Subt));
 
       --  Create an access type designating the function's result subtype. We
       --  use the type of the original call because it may be a call to an