aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_ch6.adb
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2019-08-14 09:52:15 +0000
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>2019-08-14 09:52:15 +0000
commit4b96d3861e74b8df1032f4317230408248e4bf09 (patch)
treefbcdc10f2092f73da537788d02b6fc5d18e05425 /gcc/ada/exp_ch6.adb
parent72e324b6d8cb43b07eb3927f7d150b93105d1add (diff)
downloadgcc-4b96d3861e74b8df1032f4317230408248e4bf09.zip
gcc-4b96d3861e74b8df1032f4317230408248e4bf09.tar.gz
gcc-4b96d3861e74b8df1032f4317230408248e4bf09.tar.bz2
[Ada] Compiler speedup with inlining across units
This change is aimed at speeding up the inlining across units done by the Ada compiler when -gnatn is specified and in the presence of units instantiating a lot of generic packages. The current implementation is as follows: when a generic package is being instantiated, the compiler scans its spec for the presence of subprograms with an aspect/pragma Inline and, upon finding one, schedules the instantiation of its body. That's not very efficient because the compiler doesn't know yet if one of those inlined subprograms will eventually be called from the main unit. The new implementation arranges for the compiler to instantiate the body on demand, i.e. when it encounters a call to one of the inlined subprograms. That's still not optimal because, at this point, the compiler has not yet computed whether the call itself is reachable from the main unit (it will do this computation at the very end of the processing, just before sending the inlined units to the code generator) but that's nevertheless a net progress. The patch also enhances the -gnatd.j option to make it output the list of instances "inlined" this way. The following package is a simple example: with Q; procedure P is begin Q.Proc; end; package Q is procedure Proc; pragma Inline (Proc); end Q; with G; package body Q is package My_G is new G (1); procedure Proc is Val : constant Integer := My_G.Func; begin if Val /= 1 then raise Program_Error; end if; end; end Q; generic Value : Integer; package G is function Func return Integer; pragma Inline (Func); end G; package body G is function Func return Integer is begin return Value; end; end G; 2019-08-14 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * einfo.ads (Is_Called): Document new usage on E_Package entities. * einfo.adb (Is_Called): Accept E_Package entities. (Set_Is_Called): Likewise. * exp_ch6.adb (Expand_Call_Helper): Move code dealing with instances for back-end inlining to Add_Inlined_Body. * inline.ads: Remove with clauses for Alloc and Table. (Pending_Instantiations): Move to... * inline.adb: Add with clauses for Alloc, Uintp, Table and GNAT.HTable. (Backend_Instances): New variable. (Pending_Instantiations): ...here. (Called_Pending_Instantiations): New table. (Node_Table_Size): New constant. (Node_Header_Num): New subtype. (Node_Hash): New function. (To_Pending_Instantiations): New hash table. (Add_Inlined_Body): Bail out early for subprograms in the main unit or subunit. Likewise if the Is_Called flag is set. If the subprogram is an instance, invoke Add_Inlined_Instance. Call Set_Is_Called earlier. If the subrogram is within an instance, invoke Add_Inlined_Instance. Also deal with the case where the call itself is within an instance. (Add_Inlined_Instance): New procedure. (Add_Inlined_Subprogram): Remove conditions always fulfilled. (Add_Pending_Instantiation): Move the defence against ludicruous number of instantiations to here. When back-end inlining is enabled, associate an instantiation with its index in table and mark a few selected kinds of instantiations as always needed. (Initialize): Set Backend_Instances to No_Elist. (Instantiate_Body): New procedure doing the work extracted from... (Instantiate_Bodies): ...here. When back-end inlining is enabled, loop over Called_Pending_Instantiations instead of Pending_Instantiations. (Is_Nested): Minor tweak. (List_Inlining_Info): Also list the contents of Backend_Instances. * sem_ch12.adb (Might_Inline_Subp): Return early if Is_Inlined is set and otherwise set it before returning true. (Analyze_Package_Instantiation): Remove the defence against ludicruous number of instantiations. Invoke Remove_Dead_Instance instead of doing the removal manually if there is a guaranteed ABE. From-SVN: r274465
Diffstat (limited to 'gcc/ada/exp_ch6.adb')
-rw-r--r--gcc/ada/exp_ch6.adb56
1 files changed, 0 insertions, 56 deletions
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 128fb90..c182072 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -4443,62 +4443,6 @@ package body Exp_Ch6 is
or else Has_Pragma_Inline_Always (Subp)
then
Add_Inlined_Body (Subp, Call_Node);
-
- -- If the inlined call appears within an instance, then ensure
- -- that the enclosing instance body is available so the back end
- -- can actually perform the inlining.
-
- if In_Instance and then Comes_From_Source (Subp) then
- declare
- Decl : Node_Id;
- Inst : Entity_Id;
- Inst_Node : Node_Id;
-
- begin
- Inst := Scope (Subp);
-
- -- Find enclosing instance
-
- while Present (Inst) and then Inst /= Standard_Standard loop
- exit when Is_Generic_Instance (Inst);
- Inst := Scope (Inst);
- end loop;
-
- if Present (Inst)
- and then Is_Generic_Instance (Inst)
- and then not Is_Inlined (Inst)
- then
- Set_Is_Inlined (Inst);
- Decl := Unit_Declaration_Node (Inst);
-
- -- Do not add a pending instantiation if the body exits
- -- already, or if the instance is a compilation unit, or
- -- the instance node is missing.
-
- if Present (Corresponding_Body (Decl))
- or else Nkind (Parent (Decl)) = N_Compilation_Unit
- or else No (Next (Decl))
- then
- null;
-
- else
- -- The instantiation node usually follows the package
- -- declaration for the instance. If the generic unit
- -- has aspect specifications, they are transformed
- -- into pragmas in the instance, and the instance node
- -- appears after them.
-
- Inst_Node := Next (Decl);
-
- while Nkind (Inst_Node) /= N_Package_Instantiation loop
- Inst_Node := Next (Inst_Node);
- end loop;
-
- Add_Pending_Instantiation (Inst_Node, Decl);
- end if;
- end if;
- end;
- end if;
end if;
end if;