===================================================================
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
+-- 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 @@
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 @@
-- no enclosing package to retrieve. In this case, it is the body of
-- the function that will have to be loaded.
- Level := Must_Inline;
+ declare
+ Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
- if Level /= Dont_Inline then
- declare
- Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
+ begin
+ if Pack = E then
+ Set_Is_Called (E);
+ Inlined_Bodies.Increment_Last;
+ Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
- begin
- -- Ensure that Analyze_Inlined_Bodies will be invoked after
- -- completing the analysis of the current unit.
+ elsif Ekind (Pack) = E_Package then
+ Set_Is_Called (E);
- Inline_Processing_Required := True;
+ if Is_Generic_Instance (Pack) then
+ null;
- if Pack = E then
+ -- 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.
- -- Library-level inlined function. Add function itself to
- -- list of needed units.
-
- Set_Is_Called (E);
+ 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.
+ -- Ensure that Analyze_Inlined_Bodies will be invoked after
+ -- completing the analysis of the current unit.
- 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;
+ Inline_Processing_Required := True;
+ end;
end Add_Inlined_Body;
----------------------------