aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/inline.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2016-04-27 13:01:35 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2016-04-27 13:01:35 +0200
commit2e885a6f7ce629d6517c2bf8dc14824be8e93987 (patch)
tree97c19940d80f087c3cbe29b3c4615f73aafba48f /gcc/ada/inline.adb
parent2a253c5bba9ecf4f09242253bf8efd05c9cce9de (diff)
downloadgcc-2e885a6f7ce629d6517c2bf8dc14824be8e93987.zip
gcc-2e885a6f7ce629d6517c2bf8dc14824be8e93987.tar.gz
gcc-2e885a6f7ce629d6517c2bf8dc14824be8e93987.tar.bz2
[multiple changes]
2016-04-27 Hristian Kirtchev <kirtchev@adacore.com> * aspects.ads Aspects Export and Import do not require delay. They were classified as delayed aspects, but treated as non-delayed by the analysis of aspects. * freeze.adb (Copy_Import_Pragma): New routine. (Wrap_Imported_Subprogram): Copy the import pragma by first resetting all semantic fields to avoid an infinite loop when performing the copy. * sem_ch13.adb (Analyze_Aspects_At_Freeze_Point): Add comment on the processing of aspects Export and Import at the freeze point. (Analyze_Aspect_Convention: New routine. (Analyze_Aspect_Export_Import): New routine. (Analyze_Aspect_External_Link_Name): New routine. (Analyze_Aspect_External_Or_Link_Name): Removed. (Analyze_Aspect_Specifications): Factor out the analysis of aspects Convention, Export, External_Name, Import, and Link_Name in their respective routines. Aspects Export and Import should not generate a Boolean pragma because their corresponding pragmas have a very different syntax. (Build_Export_Import_Pragma): New routine. (Get_Interfacing_Aspects): New routine. 2016-04-27 Eric Botcazou <ebotcazou@adacore.com> * inline.adb (Add_Inlined_Body): Overhaul implementation, robustify handling of -gnatn1, add special treatment for expression functions. 2016-04-27 Doug Rupp <rupp@adacore.com> * g-traceb.ads: Update comment. * exp_ch2.adb: minor style fix in object declaration From-SVN: r235483
Diffstat (limited to 'gcc/ada/inline.adb')
-rw-r--r--gcc/ada/inline.adb135
1 files changed, 70 insertions, 65 deletions
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index 7944604..4a04e11 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -390,6 +390,40 @@ package body Inline is
return;
end if;
+ -- Find out whether the call must be inlined. Unless the result is
+ -- Dont_Inline, Must_Inline also creates an edge for the call in the
+ -- callgraph; however, it will not be activated until after Is_Called
+ -- is set on the subprogram.
+
+ Level := Must_Inline;
+
+ if Level = Dont_Inline then
+ return;
+ end if;
+
+ -- If the call was generated by the compiler and is to a subprogram in
+ -- a run-time unit, we need to suppress debugging information for it,
+ -- so that the code that is eventually inlined will not affect the
+ -- debugging of the program. We do not do it if the call comes from
+ -- source because, even if the call is inlined, the user may expect it
+ -- to be present in the debugging information.
+
+ if not Comes_From_Source (N)
+ and then In_Extended_Main_Source_Unit (N)
+ and then
+ Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (E)))
+ then
+ Set_Needs_Debug_Info (E, False);
+ end if;
+
+ -- If the subprogram is an expression function, then there is no need to
+ -- load any package body since the body of the function is in the spec.
+
+ if Is_Expression_Function (E) then
+ Set_Is_Called (E);
+ return;
+ end if;
+
-- Find unit containing E, and add to list of inlined bodies if needed.
-- If the body is already present, no need to load any other unit. This
-- is the case for an initialization procedure, which appears in the
@@ -403,77 +437,48 @@ package body Inline is
-- no enclosing package to retrieve. In this case, it is the body of
-- the function that will have to be loaded.
- Level := Must_Inline;
-
- if Level /= Dont_Inline then
- declare
- Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
-
- begin
- -- Ensure that Analyze_Inlined_Bodies will be invoked after
- -- completing the analysis of the current unit.
+ declare
+ Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
- Inline_Processing_Required := True;
+ begin
+ if Pack = E then
+ Set_Is_Called (E);
+ Inlined_Bodies.Increment_Last;
+ Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
- if Pack = E then
+ elsif Ekind (Pack) = E_Package then
+ Set_Is_Called (E);
- -- Library-level inlined function. Add function itself to
- -- list of needed units.
+ if Is_Generic_Instance (Pack) then
+ null;
- Set_Is_Called (E);
+ -- Do not inline the package if the subprogram is an init proc
+ -- or other internally generated subprogram, because in that
+ -- case the subprogram body appears in the same unit that
+ -- declares the type, and that body is visible to the back end.
+ -- Do not inline it either if it is in the main unit.
+ -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
+ -- calls if the back-end takes care of inlining the call.
+
+ elsif (Level = Inline_Package
+ or else (Level = Inline_Call
+ and then Has_Pragma_Inline_Always (E)
+ and then Back_End_Inlining))
+ and then not Is_Inlined (Pack)
+ and then not Is_Internal (E)
+ and then not In_Main_Unit_Or_Subunit (Pack)
+ then
+ Set_Is_Inlined (Pack);
Inlined_Bodies.Increment_Last;
- Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
-
- elsif Ekind (Pack) = E_Package then
- Set_Is_Called (E);
-
- if Is_Generic_Instance (Pack) then
- null;
-
- -- Do not inline the package if the subprogram is an init proc
- -- or other internally generated subprogram, because in that
- -- case the subprogram body appears in the same unit that
- -- declares the type, and that body is visible to the back end.
- -- Do not inline it either if it is in the main unit.
-
- elsif Level = Inline_Package
- and then not Is_Inlined (Pack)
- and then not Is_Internal (E)
- and then not In_Main_Unit_Or_Subunit (Pack)
- then
- Set_Is_Inlined (Pack);
- Inlined_Bodies.Increment_Last;
- Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
-
- -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
- -- calls if the back-end takes care of inlining the call.
-
- elsif Level = Inline_Call
- and then Has_Pragma_Inline_Always (E)
- and then Back_End_Inlining
- then
- Set_Is_Inlined (Pack);
- Inlined_Bodies.Increment_Last;
- Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
- end if;
+ Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
end if;
+ end if;
- -- If the call was generated by the compiler and is to a function
- -- in a run-time unit, we need to suppress debugging information
- -- for it, so that the code that is eventually inlined will not
- -- affect debugging of the program. We do not do it if the call
- -- comes from source because, even if the call is inlined, the
- -- user may expect it to be present in the debugging information.
-
- if not Comes_From_Source (N)
- and then In_Extended_Main_Source_Unit (N)
- and then
- Is_Predefined_File_Name (Unit_File_Name (Get_Source_Unit (E)))
- then
- Set_Needs_Debug_Info (E, False);
- end if;
- end;
- end if;
+ -- Ensure that Analyze_Inlined_Bodies will be invoked after
+ -- completing the analysis of the current unit.
+
+ Inline_Processing_Required := True;
+ end;
end Add_Inlined_Body;
----------------------------