[Ada] Code cleanup on functions inlining
authorJavier Miranda <miranda@adacore.com>
Mon, 16 Jul 2018 14:10:32 +0000 (14:10 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Mon, 16 Jul 2018 14:10:32 +0000 (14:10 +0000)
This patch is preventive: it improves checks on inline functions that
return unconstrained type. It does not change the functionality of
the compiler.

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).

From-SVN: r262708

gcc/ada/ChangeLog
gcc/ada/inline.adb

index bff06e6be436213eff682bb4689b9d6b729fe2f2..163118f502731998241c237fd7bd5f38c11f2849 100644 (file)
@@ -1,3 +1,11 @@
+2018-07-16  Javier Miranda  <miranda@adacore.com>
+
+       * 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).
+
 2018-07-16  Javier Miranda  <miranda@adacore.com>
 
        * exp_ch5.adb (Expand_Iterator_Loop_Over_Array): Code cleanup. Required
index bc01ffc58ceaecbfbeec3cc868c0f33b42021afe..df7fdb9e893f7e5a80fc083e63a9f5aa2eb35d30 100644 (file)
@@ -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;