[Ada] Code cleanup on functions inlining

Message ID 20180716141348.GA59564@adacore.com
State New
Headers show
Series
  • [Ada] Code cleanup on functions inlining
Related show

Commit Message

Pierre-Marie de Rodat July 16, 2018, 2:13 p.m.
This patch is preventive: it improves checks on inline functions that
return unconstrained type. It does not change the functionality of
the compiler.

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

2018-07-16  Javier Miranda  <miranda@adacore.com>

gcc/ada/

	* inline.adb (Build_Body_To_Inline): Minor code reorganization that
	ensures that calls to function Has_Single_Return() pass a decorated
	tree.
	(Has_Single_Return.Check_Return): Peform checks on entities (instead on
	relying on their characters).

Patch

--- gcc/ada/inline.adb
+++ gcc/ada/inline.adb
@@ -1085,33 +1085,9 @@  package body Inline is
          Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
          return;
 
-      --  Functions that return unconstrained composite types require
-      --  secondary stack handling, and cannot currently be inlined, unless
-      --  all return statements return a local variable that is the first
-      --  local declaration in the body.
-
-      elsif Ekind (Spec_Id) = E_Function
-        and then not Is_Scalar_Type (Etype (Spec_Id))
-        and then not Is_Access_Type (Etype (Spec_Id))
-        and then not Is_Constrained (Etype (Spec_Id))
-      then
-         if not Has_Single_Return (N)
-
-           --  Skip inlining if the function returns an unconstrained type
-           --  using an extended return statement, since this part of the
-           --  new inlining model is not yet supported by the current
-           --  implementation. ???
-
-           or else (Returns_Unconstrained_Type (Spec_Id)
-                     and then Has_Extended_Return)
-         then
-            Cannot_Inline
-              ("cannot inline & (unconstrained return type)?", N, Spec_Id);
-            return;
-         end if;
-
-      --  Ditto for functions that return controlled types, where controlled
-      --  actions interfere in complex ways with inlining.
+      --  Functions that return controlled types cannot currently be inlined
+      --  because they require secondary stack handling; controlled actions
+      --  may also interfere in complex ways with inlining.
 
       elsif Ekind (Spec_Id) = E_Function
         and then Needs_Finalization (Etype (Spec_Id))
@@ -1234,10 +1210,37 @@  package body Inline is
          Restore_Env;
       end if;
 
+      --  Functions that return unconstrained composite types require
+      --  secondary stack handling, and cannot currently be inlined, unless
+      --  all return statements return a local variable that is the first
+      --  local declaration in the body. We had to delay this check until
+      --  the body of the function is analyzed since Has_Single_Return()
+      --  requires a minimum decoration.
+
+      if Ekind (Spec_Id) = E_Function
+        and then not Is_Scalar_Type (Etype (Spec_Id))
+        and then not Is_Access_Type (Etype (Spec_Id))
+        and then not Is_Constrained (Etype (Spec_Id))
+      then
+         if not Has_Single_Return (Body_To_Analyze)
+
+           --  Skip inlining if the function returns an unconstrained type
+           --  using an extended return statement, since this part of the
+           --  new inlining model is not yet supported by the current
+           --  implementation. ???
+
+           or else (Returns_Unconstrained_Type (Spec_Id)
+                     and then Has_Extended_Return)
+         then
+            Cannot_Inline
+              ("cannot inline & (unconstrained return type)?", N, Spec_Id);
+            return;
+         end if;
+
       --  If secondary stack is used, there is no point in inlining. We have
       --  already issued the warning in this case, so nothing to do.
 
-      if Uses_Secondary_Stack (Body_To_Analyze) then
+      elsif Uses_Secondary_Stack (Body_To_Analyze) then
          return;
       end if;
 
@@ -3904,17 +3907,23 @@  package body Inline is
             if Present (Expression (N))
               and then Is_Entity_Name (Expression (N))
             then
+               pragma Assert (Present (Entity (Expression (N))));
+
                if No (Return_Statement) then
                   Return_Statement := N;
                   return OK;
 
-               elsif Chars (Expression (N)) =
-                     Chars (Expression (Return_Statement))
-               then
-                  return OK;
-
                else
-                  return Abandon;
+                  pragma Assert
+                    (Present (Entity (Expression (Return_Statement))));
+
+                  if Entity (Expression (N)) =
+                       Entity (Expression (Return_Statement))
+                  then
+                     return OK;
+                  else
+                     return Abandon;
+                  end if;
                end if;
 
             --  A return statement within an extended return is a noop
@@ -3963,8 +3972,8 @@  package body Inline is
       else
          return Present (Declarations (N))
            and then Present (First (Declarations (N)))
-           and then Chars (Expression (Return_Statement)) =
-                    Chars (Defining_Identifier (First (Declarations (N))));
+           and then Entity (Expression (Return_Statement)) =
+                    Defining_Identifier (First (Declarations (N)));
       end if;
    end Has_Single_Return;