comparison gcc/ada/inline.adb @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- I N L I N E --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2017, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Aspects; use Aspects;
27 with Atree; use Atree;
28 with Debug; use Debug;
29 with Einfo; use Einfo;
30 with Elists; use Elists;
31 with Errout; use Errout;
32 with Expander; use Expander;
33 with Exp_Ch6; use Exp_Ch6;
34 with Exp_Ch7; use Exp_Ch7;
35 with Exp_Tss; use Exp_Tss;
36 with Exp_Util; use Exp_Util;
37 with Fname; use Fname;
38 with Fname.UF; use Fname.UF;
39 with Lib; use Lib;
40 with Namet; use Namet;
41 with Nmake; use Nmake;
42 with Nlists; use Nlists;
43 with Output; use Output;
44 with Sem_Aux; use Sem_Aux;
45 with Sem_Ch8; use Sem_Ch8;
46 with Sem_Ch10; use Sem_Ch10;
47 with Sem_Ch12; use Sem_Ch12;
48 with Sem_Prag; use Sem_Prag;
49 with Sem_Util; use Sem_Util;
50 with Sinfo; use Sinfo;
51 with Sinput; use Sinput;
52 with Snames; use Snames;
53 with Stand; use Stand;
54 with Uname; use Uname;
55 with Tbuild; use Tbuild;
56
57 package body Inline is
58
59 Check_Inlining_Restrictions : constant Boolean := True;
60 -- In the following cases the frontend rejects inlining because they
61 -- are not handled well by the backend. This variable facilitates
62 -- disabling these restrictions to evaluate future versions of the
63 -- GCC backend in which some of the restrictions may be supported.
64 --
65 -- - subprograms that have:
66 -- - nested subprograms
67 -- - instantiations
68 -- - package declarations
69 -- - task or protected object declarations
70 -- - some of the following statements:
71 -- - abort
72 -- - asynchronous-select
73 -- - conditional-entry-call
74 -- - delay-relative
75 -- - delay-until
76 -- - selective-accept
77 -- - timed-entry-call
78
79 Inlined_Calls : Elist_Id;
80 -- List of frontend inlined calls
81
82 Backend_Calls : Elist_Id;
83 -- List of inline calls passed to the backend
84
85 Backend_Inlined_Subps : Elist_Id;
86 -- List of subprograms inlined by the backend
87
88 Backend_Not_Inlined_Subps : Elist_Id;
89 -- List of subprograms that cannot be inlined by the backend
90
91 --------------------
92 -- Inlined Bodies --
93 --------------------
94
95 -- Inlined functions are actually placed in line by the backend if the
96 -- corresponding bodies are available (i.e. compiled). Whenever we find
97 -- a call to an inlined subprogram, we add the name of the enclosing
98 -- compilation unit to a worklist. After all compilation, and after
99 -- expansion of generic bodies, we traverse the list of pending bodies
100 -- and compile them as well.
101
102 package Inlined_Bodies is new Table.Table (
103 Table_Component_Type => Entity_Id,
104 Table_Index_Type => Int,
105 Table_Low_Bound => 0,
106 Table_Initial => Alloc.Inlined_Bodies_Initial,
107 Table_Increment => Alloc.Inlined_Bodies_Increment,
108 Table_Name => "Inlined_Bodies");
109
110 -----------------------
111 -- Inline Processing --
112 -----------------------
113
114 -- For each call to an inlined subprogram, we make entries in a table
115 -- that stores caller and callee, and indicates the call direction from
116 -- one to the other. We also record the compilation unit that contains
117 -- the callee. After analyzing the bodies of all such compilation units,
118 -- we compute the transitive closure of inlined subprograms called from
119 -- the main compilation unit and make it available to the code generator
120 -- in no particular order, thus allowing cycles in the call graph.
121
122 Last_Inlined : Entity_Id := Empty;
123
124 -- For each entry in the table we keep a list of successors in topological
125 -- order, i.e. callers of the current subprogram.
126
127 type Subp_Index is new Nat;
128 No_Subp : constant Subp_Index := 0;
129
130 -- The subprogram entities are hashed into the Inlined table
131
132 Num_Hash_Headers : constant := 512;
133
134 Hash_Headers : array (Subp_Index range 0 .. Num_Hash_Headers - 1)
135 of Subp_Index;
136
137 type Succ_Index is new Nat;
138 No_Succ : constant Succ_Index := 0;
139
140 type Succ_Info is record
141 Subp : Subp_Index;
142 Next : Succ_Index;
143 end record;
144
145 -- The following table stores list elements for the successor lists. These
146 -- lists cannot be chained directly through entries in the Inlined table,
147 -- because a given subprogram can appear in several such lists.
148
149 package Successors is new Table.Table (
150 Table_Component_Type => Succ_Info,
151 Table_Index_Type => Succ_Index,
152 Table_Low_Bound => 1,
153 Table_Initial => Alloc.Successors_Initial,
154 Table_Increment => Alloc.Successors_Increment,
155 Table_Name => "Successors");
156
157 type Subp_Info is record
158 Name : Entity_Id := Empty;
159 Next : Subp_Index := No_Subp;
160 First_Succ : Succ_Index := No_Succ;
161 Main_Call : Boolean := False;
162 Processed : Boolean := False;
163 end record;
164
165 package Inlined is new Table.Table (
166 Table_Component_Type => Subp_Info,
167 Table_Index_Type => Subp_Index,
168 Table_Low_Bound => 1,
169 Table_Initial => Alloc.Inlined_Initial,
170 Table_Increment => Alloc.Inlined_Increment,
171 Table_Name => "Inlined");
172
173 -----------------------
174 -- Local Subprograms --
175 -----------------------
176
177 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty);
178 -- Make two entries in Inlined table, for an inlined subprogram being
179 -- called, and for the inlined subprogram that contains the call. If
180 -- the call is in the main compilation unit, Caller is Empty.
181
182 procedure Add_Inlined_Subprogram (E : Entity_Id);
183 -- Add subprogram E to the list of inlined subprogram for the unit
184
185 function Add_Subp (E : Entity_Id) return Subp_Index;
186 -- Make entry in Inlined table for subprogram E, or return table index
187 -- that already holds E.
188
189 function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id;
190 pragma Inline (Get_Code_Unit_Entity);
191 -- Return the entity node for the unit containing E. Always return the spec
192 -- for a package.
193
194 function Has_Initialized_Type (E : Entity_Id) return Boolean;
195 -- If a candidate for inlining contains type declarations for types with
196 -- nontrivial initialization procedures, they are not worth inlining.
197
198 function Has_Single_Return (N : Node_Id) return Boolean;
199 -- In general we cannot inline functions that return unconstrained type.
200 -- However, we can handle such functions if all return statements return a
201 -- local variable that is the only declaration in the body of the function.
202 -- In that case the call can be replaced by that local variable as is done
203 -- for other inlined calls.
204
205 function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean;
206 -- Return True if E is in the main unit or its spec or in a subunit
207
208 function Is_Nested (E : Entity_Id) return Boolean;
209 -- If the function is nested inside some other function, it will always
210 -- be compiled if that function is, so don't add it to the inline list.
211 -- We cannot compile a nested function outside the scope of the containing
212 -- function anyway. This is also the case if the function is defined in a
213 -- task body or within an entry (for example, an initialization procedure).
214
215 procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id);
216 -- Remove all aspects and/or pragmas that have no meaning in inlined body
217 -- Body_Decl. The analysis of these items is performed on the non-inlined
218 -- body. The items currently removed are:
219 -- Contract_Cases
220 -- Global
221 -- Depends
222 -- Postcondition
223 -- Precondition
224 -- Refined_Global
225 -- Refined_Depends
226 -- Refined_Post
227 -- Test_Case
228 -- Unmodified
229 -- Unreferenced
230
231 ------------------------------
232 -- Deferred Cleanup Actions --
233 ------------------------------
234
235 -- The cleanup actions for scopes that contain instantiations is delayed
236 -- until after expansion of those instantiations, because they may contain
237 -- finalizable objects or tasks that affect the cleanup code. A scope
238 -- that contains instantiations only needs to be finalized once, even
239 -- if it contains more than one instance. We keep a list of scopes
240 -- that must still be finalized, and call cleanup_actions after all
241 -- the instantiations have been completed.
242
243 To_Clean : Elist_Id;
244
245 procedure Add_Scope_To_Clean (Inst : Entity_Id);
246 -- Build set of scopes on which cleanup actions must be performed
247
248 procedure Cleanup_Scopes;
249 -- Complete cleanup actions on scopes that need it
250
251 --------------
252 -- Add_Call --
253 --------------
254
255 procedure Add_Call (Called : Entity_Id; Caller : Entity_Id := Empty) is
256 P1 : constant Subp_Index := Add_Subp (Called);
257 P2 : Subp_Index;
258 J : Succ_Index;
259
260 begin
261 if Present (Caller) then
262 P2 := Add_Subp (Caller);
263
264 -- Add P1 to the list of successors of P2, if not already there.
265 -- Note that P2 may contain more than one call to P1, and only
266 -- one needs to be recorded.
267
268 J := Inlined.Table (P2).First_Succ;
269 while J /= No_Succ loop
270 if Successors.Table (J).Subp = P1 then
271 return;
272 end if;
273
274 J := Successors.Table (J).Next;
275 end loop;
276
277 -- On exit, make a successor entry for P1
278
279 Successors.Increment_Last;
280 Successors.Table (Successors.Last).Subp := P1;
281 Successors.Table (Successors.Last).Next :=
282 Inlined.Table (P2).First_Succ;
283 Inlined.Table (P2).First_Succ := Successors.Last;
284 else
285 Inlined.Table (P1).Main_Call := True;
286 end if;
287 end Add_Call;
288
289 ----------------------
290 -- Add_Inlined_Body --
291 ----------------------
292
293 procedure Add_Inlined_Body (E : Entity_Id; N : Node_Id) is
294
295 type Inline_Level_Type is (Dont_Inline, Inline_Call, Inline_Package);
296 -- Level of inlining for the call: Dont_Inline means no inlining,
297 -- Inline_Call means that only the call is considered for inlining,
298 -- Inline_Package means that the call is considered for inlining and
299 -- its package compiled and scanned for more inlining opportunities.
300
301 function Must_Inline return Inline_Level_Type;
302 -- Inlining is only done if the call statement N is in the main unit,
303 -- or within the body of another inlined subprogram.
304
305 -----------------
306 -- Must_Inline --
307 -----------------
308
309 function Must_Inline return Inline_Level_Type is
310 Scop : Entity_Id;
311 Comp : Node_Id;
312
313 begin
314 -- Check if call is in main unit
315
316 Scop := Current_Scope;
317
318 -- Do not try to inline if scope is standard. This could happen, for
319 -- example, for a call to Add_Global_Declaration, and it causes
320 -- trouble to try to inline at this level.
321
322 if Scop = Standard_Standard then
323 return Dont_Inline;
324 end if;
325
326 -- Otherwise lookup scope stack to outer scope
327
328 while Scope (Scop) /= Standard_Standard
329 and then not Is_Child_Unit (Scop)
330 loop
331 Scop := Scope (Scop);
332 end loop;
333
334 Comp := Parent (Scop);
335 while Nkind (Comp) /= N_Compilation_Unit loop
336 Comp := Parent (Comp);
337 end loop;
338
339 -- If the call is in the main unit, inline the call and compile the
340 -- package of the subprogram to find more calls to be inlined.
341
342 if Comp = Cunit (Main_Unit)
343 or else Comp = Library_Unit (Cunit (Main_Unit))
344 then
345 Add_Call (E);
346 return Inline_Package;
347 end if;
348
349 -- The call is not in the main unit. See if it is in some subprogram
350 -- that can be inlined outside its unit. If so, inline the call and,
351 -- if the inlining level is set to 1, stop there; otherwise also
352 -- compile the package as above.
353
354 Scop := Current_Scope;
355 while Scope (Scop) /= Standard_Standard
356 and then not Is_Child_Unit (Scop)
357 loop
358 if Is_Overloadable (Scop)
359 and then Is_Inlined (Scop)
360 and then not Is_Nested (Scop)
361 then
362 Add_Call (E, Scop);
363
364 if Inline_Level = 1 then
365 return Inline_Call;
366 else
367 return Inline_Package;
368 end if;
369 end if;
370
371 Scop := Scope (Scop);
372 end loop;
373
374 return Dont_Inline;
375 end Must_Inline;
376
377 Level : Inline_Level_Type;
378
379 -- Start of processing for Add_Inlined_Body
380
381 begin
382 Append_New_Elmt (N, To => Backend_Calls);
383
384 -- Skip subprograms that cannot be inlined outside their unit
385
386 if Is_Abstract_Subprogram (E)
387 or else Convention (E) = Convention_Protected
388 or else Is_Nested (E)
389 then
390 return;
391 end if;
392
393 -- Find out whether the call must be inlined. Unless the result is
394 -- Dont_Inline, Must_Inline also creates an edge for the call in the
395 -- callgraph; however, it will not be activated until after Is_Called
396 -- is set on the subprogram.
397
398 Level := Must_Inline;
399
400 if Level = Dont_Inline then
401 return;
402 end if;
403
404 -- If the call was generated by the compiler and is to a subprogram in
405 -- a run-time unit, we need to suppress debugging information for it,
406 -- so that the code that is eventually inlined will not affect the
407 -- debugging of the program. We do not do it if the call comes from
408 -- source because, even if the call is inlined, the user may expect it
409 -- to be present in the debugging information.
410
411 if not Comes_From_Source (N)
412 and then In_Extended_Main_Source_Unit (N)
413 and then Is_Predefined_Unit (Get_Source_Unit (E))
414 then
415 Set_Needs_Debug_Info (E, False);
416 end if;
417
418 -- If the subprogram is an expression function, then there is no need to
419 -- load any package body since the body of the function is in the spec.
420
421 if Is_Expression_Function (E) then
422 Set_Is_Called (E);
423 return;
424 end if;
425
426 -- Find unit containing E, and add to list of inlined bodies if needed.
427 -- If the body is already present, no need to load any other unit. This
428 -- is the case for an initialization procedure, which appears in the
429 -- package declaration that contains the type. It is also the case if
430 -- the body has already been analyzed. Finally, if the unit enclosing
431 -- E is an instance, the instance body will be analyzed in any case,
432 -- and there is no need to add the enclosing unit (whose body might not
433 -- be available).
434
435 -- Library-level functions must be handled specially, because there is
436 -- no enclosing package to retrieve. In this case, it is the body of
437 -- the function that will have to be loaded.
438
439 declare
440 Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
441
442 begin
443 if Pack = E then
444 Set_Is_Called (E);
445 Inlined_Bodies.Increment_Last;
446 Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
447
448 elsif Ekind (Pack) = E_Package then
449 Set_Is_Called (E);
450
451 if Is_Generic_Instance (Pack) then
452 null;
453
454 -- Do not inline the package if the subprogram is an init proc
455 -- or other internally generated subprogram, because in that
456 -- case the subprogram body appears in the same unit that
457 -- declares the type, and that body is visible to the back end.
458 -- Do not inline it either if it is in the main unit.
459 -- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
460 -- calls if the back-end takes care of inlining the call.
461 -- Note that Level in Inline_Package | Inline_Call here.
462
463 elsif ((Level = Inline_Call
464 and then Has_Pragma_Inline_Always (E)
465 and then Back_End_Inlining)
466 or else Level = Inline_Package)
467 and then not Is_Inlined (Pack)
468 and then not Is_Internal (E)
469 and then not In_Main_Unit_Or_Subunit (Pack)
470 then
471 Set_Is_Inlined (Pack);
472 Inlined_Bodies.Increment_Last;
473 Inlined_Bodies.Table (Inlined_Bodies.Last) := Pack;
474 end if;
475 end if;
476
477 -- Ensure that Analyze_Inlined_Bodies will be invoked after
478 -- completing the analysis of the current unit.
479
480 Inline_Processing_Required := True;
481 end;
482 end Add_Inlined_Body;
483
484 ----------------------------
485 -- Add_Inlined_Subprogram --
486 ----------------------------
487
488 procedure Add_Inlined_Subprogram (E : Entity_Id) is
489 Decl : constant Node_Id := Parent (Declaration_Node (E));
490 Pack : constant Entity_Id := Get_Code_Unit_Entity (E);
491
492 procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id);
493 -- Append Subp to the list of subprograms inlined by the backend
494
495 procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id);
496 -- Append Subp to the list of subprograms that cannot be inlined by
497 -- the backend.
498
499 -----------------------------------------
500 -- Register_Backend_Inlined_Subprogram --
501 -----------------------------------------
502
503 procedure Register_Backend_Inlined_Subprogram (Subp : Entity_Id) is
504 begin
505 Append_New_Elmt (Subp, To => Backend_Inlined_Subps);
506 end Register_Backend_Inlined_Subprogram;
507
508 ---------------------------------------------
509 -- Register_Backend_Not_Inlined_Subprogram --
510 ---------------------------------------------
511
512 procedure Register_Backend_Not_Inlined_Subprogram (Subp : Entity_Id) is
513 begin
514 Append_New_Elmt (Subp, To => Backend_Not_Inlined_Subps);
515 end Register_Backend_Not_Inlined_Subprogram;
516
517 -- Start of processing for Add_Inlined_Subprogram
518
519 begin
520 -- If the subprogram is to be inlined, and if its unit is known to be
521 -- inlined or is an instance whose body will be analyzed anyway or the
522 -- subprogram was generated as a body by the compiler (for example an
523 -- initialization procedure) or its declaration was provided along with
524 -- the body (for example an expression function), and if it is declared
525 -- at the library level not in the main unit, and if it can be inlined
526 -- by the back-end, then insert it in the list of inlined subprograms.
527
528 if Is_Inlined (E)
529 and then (Is_Inlined (Pack)
530 or else Is_Generic_Instance (Pack)
531 or else Nkind (Decl) = N_Subprogram_Body
532 or else Present (Corresponding_Body (Decl)))
533 and then not In_Main_Unit_Or_Subunit (E)
534 and then not Is_Nested (E)
535 and then not Has_Initialized_Type (E)
536 then
537 Register_Backend_Inlined_Subprogram (E);
538
539 if No (Last_Inlined) then
540 Set_First_Inlined_Subprogram (Cunit (Main_Unit), E);
541 else
542 Set_Next_Inlined_Subprogram (Last_Inlined, E);
543 end if;
544
545 Last_Inlined := E;
546
547 else
548 Register_Backend_Not_Inlined_Subprogram (E);
549 end if;
550 end Add_Inlined_Subprogram;
551
552 ------------------------
553 -- Add_Scope_To_Clean --
554 ------------------------
555
556 procedure Add_Scope_To_Clean (Inst : Entity_Id) is
557 Scop : constant Entity_Id := Enclosing_Dynamic_Scope (Inst);
558 Elmt : Elmt_Id;
559
560 begin
561 -- If the instance appears in a library-level package declaration,
562 -- all finalization is global, and nothing needs doing here.
563
564 if Scop = Standard_Standard then
565 return;
566 end if;
567
568 -- If the instance is within a generic unit, no finalization code
569 -- can be generated. Note that at this point all bodies have been
570 -- analyzed, and the scope stack itself is not present, and the flag
571 -- Inside_A_Generic is not set.
572
573 declare
574 S : Entity_Id;
575
576 begin
577 S := Scope (Inst);
578 while Present (S) and then S /= Standard_Standard loop
579 if Is_Generic_Unit (S) then
580 return;
581 end if;
582
583 S := Scope (S);
584 end loop;
585 end;
586
587 Elmt := First_Elmt (To_Clean);
588 while Present (Elmt) loop
589 if Node (Elmt) = Scop then
590 return;
591 end if;
592
593 Elmt := Next_Elmt (Elmt);
594 end loop;
595
596 Append_Elmt (Scop, To_Clean);
597 end Add_Scope_To_Clean;
598
599 --------------
600 -- Add_Subp --
601 --------------
602
603 function Add_Subp (E : Entity_Id) return Subp_Index is
604 Index : Subp_Index := Subp_Index (E) mod Num_Hash_Headers;
605 J : Subp_Index;
606
607 procedure New_Entry;
608 -- Initialize entry in Inlined table
609
610 procedure New_Entry is
611 begin
612 Inlined.Increment_Last;
613 Inlined.Table (Inlined.Last).Name := E;
614 Inlined.Table (Inlined.Last).Next := No_Subp;
615 Inlined.Table (Inlined.Last).First_Succ := No_Succ;
616 Inlined.Table (Inlined.Last).Main_Call := False;
617 Inlined.Table (Inlined.Last).Processed := False;
618 end New_Entry;
619
620 -- Start of processing for Add_Subp
621
622 begin
623 if Hash_Headers (Index) = No_Subp then
624 New_Entry;
625 Hash_Headers (Index) := Inlined.Last;
626 return Inlined.Last;
627
628 else
629 J := Hash_Headers (Index);
630 while J /= No_Subp loop
631 if Inlined.Table (J).Name = E then
632 return J;
633 else
634 Index := J;
635 J := Inlined.Table (J).Next;
636 end if;
637 end loop;
638
639 -- On exit, subprogram was not found. Enter in table. Index is
640 -- the current last entry on the hash chain.
641
642 New_Entry;
643 Inlined.Table (Index).Next := Inlined.Last;
644 return Inlined.Last;
645 end if;
646 end Add_Subp;
647
648 ----------------------------
649 -- Analyze_Inlined_Bodies --
650 ----------------------------
651
652 procedure Analyze_Inlined_Bodies is
653 Comp_Unit : Node_Id;
654 J : Int;
655 Pack : Entity_Id;
656 Subp : Subp_Index;
657 S : Succ_Index;
658
659 type Pending_Index is new Nat;
660
661 package Pending_Inlined is new Table.Table (
662 Table_Component_Type => Subp_Index,
663 Table_Index_Type => Pending_Index,
664 Table_Low_Bound => 1,
665 Table_Initial => Alloc.Inlined_Initial,
666 Table_Increment => Alloc.Inlined_Increment,
667 Table_Name => "Pending_Inlined");
668 -- The workpile used to compute the transitive closure
669
670 -- Start of processing for Analyze_Inlined_Bodies
671
672 begin
673 if Serious_Errors_Detected = 0 then
674 Push_Scope (Standard_Standard);
675
676 J := 0;
677 while J <= Inlined_Bodies.Last
678 and then Serious_Errors_Detected = 0
679 loop
680 Pack := Inlined_Bodies.Table (J);
681 while Present (Pack)
682 and then Scope (Pack) /= Standard_Standard
683 and then not Is_Child_Unit (Pack)
684 loop
685 Pack := Scope (Pack);
686 end loop;
687
688 Comp_Unit := Parent (Pack);
689 while Present (Comp_Unit)
690 and then Nkind (Comp_Unit) /= N_Compilation_Unit
691 loop
692 Comp_Unit := Parent (Comp_Unit);
693 end loop;
694
695 -- Load the body if it exists and contains inlineable entities,
696 -- unless it is the main unit, or is an instance whose body has
697 -- already been analyzed.
698
699 if Present (Comp_Unit)
700 and then Comp_Unit /= Cunit (Main_Unit)
701 and then Body_Required (Comp_Unit)
702 and then
703 (Nkind (Unit (Comp_Unit)) /= N_Package_Declaration
704 or else
705 (No (Corresponding_Body (Unit (Comp_Unit)))
706 and then Body_Needed_For_Inlining
707 (Defining_Entity (Unit (Comp_Unit)))))
708 then
709 declare
710 Bname : constant Unit_Name_Type :=
711 Get_Body_Name (Get_Unit_Name (Unit (Comp_Unit)));
712
713 OK : Boolean;
714
715 begin
716 if not Is_Loaded (Bname) then
717 Style_Check := False;
718 Load_Needed_Body (Comp_Unit, OK);
719
720 if not OK then
721
722 -- Warn that a body was not available for inlining
723 -- by the back-end.
724
725 Error_Msg_Unit_1 := Bname;
726 Error_Msg_N
727 ("one or more inlined subprograms accessed in $!??",
728 Comp_Unit);
729 Error_Msg_File_1 :=
730 Get_File_Name (Bname, Subunit => False);
731 Error_Msg_N ("\but file{ was not found!??", Comp_Unit);
732 end if;
733 end if;
734 end;
735 end if;
736
737 J := J + 1;
738
739 if J > Inlined_Bodies.Last then
740
741 -- The analysis of required bodies may have produced additional
742 -- generic instantiations. To obtain further inlining, we need
743 -- to perform another round of generic body instantiations.
744
745 Instantiate_Bodies;
746
747 -- Symmetrically, the instantiation of required generic bodies
748 -- may have caused additional bodies to be inlined. To obtain
749 -- further inlining, we keep looping over the inlined bodies.
750 end if;
751 end loop;
752
753 -- The list of inlined subprograms is an overestimate, because it
754 -- includes inlined functions called from functions that are compiled
755 -- as part of an inlined package, but are not themselves called. An
756 -- accurate computation of just those subprograms that are needed
757 -- requires that we perform a transitive closure over the call graph,
758 -- starting from calls in the main compilation unit.
759
760 for Index in Inlined.First .. Inlined.Last loop
761 if not Is_Called (Inlined.Table (Index).Name) then
762
763 -- This means that Add_Inlined_Body added the subprogram to the
764 -- table but wasn't able to handle its code unit. Do nothing.
765
766 Inlined.Table (Index).Processed := True;
767
768 elsif Inlined.Table (Index).Main_Call then
769 Pending_Inlined.Increment_Last;
770 Pending_Inlined.Table (Pending_Inlined.Last) := Index;
771 Inlined.Table (Index).Processed := True;
772
773 else
774 Set_Is_Called (Inlined.Table (Index).Name, False);
775 end if;
776 end loop;
777
778 -- Iterate over the workpile until it is emptied, propagating the
779 -- Is_Called flag to the successors of the processed subprogram.
780
781 while Pending_Inlined.Last >= Pending_Inlined.First loop
782 Subp := Pending_Inlined.Table (Pending_Inlined.Last);
783 Pending_Inlined.Decrement_Last;
784
785 S := Inlined.Table (Subp).First_Succ;
786
787 while S /= No_Succ loop
788 Subp := Successors.Table (S).Subp;
789
790 if not Inlined.Table (Subp).Processed then
791 Set_Is_Called (Inlined.Table (Subp).Name);
792 Pending_Inlined.Increment_Last;
793 Pending_Inlined.Table (Pending_Inlined.Last) := Subp;
794 Inlined.Table (Subp).Processed := True;
795 end if;
796
797 S := Successors.Table (S).Next;
798 end loop;
799 end loop;
800
801 -- Finally add the called subprograms to the list of inlined
802 -- subprograms for the unit.
803
804 for Index in Inlined.First .. Inlined.Last loop
805 if Is_Called (Inlined.Table (Index).Name) then
806 Add_Inlined_Subprogram (Inlined.Table (Index).Name);
807 end if;
808 end loop;
809
810 Pop_Scope;
811 end if;
812 end Analyze_Inlined_Bodies;
813
814 --------------------------
815 -- Build_Body_To_Inline --
816 --------------------------
817
818 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
819 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
820 Analysis_Status : constant Boolean := Full_Analysis;
821 Original_Body : Node_Id;
822 Body_To_Analyze : Node_Id;
823 Max_Size : constant := 10;
824
825 function Has_Pending_Instantiation return Boolean;
826 -- If some enclosing body contains instantiations that appear before
827 -- the corresponding generic body, the enclosing body has a freeze node
828 -- so that it can be elaborated after the generic itself. This might
829 -- conflict with subsequent inlinings, so that it is unsafe to try to
830 -- inline in such a case.
831
832 function Has_Single_Return_In_GNATprove_Mode return Boolean;
833 -- This function is called only in GNATprove mode, and it returns
834 -- True if the subprogram has no return statement or a single return
835 -- statement as last statement. It returns False for subprogram with
836 -- a single return as last statement inside one or more blocks, as
837 -- inlining would generate gotos in that case as well (although the
838 -- goto is useless in that case).
839
840 function Uses_Secondary_Stack (Bod : Node_Id) return Boolean;
841 -- If the body of the subprogram includes a call that returns an
842 -- unconstrained type, the secondary stack is involved, and it
843 -- is not worth inlining.
844
845 -------------------------------
846 -- Has_Pending_Instantiation --
847 -------------------------------
848
849 function Has_Pending_Instantiation return Boolean is
850 S : Entity_Id;
851
852 begin
853 S := Current_Scope;
854 while Present (S) loop
855 if Is_Compilation_Unit (S)
856 or else Is_Child_Unit (S)
857 then
858 return False;
859
860 elsif Ekind (S) = E_Package
861 and then Has_Forward_Instantiation (S)
862 then
863 return True;
864 end if;
865
866 S := Scope (S);
867 end loop;
868
869 return False;
870 end Has_Pending_Instantiation;
871
872 -----------------------------------------
873 -- Has_Single_Return_In_GNATprove_Mode --
874 -----------------------------------------
875
876 function Has_Single_Return_In_GNATprove_Mode return Boolean is
877 Body_To_Inline : constant Node_Id := N;
878 Last_Statement : Node_Id := Empty;
879
880 function Check_Return (N : Node_Id) return Traverse_Result;
881 -- Returns OK on node N if this is not a return statement different
882 -- from the last statement in the subprogram.
883
884 ------------------
885 -- Check_Return --
886 ------------------
887
888 function Check_Return (N : Node_Id) return Traverse_Result is
889 begin
890 case Nkind (N) is
891 when N_Extended_Return_Statement
892 | N_Simple_Return_Statement
893 =>
894 if N = Last_Statement then
895 return OK;
896 else
897 return Abandon;
898 end if;
899
900 -- Skip locally declared subprogram bodies inside the body to
901 -- inline, as the return statements inside those do not count.
902
903 when N_Subprogram_Body =>
904 if N = Body_To_Inline then
905 return OK;
906 else
907 return Skip;
908 end if;
909
910 when others =>
911 return OK;
912 end case;
913 end Check_Return;
914
915 function Check_All_Returns is new Traverse_Func (Check_Return);
916
917 -- Start of processing for Has_Single_Return_In_GNATprove_Mode
918
919 begin
920 -- Retrieve the last statement
921
922 Last_Statement := Last (Statements (Handled_Statement_Sequence (N)));
923
924 -- Check that the last statement is the only possible return
925 -- statement in the subprogram.
926
927 return Check_All_Returns (N) = OK;
928 end Has_Single_Return_In_GNATprove_Mode;
929
930 --------------------------
931 -- Uses_Secondary_Stack --
932 --------------------------
933
934 function Uses_Secondary_Stack (Bod : Node_Id) return Boolean is
935 function Check_Call (N : Node_Id) return Traverse_Result;
936 -- Look for function calls that return an unconstrained type
937
938 ----------------
939 -- Check_Call --
940 ----------------
941
942 function Check_Call (N : Node_Id) return Traverse_Result is
943 begin
944 if Nkind (N) = N_Function_Call
945 and then Is_Entity_Name (Name (N))
946 and then Is_Composite_Type (Etype (Entity (Name (N))))
947 and then not Is_Constrained (Etype (Entity (Name (N))))
948 then
949 Cannot_Inline
950 ("cannot inline & (call returns unconstrained type)?",
951 N, Spec_Id);
952 return Abandon;
953 else
954 return OK;
955 end if;
956 end Check_Call;
957
958 function Check_Calls is new Traverse_Func (Check_Call);
959
960 begin
961 return Check_Calls (Bod) = Abandon;
962 end Uses_Secondary_Stack;
963
964 -- Start of processing for Build_Body_To_Inline
965
966 begin
967 -- Return immediately if done already
968
969 if Nkind (Decl) = N_Subprogram_Declaration
970 and then Present (Body_To_Inline (Decl))
971 then
972 return;
973
974 -- Subprograms that have return statements in the middle of the body are
975 -- inlined with gotos. GNATprove does not currently support gotos, so
976 -- we prevent such inlining.
977
978 elsif GNATprove_Mode
979 and then not Has_Single_Return_In_GNATprove_Mode
980 then
981 Cannot_Inline ("cannot inline & (multiple returns)?", N, Spec_Id);
982 return;
983
984 -- Functions that return unconstrained composite types require
985 -- secondary stack handling, and cannot currently be inlined, unless
986 -- all return statements return a local variable that is the first
987 -- local declaration in the body.
988
989 elsif Ekind (Spec_Id) = E_Function
990 and then not Is_Scalar_Type (Etype (Spec_Id))
991 and then not Is_Access_Type (Etype (Spec_Id))
992 and then not Is_Constrained (Etype (Spec_Id))
993 then
994 if not Has_Single_Return (N) then
995 Cannot_Inline
996 ("cannot inline & (unconstrained return type)?", N, Spec_Id);
997 return;
998 end if;
999
1000 -- Ditto for functions that return controlled types, where controlled
1001 -- actions interfere in complex ways with inlining.
1002
1003 elsif Ekind (Spec_Id) = E_Function
1004 and then Needs_Finalization (Etype (Spec_Id))
1005 then
1006 Cannot_Inline
1007 ("cannot inline & (controlled return type)?", N, Spec_Id);
1008 return;
1009 end if;
1010
1011 if Present (Declarations (N))
1012 and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
1013 then
1014 return;
1015 end if;
1016
1017 if Present (Handled_Statement_Sequence (N)) then
1018 if Present (Exception_Handlers (Handled_Statement_Sequence (N))) then
1019 Cannot_Inline
1020 ("cannot inline& (exception handler)?",
1021 First (Exception_Handlers (Handled_Statement_Sequence (N))),
1022 Spec_Id);
1023 return;
1024
1025 elsif Has_Excluded_Statement
1026 (Spec_Id, Statements (Handled_Statement_Sequence (N)))
1027 then
1028 return;
1029 end if;
1030 end if;
1031
1032 -- We do not inline a subprogram that is too large, unless it is marked
1033 -- Inline_Always or we are in GNATprove mode. This pragma does not
1034 -- suppress the other checks on inlining (forbidden declarations,
1035 -- handlers, etc).
1036
1037 if not (Has_Pragma_Inline_Always (Spec_Id) or else GNATprove_Mode)
1038 and then List_Length
1039 (Statements (Handled_Statement_Sequence (N))) > Max_Size
1040 then
1041 Cannot_Inline ("cannot inline& (body too large)?", N, Spec_Id);
1042 return;
1043 end if;
1044
1045 if Has_Pending_Instantiation then
1046 Cannot_Inline
1047 ("cannot inline& (forward instance within enclosing body)?",
1048 N, Spec_Id);
1049 return;
1050 end if;
1051
1052 -- Within an instance, the body to inline must be treated as a nested
1053 -- generic, so that the proper global references are preserved.
1054
1055 -- Note that we do not do this at the library level, because it is not
1056 -- needed, and furthermore this causes trouble if front-end inlining
1057 -- is activated (-gnatN).
1058
1059 if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1060 Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1061 Original_Body := Copy_Generic_Node (N, Empty, Instantiating => True);
1062 else
1063 Original_Body := Copy_Separate_Tree (N);
1064 end if;
1065
1066 -- We need to capture references to the formals in order to substitute
1067 -- the actuals at the point of inlining, i.e. instantiation. To treat
1068 -- the formals as globals to the body to inline, we nest it within a
1069 -- dummy parameterless subprogram, declared within the real one. To
1070 -- avoid generating an internal name (which is never public, and which
1071 -- affects serial numbers of other generated names), we use an internal
1072 -- symbol that cannot conflict with user declarations.
1073
1074 Set_Parameter_Specifications (Specification (Original_Body), No_List);
1075 Set_Defining_Unit_Name
1076 (Specification (Original_Body),
1077 Make_Defining_Identifier (Sloc (N), Name_uParent));
1078 Set_Corresponding_Spec (Original_Body, Empty);
1079
1080 -- Remove all aspects/pragmas that have no meaning in an inlined body
1081
1082 Remove_Aspects_And_Pragmas (Original_Body);
1083
1084 Body_To_Analyze :=
1085 Copy_Generic_Node (Original_Body, Empty, Instantiating => False);
1086
1087 -- Set return type of function, which is also global and does not need
1088 -- to be resolved.
1089
1090 if Ekind (Spec_Id) = E_Function then
1091 Set_Result_Definition
1092 (Specification (Body_To_Analyze),
1093 New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1094 end if;
1095
1096 if No (Declarations (N)) then
1097 Set_Declarations (N, New_List (Body_To_Analyze));
1098 else
1099 Append (Body_To_Analyze, Declarations (N));
1100 end if;
1101
1102 -- The body to inline is pre-analyzed. In GNATprove mode we must disable
1103 -- full analysis as well so that light expansion does not take place
1104 -- either, and name resolution is unaffected.
1105
1106 Expander_Mode_Save_And_Set (False);
1107 Full_Analysis := False;
1108
1109 Analyze (Body_To_Analyze);
1110 Push_Scope (Defining_Entity (Body_To_Analyze));
1111 Save_Global_References (Original_Body);
1112 End_Scope;
1113 Remove (Body_To_Analyze);
1114
1115 Expander_Mode_Restore;
1116 Full_Analysis := Analysis_Status;
1117
1118 -- Restore environment if previously saved
1119
1120 if In_Instance and then Scope (Current_Scope) /= Standard_Standard then
1121 Restore_Env;
1122 end if;
1123
1124 -- If secondary stack is used, there is no point in inlining. We have
1125 -- already issued the warning in this case, so nothing to do.
1126
1127 if Uses_Secondary_Stack (Body_To_Analyze) then
1128 return;
1129 end if;
1130
1131 Set_Body_To_Inline (Decl, Original_Body);
1132 Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1133 Set_Is_Inlined (Spec_Id);
1134 end Build_Body_To_Inline;
1135
1136 -------------------------------------------
1137 -- Call_Can_Be_Inlined_In_GNATprove_Mode --
1138 -------------------------------------------
1139
1140 function Call_Can_Be_Inlined_In_GNATprove_Mode
1141 (N : Node_Id;
1142 Subp : Entity_Id) return Boolean
1143 is
1144 F : Entity_Id;
1145 A : Node_Id;
1146
1147 begin
1148 F := First_Formal (Subp);
1149 A := First_Actual (N);
1150 while Present (F) loop
1151 if Ekind (F) /= E_Out_Parameter
1152 and then not Same_Type (Etype (F), Etype (A))
1153 and then
1154 (Is_By_Reference_Type (Etype (A))
1155 or else Is_Limited_Type (Etype (A)))
1156 then
1157 return False;
1158 end if;
1159
1160 Next_Formal (F);
1161 Next_Actual (A);
1162 end loop;
1163
1164 return True;
1165 end Call_Can_Be_Inlined_In_GNATprove_Mode;
1166
1167 --------------------------------------
1168 -- Can_Be_Inlined_In_GNATprove_Mode --
1169 --------------------------------------
1170
1171 function Can_Be_Inlined_In_GNATprove_Mode
1172 (Spec_Id : Entity_Id;
1173 Body_Id : Entity_Id) return Boolean
1174 is
1175 function Has_Formal_With_Discriminant_Dependent_Fields
1176 (Id : Entity_Id) return Boolean;
1177 -- Returns true if the subprogram has at least one formal parameter of
1178 -- an unconstrained record type with per-object constraints on component
1179 -- types.
1180
1181 function Has_Some_Contract (Id : Entity_Id) return Boolean;
1182 -- Return True if subprogram Id has any contract. The presence of
1183 -- Extensions_Visible or Volatile_Function is also considered as a
1184 -- contract here.
1185
1186 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean;
1187 -- Return True if subprogram Id defines a compilation unit
1188 -- Shouldn't this be in Sem_Aux???
1189
1190 function In_Package_Spec (Id : Entity_Id) return Boolean;
1191 -- Return True if subprogram Id is defined in the package specification,
1192 -- either its visible or private part.
1193
1194 ---------------------------------------------------
1195 -- Has_Formal_With_Discriminant_Dependent_Fields --
1196 ---------------------------------------------------
1197
1198 function Has_Formal_With_Discriminant_Dependent_Fields
1199 (Id : Entity_Id) return Boolean
1200 is
1201 function Has_Discriminant_Dependent_Component
1202 (Typ : Entity_Id) return Boolean;
1203 -- Determine whether unconstrained record type Typ has at least one
1204 -- component that depends on a discriminant.
1205
1206 ------------------------------------------
1207 -- Has_Discriminant_Dependent_Component --
1208 ------------------------------------------
1209
1210 function Has_Discriminant_Dependent_Component
1211 (Typ : Entity_Id) return Boolean
1212 is
1213 Comp : Entity_Id;
1214
1215 begin
1216 -- Inspect all components of the record type looking for one that
1217 -- depends on a discriminant.
1218
1219 Comp := First_Component (Typ);
1220 while Present (Comp) loop
1221 if Has_Discriminant_Dependent_Constraint (Comp) then
1222 return True;
1223 end if;
1224
1225 Next_Component (Comp);
1226 end loop;
1227
1228 return False;
1229 end Has_Discriminant_Dependent_Component;
1230
1231 -- Local variables
1232
1233 Subp_Id : constant Entity_Id := Ultimate_Alias (Id);
1234 Formal : Entity_Id;
1235 Formal_Typ : Entity_Id;
1236
1237 -- Start of processing for
1238 -- Has_Formal_With_Discriminant_Dependent_Fields
1239
1240 begin
1241 -- Inspect all parameters of the subprogram looking for a formal
1242 -- of an unconstrained record type with at least one discriminant
1243 -- dependent component.
1244
1245 Formal := First_Formal (Subp_Id);
1246 while Present (Formal) loop
1247 Formal_Typ := Etype (Formal);
1248
1249 if Is_Record_Type (Formal_Typ)
1250 and then not Is_Constrained (Formal_Typ)
1251 and then Has_Discriminant_Dependent_Component (Formal_Typ)
1252 then
1253 return True;
1254 end if;
1255
1256 Next_Formal (Formal);
1257 end loop;
1258
1259 return False;
1260 end Has_Formal_With_Discriminant_Dependent_Fields;
1261
1262 -----------------------
1263 -- Has_Some_Contract --
1264 -----------------------
1265
1266 function Has_Some_Contract (Id : Entity_Id) return Boolean is
1267 Items : Node_Id;
1268
1269 begin
1270 -- A call to an expression function may precede the actual body which
1271 -- is inserted at the end of the enclosing declarations. Ensure that
1272 -- the related entity is decorated before inspecting the contract.
1273
1274 if Is_Subprogram_Or_Generic_Subprogram (Id) then
1275 Items := Contract (Id);
1276
1277 -- Note that Classifications is not Empty when Extensions_Visible
1278 -- or Volatile_Function is present, which causes such subprograms
1279 -- to be considered to have a contract here. This is fine as we
1280 -- want to avoid inlining these too.
1281
1282 return Present (Items)
1283 and then (Present (Pre_Post_Conditions (Items)) or else
1284 Present (Contract_Test_Cases (Items)) or else
1285 Present (Classifications (Items)));
1286 end if;
1287
1288 return False;
1289 end Has_Some_Contract;
1290
1291 ---------------------
1292 -- In_Package_Spec --
1293 ---------------------
1294
1295 function In_Package_Spec (Id : Entity_Id) return Boolean is
1296 P : constant Node_Id := Parent (Subprogram_Spec (Id));
1297 -- Parent of the subprogram's declaration
1298
1299 begin
1300 return Nkind (Enclosing_Declaration (P)) = N_Package_Declaration;
1301 end In_Package_Spec;
1302
1303 ------------------------
1304 -- Is_Unit_Subprogram --
1305 ------------------------
1306
1307 function Is_Unit_Subprogram (Id : Entity_Id) return Boolean is
1308 Decl : Node_Id := Parent (Parent (Id));
1309 begin
1310 if Nkind (Parent (Id)) = N_Defining_Program_Unit_Name then
1311 Decl := Parent (Decl);
1312 end if;
1313
1314 return Nkind (Parent (Decl)) = N_Compilation_Unit;
1315 end Is_Unit_Subprogram;
1316
1317 -- Local declarations
1318
1319 Id : Entity_Id;
1320 -- Procedure or function entity for the subprogram
1321
1322 -- Start of processing for Can_Be_Inlined_In_GNATprove_Mode
1323
1324 begin
1325 pragma Assert (Present (Spec_Id) or else Present (Body_Id));
1326
1327 if Present (Spec_Id) then
1328 Id := Spec_Id;
1329 else
1330 Id := Body_Id;
1331 end if;
1332
1333 -- Only local subprograms without contracts are inlined in GNATprove
1334 -- mode, as these are the subprograms which a user is not interested in
1335 -- analyzing in isolation, but rather in the context of their call. This
1336 -- is a convenient convention, that could be changed for an explicit
1337 -- pragma/aspect one day.
1338
1339 -- In a number of special cases, inlining is not desirable or not
1340 -- possible, see below.
1341
1342 -- Do not inline unit-level subprograms
1343
1344 if Is_Unit_Subprogram (Id) then
1345 return False;
1346
1347 -- Do not inline subprograms declared in package specs, because they are
1348 -- not local, i.e. can be called either from anywhere (if declared in
1349 -- visible part) or from the child units (if declared in private part).
1350
1351 elsif In_Package_Spec (Id) then
1352 return False;
1353
1354 -- Do not inline subprograms declared in other units. This is important
1355 -- in particular for subprograms defined in the private part of a
1356 -- package spec, when analyzing one of its child packages, as otherwise
1357 -- we issue spurious messages about the impossibility to inline such
1358 -- calls.
1359
1360 elsif not In_Extended_Main_Code_Unit (Id) then
1361 return False;
1362
1363 -- Do not inline subprograms marked No_Return, possibly used for
1364 -- signaling errors, which GNATprove handles specially.
1365
1366 elsif No_Return (Id) then
1367 return False;
1368
1369 -- Do not inline subprograms that have a contract on the spec or the
1370 -- body. Use the contract(s) instead in GNATprove. This also prevents
1371 -- inlining of subprograms with Extensions_Visible or Volatile_Function.
1372
1373 elsif (Present (Spec_Id) and then Has_Some_Contract (Spec_Id))
1374 or else
1375 (Present (Body_Id) and then Has_Some_Contract (Body_Id))
1376 then
1377 return False;
1378
1379 -- Do not inline expression functions, which are directly inlined at the
1380 -- prover level.
1381
1382 elsif (Present (Spec_Id) and then Is_Expression_Function (Spec_Id))
1383 or else
1384 (Present (Body_Id) and then Is_Expression_Function (Body_Id))
1385 then
1386 return False;
1387
1388 -- Do not inline generic subprogram instances. The visibility rules of
1389 -- generic instances plays badly with inlining.
1390
1391 elsif Is_Generic_Instance (Spec_Id) then
1392 return False;
1393
1394 -- Only inline subprograms whose spec is marked SPARK_Mode On. For
1395 -- the subprogram body, a similar check is performed after the body
1396 -- is analyzed, as this is where a pragma SPARK_Mode might be inserted.
1397
1398 elsif Present (Spec_Id)
1399 and then
1400 (No (SPARK_Pragma (Spec_Id))
1401 or else
1402 Get_SPARK_Mode_From_Annotation (SPARK_Pragma (Spec_Id)) /= On)
1403 then
1404 return False;
1405
1406 -- Subprograms in generic instances are currently not inlined, to avoid
1407 -- problems with inlining of standard library subprograms.
1408
1409 elsif Instantiation_Location (Sloc (Id)) /= No_Location then
1410 return False;
1411
1412 -- Do not inline subprograms and entries defined inside protected types,
1413 -- which typically are not helper subprograms, which also avoids getting
1414 -- spurious messages on calls that cannot be inlined.
1415
1416 elsif Within_Protected_Type (Id) then
1417 return False;
1418
1419 -- Do not inline predicate functions (treated specially by GNATprove)
1420
1421 elsif Is_Predicate_Function (Id) then
1422 return False;
1423
1424 -- Do not inline subprograms with a parameter of an unconstrained
1425 -- record type if it has discrimiant dependent fields. Indeed, with
1426 -- such parameters, the frontend cannot always ensure type compliance
1427 -- in record component accesses (in particular with records containing
1428 -- packed arrays).
1429
1430 elsif Has_Formal_With_Discriminant_Dependent_Fields (Id) then
1431 return False;
1432
1433 -- Otherwise, this is a subprogram declared inside the private part of a
1434 -- package, or inside a package body, or locally in a subprogram, and it
1435 -- does not have any contract. Inline it.
1436
1437 else
1438 return True;
1439 end if;
1440 end Can_Be_Inlined_In_GNATprove_Mode;
1441
1442 -------------------
1443 -- Cannot_Inline --
1444 -------------------
1445
1446 procedure Cannot_Inline
1447 (Msg : String;
1448 N : Node_Id;
1449 Subp : Entity_Id;
1450 Is_Serious : Boolean := False)
1451 is
1452 begin
1453 -- In GNATprove mode, inlining is the technical means by which the
1454 -- higher-level goal of contextual analysis is reached, so issue
1455 -- messages about failure to apply contextual analysis to a
1456 -- subprogram, rather than failure to inline it.
1457
1458 if GNATprove_Mode
1459 and then Msg (Msg'First .. Msg'First + 12) = "cannot inline"
1460 then
1461 declare
1462 Len1 : constant Positive :=
1463 String (String'("cannot inline"))'Length;
1464 Len2 : constant Positive :=
1465 String (String'("info: no contextual analysis of"))'Length;
1466
1467 New_Msg : String (1 .. Msg'Length + Len2 - Len1);
1468
1469 begin
1470 New_Msg (1 .. Len2) := "info: no contextual analysis of";
1471 New_Msg (Len2 + 1 .. Msg'Length + Len2 - Len1) :=
1472 Msg (Msg'First + Len1 .. Msg'Last);
1473 Cannot_Inline (New_Msg, N, Subp, Is_Serious);
1474 return;
1475 end;
1476 end if;
1477
1478 pragma Assert (Msg (Msg'Last) = '?');
1479
1480 -- Legacy front-end inlining model
1481
1482 if not Back_End_Inlining then
1483
1484 -- Do not emit warning if this is a predefined unit which is not
1485 -- the main unit. With validity checks enabled, some predefined
1486 -- subprograms may contain nested subprograms and become ineligible
1487 -- for inlining.
1488
1489 if Is_Predefined_Unit (Get_Source_Unit (Subp))
1490 and then not In_Extended_Main_Source_Unit (Subp)
1491 then
1492 null;
1493
1494 -- In GNATprove mode, issue a warning, and indicate that the
1495 -- subprogram is not always inlined by setting flag Is_Inlined_Always
1496 -- to False.
1497
1498 elsif GNATprove_Mode then
1499 Set_Is_Inlined_Always (Subp, False);
1500 Error_Msg_NE (Msg & "p?", N, Subp);
1501
1502 elsif Has_Pragma_Inline_Always (Subp) then
1503
1504 -- Remove last character (question mark) to make this into an
1505 -- error, because the Inline_Always pragma cannot be obeyed.
1506
1507 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1508
1509 elsif Ineffective_Inline_Warnings then
1510 Error_Msg_NE (Msg & "p?", N, Subp);
1511 end if;
1512
1513 -- New semantics relying on back-end inlining
1514
1515 elsif Is_Serious then
1516
1517 -- Remove last character (question mark) to make this into an error.
1518
1519 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1520
1521 -- In GNATprove mode, issue a warning, and indicate that the subprogram
1522 -- is not always inlined by setting flag Is_Inlined_Always to False.
1523
1524 elsif GNATprove_Mode then
1525 Set_Is_Inlined_Always (Subp, False);
1526 Error_Msg_NE (Msg & "p?", N, Subp);
1527
1528 else
1529
1530 -- Do not emit warning if this is a predefined unit which is not
1531 -- the main unit. This behavior is currently provided for backward
1532 -- compatibility but it will be removed when we enforce the
1533 -- strictness of the new rules.
1534
1535 if Is_Predefined_Unit (Get_Source_Unit (Subp))
1536 and then not In_Extended_Main_Source_Unit (Subp)
1537 then
1538 null;
1539
1540 elsif Has_Pragma_Inline_Always (Subp) then
1541
1542 -- Emit a warning if this is a call to a runtime subprogram
1543 -- which is located inside a generic. Previously this call
1544 -- was silently skipped.
1545
1546 if Is_Generic_Instance (Subp) then
1547 declare
1548 Gen_P : constant Entity_Id := Generic_Parent (Parent (Subp));
1549 begin
1550 if Is_Predefined_Unit (Get_Source_Unit (Gen_P)) then
1551 Set_Is_Inlined (Subp, False);
1552 Error_Msg_NE (Msg & "p?", N, Subp);
1553 return;
1554 end if;
1555 end;
1556 end if;
1557
1558 -- Remove last character (question mark) to make this into an
1559 -- error, because the Inline_Always pragma cannot be obeyed.
1560
1561 Error_Msg_NE (Msg (Msg'First .. Msg'Last - 1), N, Subp);
1562
1563 else
1564 Set_Is_Inlined (Subp, False);
1565
1566 if Ineffective_Inline_Warnings then
1567 Error_Msg_NE (Msg & "p?", N, Subp);
1568 end if;
1569 end if;
1570 end if;
1571 end Cannot_Inline;
1572
1573 --------------------------------------------
1574 -- Check_And_Split_Unconstrained_Function --
1575 --------------------------------------------
1576
1577 procedure Check_And_Split_Unconstrained_Function
1578 (N : Node_Id;
1579 Spec_Id : Entity_Id;
1580 Body_Id : Entity_Id)
1581 is
1582 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id);
1583 -- Use generic machinery to build an unexpanded body for the subprogram.
1584 -- This body is subsequently used for inline expansions at call sites.
1585
1586 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean;
1587 -- Return true if we generate code for the function body N, the function
1588 -- body N has no local declarations and its unique statement is a single
1589 -- extended return statement with a handled statements sequence.
1590
1591 procedure Split_Unconstrained_Function
1592 (N : Node_Id;
1593 Spec_Id : Entity_Id);
1594 -- N is an inlined function body that returns an unconstrained type and
1595 -- has a single extended return statement. Split N in two subprograms:
1596 -- a procedure P' and a function F'. The formals of P' duplicate the
1597 -- formals of N plus an extra formal which is used to return a value;
1598 -- its body is composed by the declarations and list of statements
1599 -- of the extended return statement of N.
1600
1601 --------------------------
1602 -- Build_Body_To_Inline --
1603 --------------------------
1604
1605 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id) is
1606 procedure Generate_Subprogram_Body
1607 (N : Node_Id;
1608 Body_To_Inline : out Node_Id);
1609 -- Generate a parameterless duplicate of subprogram body N. Note that
1610 -- occurrences of pragmas referencing the formals are removed since
1611 -- they have no meaning when the body is inlined and the formals are
1612 -- rewritten (the analysis of the non-inlined body will handle these
1613 -- pragmas). A new internal name is associated with Body_To_Inline.
1614
1615 -----------------------------
1616 -- Generate_Body_To_Inline --
1617 -----------------------------
1618
1619 procedure Generate_Subprogram_Body
1620 (N : Node_Id;
1621 Body_To_Inline : out Node_Id)
1622 is
1623 begin
1624 -- Within an instance, the body to inline must be treated as a
1625 -- nested generic so that proper global references are preserved.
1626
1627 -- Note that we do not do this at the library level, because it
1628 -- is not needed, and furthermore this causes trouble if front
1629 -- end inlining is activated (-gnatN).
1630
1631 if In_Instance
1632 and then Scope (Current_Scope) /= Standard_Standard
1633 then
1634 Body_To_Inline :=
1635 Copy_Generic_Node (N, Empty, Instantiating => True);
1636 else
1637 Body_To_Inline := Copy_Separate_Tree (N);
1638 end if;
1639
1640 -- Remove aspects/pragmas that have no meaning in an inlined body
1641
1642 Remove_Aspects_And_Pragmas (Body_To_Inline);
1643
1644 -- We need to capture references to the formals in order
1645 -- to substitute the actuals at the point of inlining, i.e.
1646 -- instantiation. To treat the formals as globals to the body to
1647 -- inline, we nest it within a dummy parameterless subprogram,
1648 -- declared within the real one.
1649
1650 Set_Parameter_Specifications
1651 (Specification (Body_To_Inline), No_List);
1652
1653 -- A new internal name is associated with Body_To_Inline to avoid
1654 -- conflicts when the non-inlined body N is analyzed.
1655
1656 Set_Defining_Unit_Name (Specification (Body_To_Inline),
1657 Make_Defining_Identifier (Sloc (N), New_Internal_Name ('P')));
1658 Set_Corresponding_Spec (Body_To_Inline, Empty);
1659 end Generate_Subprogram_Body;
1660
1661 -- Local variables
1662
1663 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1664 Original_Body : Node_Id;
1665 Body_To_Analyze : Node_Id;
1666
1667 begin
1668 pragma Assert (Current_Scope = Spec_Id);
1669
1670 -- Within an instance, the body to inline must be treated as a nested
1671 -- generic, so that the proper global references are preserved. We
1672 -- do not do this at the library level, because it is not needed, and
1673 -- furthermore this causes trouble if front-end inlining is activated
1674 -- (-gnatN).
1675
1676 if In_Instance
1677 and then Scope (Current_Scope) /= Standard_Standard
1678 then
1679 Save_Env (Scope (Current_Scope), Scope (Current_Scope));
1680 end if;
1681
1682 -- Capture references to formals in order to substitute the actuals
1683 -- at the point of inlining or instantiation. To treat the formals
1684 -- as globals to the body to inline, nest the body within a dummy
1685 -- parameterless subprogram, declared within the real one.
1686
1687 Generate_Subprogram_Body (N, Original_Body);
1688 Body_To_Analyze :=
1689 Copy_Generic_Node (Original_Body, Empty, Instantiating => False);
1690
1691 -- Set return type of function, which is also global and does not
1692 -- need to be resolved.
1693
1694 if Ekind (Spec_Id) = E_Function then
1695 Set_Result_Definition (Specification (Body_To_Analyze),
1696 New_Occurrence_Of (Etype (Spec_Id), Sloc (N)));
1697 end if;
1698
1699 if No (Declarations (N)) then
1700 Set_Declarations (N, New_List (Body_To_Analyze));
1701 else
1702 Append_To (Declarations (N), Body_To_Analyze);
1703 end if;
1704
1705 Preanalyze (Body_To_Analyze);
1706
1707 Push_Scope (Defining_Entity (Body_To_Analyze));
1708 Save_Global_References (Original_Body);
1709 End_Scope;
1710 Remove (Body_To_Analyze);
1711
1712 -- Restore environment if previously saved
1713
1714 if In_Instance
1715 and then Scope (Current_Scope) /= Standard_Standard
1716 then
1717 Restore_Env;
1718 end if;
1719
1720 pragma Assert (No (Body_To_Inline (Decl)));
1721 Set_Body_To_Inline (Decl, Original_Body);
1722 Set_Ekind (Defining_Entity (Original_Body), Ekind (Spec_Id));
1723 end Build_Body_To_Inline;
1724
1725 --------------------------------------
1726 -- Can_Split_Unconstrained_Function --
1727 --------------------------------------
1728
1729 function Can_Split_Unconstrained_Function (N : Node_Id) return Boolean is
1730 Ret_Node : constant Node_Id :=
1731 First (Statements (Handled_Statement_Sequence (N)));
1732 D : Node_Id;
1733
1734 begin
1735 -- No user defined declarations allowed in the function except inside
1736 -- the unique return statement; implicit labels are the only allowed
1737 -- declarations.
1738
1739 if not Is_Empty_List (Declarations (N)) then
1740 D := First (Declarations (N));
1741 while Present (D) loop
1742 if Nkind (D) /= N_Implicit_Label_Declaration then
1743 return False;
1744 end if;
1745
1746 Next (D);
1747 end loop;
1748 end if;
1749
1750 -- We only split the inlined function when we are generating the code
1751 -- of its body; otherwise we leave duplicated split subprograms in
1752 -- the tree which (if referenced) generate wrong references at link
1753 -- time.
1754
1755 return In_Extended_Main_Code_Unit (N)
1756 and then Present (Ret_Node)
1757 and then Nkind (Ret_Node) = N_Extended_Return_Statement
1758 and then No (Next (Ret_Node))
1759 and then Present (Handled_Statement_Sequence (Ret_Node));
1760 end Can_Split_Unconstrained_Function;
1761
1762 ----------------------------------
1763 -- Split_Unconstrained_Function --
1764 ----------------------------------
1765
1766 procedure Split_Unconstrained_Function
1767 (N : Node_Id;
1768 Spec_Id : Entity_Id)
1769 is
1770 Loc : constant Source_Ptr := Sloc (N);
1771 Ret_Node : constant Node_Id :=
1772 First (Statements (Handled_Statement_Sequence (N)));
1773 Ret_Obj : constant Node_Id :=
1774 First (Return_Object_Declarations (Ret_Node));
1775
1776 procedure Build_Procedure
1777 (Proc_Id : out Entity_Id;
1778 Decl_List : out List_Id);
1779 -- Build a procedure containing the statements found in the extended
1780 -- return statement of the unconstrained function body N.
1781
1782 ---------------------
1783 -- Build_Procedure --
1784 ---------------------
1785
1786 procedure Build_Procedure
1787 (Proc_Id : out Entity_Id;
1788 Decl_List : out List_Id)
1789 is
1790 Formal : Entity_Id;
1791 Formal_List : constant List_Id := New_List;
1792 Proc_Spec : Node_Id;
1793 Proc_Body : Node_Id;
1794 Subp_Name : constant Name_Id := New_Internal_Name ('F');
1795 Body_Decl_List : List_Id := No_List;
1796 Param_Type : Node_Id;
1797
1798 begin
1799 if Nkind (Object_Definition (Ret_Obj)) = N_Identifier then
1800 Param_Type :=
1801 New_Copy (Object_Definition (Ret_Obj));
1802 else
1803 Param_Type :=
1804 New_Copy (Subtype_Mark (Object_Definition (Ret_Obj)));
1805 end if;
1806
1807 Append_To (Formal_List,
1808 Make_Parameter_Specification (Loc,
1809 Defining_Identifier =>
1810 Make_Defining_Identifier (Loc,
1811 Chars => Chars (Defining_Identifier (Ret_Obj))),
1812 In_Present => False,
1813 Out_Present => True,
1814 Null_Exclusion_Present => False,
1815 Parameter_Type => Param_Type));
1816
1817 Formal := First_Formal (Spec_Id);
1818
1819 -- Note that we copy the parameter type rather than creating
1820 -- a reference to it, because it may be a class-wide entity
1821 -- that will not be retrieved by name.
1822
1823 while Present (Formal) loop
1824 Append_To (Formal_List,
1825 Make_Parameter_Specification (Loc,
1826 Defining_Identifier =>
1827 Make_Defining_Identifier (Sloc (Formal),
1828 Chars => Chars (Formal)),
1829 In_Present => In_Present (Parent (Formal)),
1830 Out_Present => Out_Present (Parent (Formal)),
1831 Null_Exclusion_Present =>
1832 Null_Exclusion_Present (Parent (Formal)),
1833 Parameter_Type =>
1834 New_Copy_Tree (Parameter_Type (Parent (Formal))),
1835 Expression =>
1836 Copy_Separate_Tree (Expression (Parent (Formal)))));
1837
1838 Next_Formal (Formal);
1839 end loop;
1840
1841 Proc_Id := Make_Defining_Identifier (Loc, Chars => Subp_Name);
1842
1843 Proc_Spec :=
1844 Make_Procedure_Specification (Loc,
1845 Defining_Unit_Name => Proc_Id,
1846 Parameter_Specifications => Formal_List);
1847
1848 Decl_List := New_List;
1849
1850 Append_To (Decl_List,
1851 Make_Subprogram_Declaration (Loc, Proc_Spec));
1852
1853 -- Can_Convert_Unconstrained_Function checked that the function
1854 -- has no local declarations except implicit label declarations.
1855 -- Copy these declarations to the built procedure.
1856
1857 if Present (Declarations (N)) then
1858 Body_Decl_List := New_List;
1859
1860 declare
1861 D : Node_Id;
1862 New_D : Node_Id;
1863
1864 begin
1865 D := First (Declarations (N));
1866 while Present (D) loop
1867 pragma Assert (Nkind (D) = N_Implicit_Label_Declaration);
1868
1869 New_D :=
1870 Make_Implicit_Label_Declaration (Loc,
1871 Make_Defining_Identifier (Loc,
1872 Chars => Chars (Defining_Identifier (D))),
1873 Label_Construct => Empty);
1874 Append_To (Body_Decl_List, New_D);
1875
1876 Next (D);
1877 end loop;
1878 end;
1879 end if;
1880
1881 pragma Assert (Present (Handled_Statement_Sequence (Ret_Node)));
1882
1883 Proc_Body :=
1884 Make_Subprogram_Body (Loc,
1885 Specification => Copy_Separate_Tree (Proc_Spec),
1886 Declarations => Body_Decl_List,
1887 Handled_Statement_Sequence =>
1888 Copy_Separate_Tree (Handled_Statement_Sequence (Ret_Node)));
1889
1890 Set_Defining_Unit_Name (Specification (Proc_Body),
1891 Make_Defining_Identifier (Loc, Subp_Name));
1892
1893 Append_To (Decl_List, Proc_Body);
1894 end Build_Procedure;
1895
1896 -- Local variables
1897
1898 New_Obj : constant Node_Id := Copy_Separate_Tree (Ret_Obj);
1899 Blk_Stmt : Node_Id;
1900 Proc_Id : Entity_Id;
1901 Proc_Call : Node_Id;
1902
1903 -- Start of processing for Split_Unconstrained_Function
1904
1905 begin
1906 -- Build the associated procedure, analyze it and insert it before
1907 -- the function body N.
1908
1909 declare
1910 Scope : constant Entity_Id := Current_Scope;
1911 Decl_List : List_Id;
1912 begin
1913 Pop_Scope;
1914 Build_Procedure (Proc_Id, Decl_List);
1915 Insert_Actions (N, Decl_List);
1916 Set_Is_Inlined (Proc_Id);
1917 Push_Scope (Scope);
1918 end;
1919
1920 -- Build the call to the generated procedure
1921
1922 declare
1923 Actual_List : constant List_Id := New_List;
1924 Formal : Entity_Id;
1925
1926 begin
1927 Append_To (Actual_List,
1928 New_Occurrence_Of (Defining_Identifier (New_Obj), Loc));
1929
1930 Formal := First_Formal (Spec_Id);
1931 while Present (Formal) loop
1932 Append_To (Actual_List, New_Occurrence_Of (Formal, Loc));
1933
1934 -- Avoid spurious warning on unreferenced formals
1935
1936 Set_Referenced (Formal);
1937 Next_Formal (Formal);
1938 end loop;
1939
1940 Proc_Call :=
1941 Make_Procedure_Call_Statement (Loc,
1942 Name => New_Occurrence_Of (Proc_Id, Loc),
1943 Parameter_Associations => Actual_List);
1944 end;
1945
1946 -- Generate:
1947
1948 -- declare
1949 -- New_Obj : ...
1950 -- begin
1951 -- Proc (New_Obj, ...);
1952 -- return New_Obj;
1953 -- end;
1954
1955 Blk_Stmt :=
1956 Make_Block_Statement (Loc,
1957 Declarations => New_List (New_Obj),
1958 Handled_Statement_Sequence =>
1959 Make_Handled_Sequence_Of_Statements (Loc,
1960 Statements => New_List (
1961
1962 Proc_Call,
1963
1964 Make_Simple_Return_Statement (Loc,
1965 Expression =>
1966 New_Occurrence_Of
1967 (Defining_Identifier (New_Obj), Loc)))));
1968
1969 Rewrite (Ret_Node, Blk_Stmt);
1970 end Split_Unconstrained_Function;
1971
1972 -- Local variables
1973
1974 Decl : constant Node_Id := Unit_Declaration_Node (Spec_Id);
1975
1976 -- Start of processing for Check_And_Split_Unconstrained_Function
1977
1978 begin
1979 pragma Assert (Back_End_Inlining
1980 and then Ekind (Spec_Id) = E_Function
1981 and then Returns_Unconstrained_Type (Spec_Id)
1982 and then Comes_From_Source (Body_Id)
1983 and then (Has_Pragma_Inline_Always (Spec_Id)
1984 or else Optimization_Level > 0));
1985
1986 -- This routine must not be used in GNATprove mode since GNATprove
1987 -- relies on frontend inlining
1988
1989 pragma Assert (not GNATprove_Mode);
1990
1991 -- No need to split the function if we cannot generate the code
1992
1993 if Serious_Errors_Detected /= 0 then
1994 return;
1995 end if;
1996
1997 -- No action needed in stubs since the attribute Body_To_Inline
1998 -- is not available
1999
2000 if Nkind (Decl) = N_Subprogram_Body_Stub then
2001 return;
2002
2003 -- Cannot build the body to inline if the attribute is already set.
2004 -- This attribute may have been set if this is a subprogram renaming
2005 -- declarations (see Freeze.Build_Renamed_Body).
2006
2007 elsif Present (Body_To_Inline (Decl)) then
2008 return;
2009
2010 -- Check excluded declarations
2011
2012 elsif Present (Declarations (N))
2013 and then Has_Excluded_Declaration (Spec_Id, Declarations (N))
2014 then
2015 return;
2016
2017 -- Check excluded statements. There is no need to protect us against
2018 -- exception handlers since they are supported by the GCC backend.
2019
2020 elsif Present (Handled_Statement_Sequence (N))
2021 and then Has_Excluded_Statement
2022 (Spec_Id, Statements (Handled_Statement_Sequence (N)))
2023 then
2024 return;
2025 end if;
2026
2027 -- Build the body to inline only if really needed
2028
2029 if Can_Split_Unconstrained_Function (N) then
2030 Split_Unconstrained_Function (N, Spec_Id);
2031 Build_Body_To_Inline (N, Spec_Id);
2032 Set_Is_Inlined (Spec_Id);
2033 end if;
2034 end Check_And_Split_Unconstrained_Function;
2035
2036 -------------------------------------
2037 -- Check_Package_Body_For_Inlining --
2038 -------------------------------------
2039
2040 procedure Check_Package_Body_For_Inlining (N : Node_Id; P : Entity_Id) is
2041 Bname : Unit_Name_Type;
2042 E : Entity_Id;
2043 OK : Boolean;
2044
2045 begin
2046 -- Legacy implementation (relying on frontend inlining)
2047
2048 if not Back_End_Inlining
2049 and then Is_Compilation_Unit (P)
2050 and then not Is_Generic_Instance (P)
2051 then
2052 Bname := Get_Body_Name (Get_Unit_Name (Unit (N)));
2053
2054 E := First_Entity (P);
2055 while Present (E) loop
2056 if Has_Pragma_Inline_Always (E)
2057 or else (Has_Pragma_Inline (E) and Front_End_Inlining)
2058 then
2059 if not Is_Loaded (Bname) then
2060 Load_Needed_Body (N, OK);
2061
2062 if OK then
2063
2064 -- Check we are not trying to inline a parent whose body
2065 -- depends on a child, when we are compiling the body of
2066 -- the child. Otherwise we have a potential elaboration
2067 -- circularity with inlined subprograms and with
2068 -- Taft-Amendment types.
2069
2070 declare
2071 Comp : Node_Id; -- Body just compiled
2072 Child_Spec : Entity_Id; -- Spec of main unit
2073 Ent : Entity_Id; -- For iteration
2074 With_Clause : Node_Id; -- Context of body.
2075
2076 begin
2077 if Nkind (Unit (Cunit (Main_Unit))) = N_Package_Body
2078 and then Present (Body_Entity (P))
2079 then
2080 Child_Spec :=
2081 Defining_Entity
2082 ((Unit (Library_Unit (Cunit (Main_Unit)))));
2083
2084 Comp :=
2085 Parent (Unit_Declaration_Node (Body_Entity (P)));
2086
2087 -- Check whether the context of the body just
2088 -- compiled includes a child of itself, and that
2089 -- child is the spec of the main compilation.
2090
2091 With_Clause := First (Context_Items (Comp));
2092 while Present (With_Clause) loop
2093 if Nkind (With_Clause) = N_With_Clause
2094 and then
2095 Scope (Entity (Name (With_Clause))) = P
2096 and then
2097 Entity (Name (With_Clause)) = Child_Spec
2098 then
2099 Error_Msg_Node_2 := Child_Spec;
2100 Error_Msg_NE
2101 ("body of & depends on child unit&??",
2102 With_Clause, P);
2103 Error_Msg_N
2104 ("\subprograms in body cannot be inlined??",
2105 With_Clause);
2106
2107 -- Disable further inlining from this unit,
2108 -- and keep Taft-amendment types incomplete.
2109
2110 Ent := First_Entity (P);
2111 while Present (Ent) loop
2112 if Is_Type (Ent)
2113 and then Has_Completion_In_Body (Ent)
2114 then
2115 Set_Full_View (Ent, Empty);
2116
2117 elsif Is_Subprogram (Ent) then
2118 Set_Is_Inlined (Ent, False);
2119 end if;
2120
2121 Next_Entity (Ent);
2122 end loop;
2123
2124 return;
2125 end if;
2126
2127 Next (With_Clause);
2128 end loop;
2129 end if;
2130 end;
2131
2132 elsif Ineffective_Inline_Warnings then
2133 Error_Msg_Unit_1 := Bname;
2134 Error_Msg_N
2135 ("unable to inline subprograms defined in $??", P);
2136 Error_Msg_N ("\body not found??", P);
2137 return;
2138 end if;
2139 end if;
2140
2141 return;
2142 end if;
2143
2144 Next_Entity (E);
2145 end loop;
2146 end if;
2147 end Check_Package_Body_For_Inlining;
2148
2149 --------------------
2150 -- Cleanup_Scopes --
2151 --------------------
2152
2153 procedure Cleanup_Scopes is
2154 Elmt : Elmt_Id;
2155 Decl : Node_Id;
2156 Scop : Entity_Id;
2157
2158 begin
2159 Elmt := First_Elmt (To_Clean);
2160 while Present (Elmt) loop
2161 Scop := Node (Elmt);
2162
2163 if Ekind (Scop) = E_Entry then
2164 Scop := Protected_Body_Subprogram (Scop);
2165
2166 elsif Is_Subprogram (Scop)
2167 and then Is_Protected_Type (Scope (Scop))
2168 and then Present (Protected_Body_Subprogram (Scop))
2169 then
2170 -- If a protected operation contains an instance, its cleanup
2171 -- operations have been delayed, and the subprogram has been
2172 -- rewritten in the expansion of the enclosing protected body. It
2173 -- is the corresponding subprogram that may require the cleanup
2174 -- operations, so propagate the information that triggers cleanup
2175 -- activity.
2176
2177 Set_Uses_Sec_Stack
2178 (Protected_Body_Subprogram (Scop),
2179 Uses_Sec_Stack (Scop));
2180
2181 Scop := Protected_Body_Subprogram (Scop);
2182 end if;
2183
2184 if Ekind (Scop) = E_Block then
2185 Decl := Parent (Block_Node (Scop));
2186
2187 else
2188 Decl := Unit_Declaration_Node (Scop);
2189
2190 if Nkind_In (Decl, N_Subprogram_Declaration,
2191 N_Task_Type_Declaration,
2192 N_Subprogram_Body_Stub)
2193 then
2194 Decl := Unit_Declaration_Node (Corresponding_Body (Decl));
2195 end if;
2196 end if;
2197
2198 Push_Scope (Scop);
2199 Expand_Cleanup_Actions (Decl);
2200 End_Scope;
2201
2202 Elmt := Next_Elmt (Elmt);
2203 end loop;
2204 end Cleanup_Scopes;
2205
2206 -------------------------
2207 -- Expand_Inlined_Call --
2208 -------------------------
2209
2210 procedure Expand_Inlined_Call
2211 (N : Node_Id;
2212 Subp : Entity_Id;
2213 Orig_Subp : Entity_Id)
2214 is
2215 Loc : constant Source_Ptr := Sloc (N);
2216 Is_Predef : constant Boolean :=
2217 Is_Predefined_Unit (Get_Source_Unit (Subp));
2218 Orig_Bod : constant Node_Id :=
2219 Body_To_Inline (Unit_Declaration_Node (Subp));
2220
2221 Blk : Node_Id;
2222 Decl : Node_Id;
2223 Decls : constant List_Id := New_List;
2224 Exit_Lab : Entity_Id := Empty;
2225 F : Entity_Id;
2226 A : Node_Id;
2227 Lab_Decl : Node_Id;
2228 Lab_Id : Node_Id;
2229 New_A : Node_Id;
2230 Num_Ret : Nat := 0;
2231 Ret_Type : Entity_Id;
2232
2233 Targ : Node_Id;
2234 -- The target of the call. If context is an assignment statement then
2235 -- this is the left-hand side of the assignment, else it is a temporary
2236 -- to which the return value is assigned prior to rewriting the call.
2237
2238 Targ1 : Node_Id := Empty;
2239 -- A separate target used when the return type is unconstrained
2240
2241 Temp : Entity_Id;
2242 Temp_Typ : Entity_Id;
2243
2244 Return_Object : Entity_Id := Empty;
2245 -- Entity in declaration in an extended_return_statement
2246
2247 Is_Unc : Boolean;
2248 Is_Unc_Decl : Boolean;
2249 -- If the type returned by the function is unconstrained and the call
2250 -- can be inlined, special processing is required.
2251
2252 procedure Declare_Postconditions_Result;
2253 -- When generating C code, declare _Result, which may be used in the
2254 -- inlined _Postconditions procedure to verify the return value.
2255
2256 procedure Make_Exit_Label;
2257 -- Build declaration for exit label to be used in Return statements,
2258 -- sets Exit_Lab (the label node) and Lab_Decl (corresponding implicit
2259 -- declaration). Does nothing if Exit_Lab already set.
2260
2261 function Process_Formals (N : Node_Id) return Traverse_Result;
2262 -- Replace occurrence of a formal with the corresponding actual, or the
2263 -- thunk generated for it. Replace a return statement with an assignment
2264 -- to the target of the call, with appropriate conversions if needed.
2265
2266 function Process_Sloc (Nod : Node_Id) return Traverse_Result;
2267 -- If the call being expanded is that of an internal subprogram, set the
2268 -- sloc of the generated block to that of the call itself, so that the
2269 -- expansion is skipped by the "next" command in gdb. Same processing
2270 -- for a subprogram in a predefined file, e.g. Ada.Tags. If
2271 -- Debug_Generated_Code is true, suppress this change to simplify our
2272 -- own development. Same in GNATprove mode, to ensure that warnings and
2273 -- diagnostics point to the proper location.
2274
2275 procedure Reset_Dispatching_Calls (N : Node_Id);
2276 -- In subtree N search for occurrences of dispatching calls that use the
2277 -- Ada 2005 Object.Operation notation and the object is a formal of the
2278 -- inlined subprogram. Reset the entity associated with Operation in all
2279 -- the found occurrences.
2280
2281 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id);
2282 -- If the function body is a single expression, replace call with
2283 -- expression, else insert block appropriately.
2284
2285 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id);
2286 -- If procedure body has no local variables, inline body without
2287 -- creating block, otherwise rewrite call with block.
2288
2289 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean;
2290 -- Determine whether a formal parameter is used only once in Orig_Bod
2291
2292 -----------------------------------
2293 -- Declare_Postconditions_Result --
2294 -----------------------------------
2295
2296 procedure Declare_Postconditions_Result is
2297 Enclosing_Subp : constant Entity_Id := Scope (Subp);
2298
2299 begin
2300 pragma Assert
2301 (Modify_Tree_For_C
2302 and then Is_Subprogram (Enclosing_Subp)
2303 and then Present (Postconditions_Proc (Enclosing_Subp)));
2304
2305 if Ekind (Enclosing_Subp) = E_Function then
2306 if Nkind (First (Parameter_Associations (N))) in
2307 N_Numeric_Or_String_Literal
2308 then
2309 Append_To (Declarations (Blk),
2310 Make_Object_Declaration (Loc,
2311 Defining_Identifier =>
2312 Make_Defining_Identifier (Loc, Name_uResult),
2313 Constant_Present => True,
2314 Object_Definition =>
2315 New_Occurrence_Of (Etype (Enclosing_Subp), Loc),
2316 Expression =>
2317 New_Copy_Tree (First (Parameter_Associations (N)))));
2318 else
2319 Append_To (Declarations (Blk),
2320 Make_Object_Renaming_Declaration (Loc,
2321 Defining_Identifier =>
2322 Make_Defining_Identifier (Loc, Name_uResult),
2323 Subtype_Mark =>
2324 New_Occurrence_Of (Etype (Enclosing_Subp), Loc),
2325 Name =>
2326 New_Copy_Tree (First (Parameter_Associations (N)))));
2327 end if;
2328 end if;
2329 end Declare_Postconditions_Result;
2330
2331 ---------------------
2332 -- Make_Exit_Label --
2333 ---------------------
2334
2335 procedure Make_Exit_Label is
2336 Lab_Ent : Entity_Id;
2337 begin
2338 if No (Exit_Lab) then
2339 Lab_Ent := Make_Temporary (Loc, 'L');
2340 Lab_Id := New_Occurrence_Of (Lab_Ent, Loc);
2341 Exit_Lab := Make_Label (Loc, Lab_Id);
2342 Lab_Decl :=
2343 Make_Implicit_Label_Declaration (Loc,
2344 Defining_Identifier => Lab_Ent,
2345 Label_Construct => Exit_Lab);
2346 end if;
2347 end Make_Exit_Label;
2348
2349 ---------------------
2350 -- Process_Formals --
2351 ---------------------
2352
2353 function Process_Formals (N : Node_Id) return Traverse_Result is
2354 A : Entity_Id;
2355 E : Entity_Id;
2356 Ret : Node_Id;
2357
2358 begin
2359 if Is_Entity_Name (N) and then Present (Entity (N)) then
2360 E := Entity (N);
2361
2362 if Is_Formal (E) and then Scope (E) = Subp then
2363 A := Renamed_Object (E);
2364
2365 -- Rewrite the occurrence of the formal into an occurrence of
2366 -- the actual. Also establish visibility on the proper view of
2367 -- the actual's subtype for the body's context (if the actual's
2368 -- subtype is private at the call point but its full view is
2369 -- visible to the body, then the inlined tree here must be
2370 -- analyzed with the full view).
2371
2372 if Is_Entity_Name (A) then
2373 Rewrite (N, New_Occurrence_Of (Entity (A), Sloc (N)));
2374 Check_Private_View (N);
2375
2376 elsif Nkind (A) = N_Defining_Identifier then
2377 Rewrite (N, New_Occurrence_Of (A, Sloc (N)));
2378 Check_Private_View (N);
2379
2380 -- Numeric literal
2381
2382 else
2383 Rewrite (N, New_Copy (A));
2384 end if;
2385 end if;
2386
2387 return Skip;
2388
2389 elsif Is_Entity_Name (N)
2390 and then Present (Return_Object)
2391 and then Chars (N) = Chars (Return_Object)
2392 then
2393 -- Occurrence within an extended return statement. The return
2394 -- object is local to the body been inlined, and thus the generic
2395 -- copy is not analyzed yet, so we match by name, and replace it
2396 -- with target of call.
2397
2398 if Nkind (Targ) = N_Defining_Identifier then
2399 Rewrite (N, New_Occurrence_Of (Targ, Loc));
2400 else
2401 Rewrite (N, New_Copy_Tree (Targ));
2402 end if;
2403
2404 return Skip;
2405
2406 elsif Nkind (N) = N_Simple_Return_Statement then
2407 if No (Expression (N)) then
2408 Num_Ret := Num_Ret + 1;
2409 Make_Exit_Label;
2410 Rewrite (N,
2411 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2412
2413 else
2414 if Nkind (Parent (N)) = N_Handled_Sequence_Of_Statements
2415 and then Nkind (Parent (Parent (N))) = N_Subprogram_Body
2416 then
2417 -- Function body is a single expression. No need for
2418 -- exit label.
2419
2420 null;
2421
2422 else
2423 Num_Ret := Num_Ret + 1;
2424 Make_Exit_Label;
2425 end if;
2426
2427 -- Because of the presence of private types, the views of the
2428 -- expression and the context may be different, so place an
2429 -- unchecked conversion to the context type to avoid spurious
2430 -- errors, e.g. when the expression is a numeric literal and
2431 -- the context is private. If the expression is an aggregate,
2432 -- use a qualified expression, because an aggregate is not a
2433 -- legal argument of a conversion. Ditto for numeric literals
2434 -- and attributes that yield a universal type, because those
2435 -- must be resolved to a specific type.
2436
2437 if Nkind_In (Expression (N), N_Aggregate, N_Null)
2438 or else Yields_Universal_Type (Expression (N))
2439 then
2440 Ret :=
2441 Make_Qualified_Expression (Sloc (N),
2442 Subtype_Mark => New_Occurrence_Of (Ret_Type, Sloc (N)),
2443 Expression => Relocate_Node (Expression (N)));
2444 else
2445 Ret :=
2446 Unchecked_Convert_To
2447 (Ret_Type, Relocate_Node (Expression (N)));
2448 end if;
2449
2450 if Nkind (Targ) = N_Defining_Identifier then
2451 Rewrite (N,
2452 Make_Assignment_Statement (Loc,
2453 Name => New_Occurrence_Of (Targ, Loc),
2454 Expression => Ret));
2455 else
2456 Rewrite (N,
2457 Make_Assignment_Statement (Loc,
2458 Name => New_Copy (Targ),
2459 Expression => Ret));
2460 end if;
2461
2462 Set_Assignment_OK (Name (N));
2463
2464 if Present (Exit_Lab) then
2465 Insert_After (N,
2466 Make_Goto_Statement (Loc, Name => New_Copy (Lab_Id)));
2467 end if;
2468 end if;
2469
2470 return OK;
2471
2472 -- An extended return becomes a block whose first statement is the
2473 -- assignment of the initial expression of the return object to the
2474 -- target of the call itself.
2475
2476 elsif Nkind (N) = N_Extended_Return_Statement then
2477 declare
2478 Return_Decl : constant Entity_Id :=
2479 First (Return_Object_Declarations (N));
2480 Assign : Node_Id;
2481
2482 begin
2483 Return_Object := Defining_Identifier (Return_Decl);
2484
2485 if Present (Expression (Return_Decl)) then
2486 if Nkind (Targ) = N_Defining_Identifier then
2487 Assign :=
2488 Make_Assignment_Statement (Loc,
2489 Name => New_Occurrence_Of (Targ, Loc),
2490 Expression => Expression (Return_Decl));
2491 else
2492 Assign :=
2493 Make_Assignment_Statement (Loc,
2494 Name => New_Copy (Targ),
2495 Expression => Expression (Return_Decl));
2496 end if;
2497
2498 Set_Assignment_OK (Name (Assign));
2499
2500 if No (Handled_Statement_Sequence (N)) then
2501 Set_Handled_Statement_Sequence (N,
2502 Make_Handled_Sequence_Of_Statements (Loc,
2503 Statements => New_List));
2504 end if;
2505
2506 Prepend (Assign,
2507 Statements (Handled_Statement_Sequence (N)));
2508 end if;
2509
2510 Rewrite (N,
2511 Make_Block_Statement (Loc,
2512 Handled_Statement_Sequence =>
2513 Handled_Statement_Sequence (N)));
2514
2515 return OK;
2516 end;
2517
2518 -- Remove pragma Unreferenced since it may refer to formals that
2519 -- are not visible in the inlined body, and in any case we will
2520 -- not be posting warnings on the inlined body so it is unneeded.
2521
2522 elsif Nkind (N) = N_Pragma
2523 and then Pragma_Name (N) = Name_Unreferenced
2524 then
2525 Rewrite (N, Make_Null_Statement (Sloc (N)));
2526 return OK;
2527
2528 else
2529 return OK;
2530 end if;
2531 end Process_Formals;
2532
2533 procedure Replace_Formals is new Traverse_Proc (Process_Formals);
2534
2535 ------------------
2536 -- Process_Sloc --
2537 ------------------
2538
2539 function Process_Sloc (Nod : Node_Id) return Traverse_Result is
2540 begin
2541 if not Debug_Generated_Code then
2542 Set_Sloc (Nod, Sloc (N));
2543 Set_Comes_From_Source (Nod, False);
2544 end if;
2545
2546 return OK;
2547 end Process_Sloc;
2548
2549 procedure Reset_Slocs is new Traverse_Proc (Process_Sloc);
2550
2551 ------------------------------
2552 -- Reset_Dispatching_Calls --
2553 ------------------------------
2554
2555 procedure Reset_Dispatching_Calls (N : Node_Id) is
2556
2557 function Do_Reset (N : Node_Id) return Traverse_Result;
2558 -- Comment required ???
2559
2560 --------------
2561 -- Do_Reset --
2562 --------------
2563
2564 function Do_Reset (N : Node_Id) return Traverse_Result is
2565 begin
2566 if Nkind (N) = N_Procedure_Call_Statement
2567 and then Nkind (Name (N)) = N_Selected_Component
2568 and then Nkind (Prefix (Name (N))) = N_Identifier
2569 and then Is_Formal (Entity (Prefix (Name (N))))
2570 and then Is_Dispatching_Operation
2571 (Entity (Selector_Name (Name (N))))
2572 then
2573 Set_Entity (Selector_Name (Name (N)), Empty);
2574 end if;
2575
2576 return OK;
2577 end Do_Reset;
2578
2579 function Do_Reset_Calls is new Traverse_Func (Do_Reset);
2580
2581 -- Local variables
2582
2583 Dummy : constant Traverse_Result := Do_Reset_Calls (N);
2584 pragma Unreferenced (Dummy);
2585
2586 -- Start of processing for Reset_Dispatching_Calls
2587
2588 begin
2589 null;
2590 end Reset_Dispatching_Calls;
2591
2592 ---------------------------
2593 -- Rewrite_Function_Call --
2594 ---------------------------
2595
2596 procedure Rewrite_Function_Call (N : Node_Id; Blk : Node_Id) is
2597 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2598 Fst : constant Node_Id := First (Statements (HSS));
2599
2600 begin
2601 -- Optimize simple case: function body is a single return statement,
2602 -- which has been expanded into an assignment.
2603
2604 if Is_Empty_List (Declarations (Blk))
2605 and then Nkind (Fst) = N_Assignment_Statement
2606 and then No (Next (Fst))
2607 then
2608 -- The function call may have been rewritten as the temporary
2609 -- that holds the result of the call, in which case remove the
2610 -- now useless declaration.
2611
2612 if Nkind (N) = N_Identifier
2613 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2614 then
2615 Rewrite (Parent (Entity (N)), Make_Null_Statement (Loc));
2616 end if;
2617
2618 Rewrite (N, Expression (Fst));
2619
2620 elsif Nkind (N) = N_Identifier
2621 and then Nkind (Parent (Entity (N))) = N_Object_Declaration
2622 then
2623 -- The block assigns the result of the call to the temporary
2624
2625 Insert_After (Parent (Entity (N)), Blk);
2626
2627 -- If the context is an assignment, and the left-hand side is free of
2628 -- side-effects, the replacement is also safe.
2629 -- Can this be generalized further???
2630
2631 elsif Nkind (Parent (N)) = N_Assignment_Statement
2632 and then
2633 (Is_Entity_Name (Name (Parent (N)))
2634 or else
2635 (Nkind (Name (Parent (N))) = N_Explicit_Dereference
2636 and then Is_Entity_Name (Prefix (Name (Parent (N)))))
2637
2638 or else
2639 (Nkind (Name (Parent (N))) = N_Selected_Component
2640 and then Is_Entity_Name (Prefix (Name (Parent (N))))))
2641 then
2642 -- Replace assignment with the block
2643
2644 declare
2645 Original_Assignment : constant Node_Id := Parent (N);
2646
2647 begin
2648 -- Preserve the original assignment node to keep the complete
2649 -- assignment subtree consistent enough for Analyze_Assignment
2650 -- to proceed (specifically, the original Lhs node must still
2651 -- have an assignment statement as its parent).
2652
2653 -- We cannot rely on Original_Node to go back from the block
2654 -- node to the assignment node, because the assignment might
2655 -- already be a rewrite substitution.
2656
2657 Discard_Node (Relocate_Node (Original_Assignment));
2658 Rewrite (Original_Assignment, Blk);
2659 end;
2660
2661 elsif Nkind (Parent (N)) = N_Object_Declaration then
2662
2663 -- A call to a function which returns an unconstrained type
2664 -- found in the expression initializing an object-declaration is
2665 -- expanded into a procedure call which must be added after the
2666 -- object declaration.
2667
2668 if Is_Unc_Decl and Back_End_Inlining then
2669 Insert_Action_After (Parent (N), Blk);
2670 else
2671 Set_Expression (Parent (N), Empty);
2672 Insert_After (Parent (N), Blk);
2673 end if;
2674
2675 elsif Is_Unc and then not Back_End_Inlining then
2676 Insert_Before (Parent (N), Blk);
2677 end if;
2678 end Rewrite_Function_Call;
2679
2680 ----------------------------
2681 -- Rewrite_Procedure_Call --
2682 ----------------------------
2683
2684 procedure Rewrite_Procedure_Call (N : Node_Id; Blk : Node_Id) is
2685 HSS : constant Node_Id := Handled_Statement_Sequence (Blk);
2686
2687 begin
2688 -- If there is a transient scope for N, this will be the scope of the
2689 -- actions for N, and the statements in Blk need to be within this
2690 -- scope. For example, they need to have visibility on the constant
2691 -- declarations created for the formals.
2692
2693 -- If N needs no transient scope, and if there are no declarations in
2694 -- the inlined body, we can do a little optimization and insert the
2695 -- statements for the body directly after N, and rewrite N to a
2696 -- null statement, instead of rewriting N into a full-blown block
2697 -- statement.
2698
2699 if not Scope_Is_Transient
2700 and then Is_Empty_List (Declarations (Blk))
2701 then
2702 Insert_List_After (N, Statements (HSS));
2703 Rewrite (N, Make_Null_Statement (Loc));
2704 else
2705 Rewrite (N, Blk);
2706 end if;
2707 end Rewrite_Procedure_Call;
2708
2709 -------------------------
2710 -- Formal_Is_Used_Once --
2711 -------------------------
2712
2713 function Formal_Is_Used_Once (Formal : Entity_Id) return Boolean is
2714 Use_Counter : Int := 0;
2715
2716 function Count_Uses (N : Node_Id) return Traverse_Result;
2717 -- Traverse the tree and count the uses of the formal parameter.
2718 -- In this case, for optimization purposes, we do not need to
2719 -- continue the traversal once more than one use is encountered.
2720
2721 ----------------
2722 -- Count_Uses --
2723 ----------------
2724
2725 function Count_Uses (N : Node_Id) return Traverse_Result is
2726 begin
2727 -- The original node is an identifier
2728
2729 if Nkind (N) = N_Identifier
2730 and then Present (Entity (N))
2731
2732 -- Original node's entity points to the one in the copied body
2733
2734 and then Nkind (Entity (N)) = N_Identifier
2735 and then Present (Entity (Entity (N)))
2736
2737 -- The entity of the copied node is the formal parameter
2738
2739 and then Entity (Entity (N)) = Formal
2740 then
2741 Use_Counter := Use_Counter + 1;
2742
2743 if Use_Counter > 1 then
2744
2745 -- Denote more than one use and abandon the traversal
2746
2747 Use_Counter := 2;
2748 return Abandon;
2749
2750 end if;
2751 end if;
2752
2753 return OK;
2754 end Count_Uses;
2755
2756 procedure Count_Formal_Uses is new Traverse_Proc (Count_Uses);
2757
2758 -- Start of processing for Formal_Is_Used_Once
2759
2760 begin
2761 Count_Formal_Uses (Orig_Bod);
2762 return Use_Counter = 1;
2763 end Formal_Is_Used_Once;
2764
2765 -- Start of processing for Expand_Inlined_Call
2766
2767 begin
2768 -- Initializations for old/new semantics
2769
2770 if not Back_End_Inlining then
2771 Is_Unc := Is_Array_Type (Etype (Subp))
2772 and then not Is_Constrained (Etype (Subp));
2773 Is_Unc_Decl := False;
2774 else
2775 Is_Unc := Returns_Unconstrained_Type (Subp)
2776 and then Optimization_Level > 0;
2777 Is_Unc_Decl := Nkind (Parent (N)) = N_Object_Declaration
2778 and then Is_Unc;
2779 end if;
2780
2781 -- Check for an illegal attempt to inline a recursive procedure. If the
2782 -- subprogram has parameters this is detected when trying to supply a
2783 -- binding for parameters that already have one. For parameterless
2784 -- subprograms this must be done explicitly.
2785
2786 if In_Open_Scopes (Subp) then
2787 Cannot_Inline
2788 ("cannot inline call to recursive subprogram?", N, Subp);
2789 Set_Is_Inlined (Subp, False);
2790 return;
2791
2792 -- Skip inlining if this is not a true inlining since the attribute
2793 -- Body_To_Inline is also set for renamings (see sinfo.ads). For a
2794 -- true inlining, Orig_Bod has code rather than being an entity.
2795
2796 elsif Nkind (Orig_Bod) in N_Entity then
2797 return;
2798
2799 -- Skip inlining if the function returns an unconstrained type using
2800 -- an extended return statement since this part of the new inlining
2801 -- model which is not yet supported by the current implementation. ???
2802
2803 elsif Is_Unc
2804 and then
2805 Nkind (First (Statements (Handled_Statement_Sequence (Orig_Bod)))) =
2806 N_Extended_Return_Statement
2807 and then not Back_End_Inlining
2808 then
2809 return;
2810 end if;
2811
2812 if Nkind (Orig_Bod) = N_Defining_Identifier
2813 or else Nkind (Orig_Bod) = N_Defining_Operator_Symbol
2814 then
2815 -- Subprogram is renaming_as_body. Calls occurring after the renaming
2816 -- can be replaced with calls to the renamed entity directly, because
2817 -- the subprograms are subtype conformant. If the renamed subprogram
2818 -- is an inherited operation, we must redo the expansion because
2819 -- implicit conversions may be needed. Similarly, if the renamed
2820 -- entity is inlined, expand the call for further optimizations.
2821
2822 Set_Name (N, New_Occurrence_Of (Orig_Bod, Loc));
2823
2824 if Present (Alias (Orig_Bod)) or else Is_Inlined (Orig_Bod) then
2825 Expand_Call (N);
2826 end if;
2827
2828 return;
2829 end if;
2830
2831 -- Register the call in the list of inlined calls
2832
2833 Append_New_Elmt (N, To => Inlined_Calls);
2834
2835 -- Use generic machinery to copy body of inlined subprogram, as if it
2836 -- were an instantiation, resetting source locations appropriately, so
2837 -- that nested inlined calls appear in the main unit.
2838
2839 Save_Env (Subp, Empty);
2840 Set_Copied_Sloc_For_Inlined_Body (N, Defining_Entity (Orig_Bod));
2841
2842 -- Old semantics
2843
2844 if not Back_End_Inlining then
2845 declare
2846 Bod : Node_Id;
2847
2848 begin
2849 Bod := Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2850 Blk :=
2851 Make_Block_Statement (Loc,
2852 Declarations => Declarations (Bod),
2853 Handled_Statement_Sequence =>
2854 Handled_Statement_Sequence (Bod));
2855
2856 if No (Declarations (Bod)) then
2857 Set_Declarations (Blk, New_List);
2858 end if;
2859
2860 -- When generating C code, declare _Result, which may be used to
2861 -- verify the return value.
2862
2863 if Modify_Tree_For_C
2864 and then Nkind (N) = N_Procedure_Call_Statement
2865 and then Chars (Name (N)) = Name_uPostconditions
2866 then
2867 Declare_Postconditions_Result;
2868 end if;
2869
2870 -- For the unconstrained case, capture the name of the local
2871 -- variable that holds the result. This must be the first
2872 -- declaration in the block, because its bounds cannot depend
2873 -- on local variables. Otherwise there is no way to declare the
2874 -- result outside of the block. Needless to say, in general the
2875 -- bounds will depend on the actuals in the call.
2876
2877 -- If the context is an assignment statement, as is the case
2878 -- for the expansion of an extended return, the left-hand side
2879 -- provides bounds even if the return type is unconstrained.
2880
2881 if Is_Unc then
2882 declare
2883 First_Decl : Node_Id;
2884
2885 begin
2886 First_Decl := First (Declarations (Blk));
2887
2888 if Nkind (First_Decl) /= N_Object_Declaration then
2889 return;
2890 end if;
2891
2892 if Nkind (Parent (N)) /= N_Assignment_Statement then
2893 Targ1 := Defining_Identifier (First_Decl);
2894 else
2895 Targ1 := Name (Parent (N));
2896 end if;
2897 end;
2898 end if;
2899 end;
2900
2901 -- New semantics
2902
2903 else
2904 declare
2905 Bod : Node_Id;
2906
2907 begin
2908 -- General case
2909
2910 if not Is_Unc then
2911 Bod :=
2912 Copy_Generic_Node (Orig_Bod, Empty, Instantiating => True);
2913 Blk :=
2914 Make_Block_Statement (Loc,
2915 Declarations => Declarations (Bod),
2916 Handled_Statement_Sequence =>
2917 Handled_Statement_Sequence (Bod));
2918
2919 -- Inline a call to a function that returns an unconstrained type.
2920 -- The semantic analyzer checked that frontend-inlined functions
2921 -- returning unconstrained types have no declarations and have
2922 -- a single extended return statement. As part of its processing
2923 -- the function was split into two subprograms: a procedure P' and
2924 -- a function F' that has a block with a call to procedure P' (see
2925 -- Split_Unconstrained_Function).
2926
2927 else
2928 pragma Assert
2929 (Nkind
2930 (First
2931 (Statements (Handled_Statement_Sequence (Orig_Bod)))) =
2932 N_Block_Statement);
2933
2934 declare
2935 Blk_Stmt : constant Node_Id :=
2936 First (Statements (Handled_Statement_Sequence (Orig_Bod)));
2937 First_Stmt : constant Node_Id :=
2938 First (Statements (Handled_Statement_Sequence (Blk_Stmt)));
2939 Second_Stmt : constant Node_Id := Next (First_Stmt);
2940
2941 begin
2942 pragma Assert
2943 (Nkind (First_Stmt) = N_Procedure_Call_Statement
2944 and then Nkind (Second_Stmt) = N_Simple_Return_Statement
2945 and then No (Next (Second_Stmt)));
2946
2947 Bod :=
2948 Copy_Generic_Node
2949 (First
2950 (Statements (Handled_Statement_Sequence (Orig_Bod))),
2951 Empty, Instantiating => True);
2952 Blk := Bod;
2953
2954 -- Capture the name of the local variable that holds the
2955 -- result. This must be the first declaration in the block,
2956 -- because its bounds cannot depend on local variables.
2957 -- Otherwise there is no way to declare the result outside
2958 -- of the block. Needless to say, in general the bounds will
2959 -- depend on the actuals in the call.
2960
2961 if Nkind (Parent (N)) /= N_Assignment_Statement then
2962 Targ1 := Defining_Identifier (First (Declarations (Blk)));
2963
2964 -- If the context is an assignment statement, as is the case
2965 -- for the expansion of an extended return, the left-hand
2966 -- side provides bounds even if the return type is
2967 -- unconstrained.
2968
2969 else
2970 Targ1 := Name (Parent (N));
2971 end if;
2972 end;
2973 end if;
2974
2975 if No (Declarations (Bod)) then
2976 Set_Declarations (Blk, New_List);
2977 end if;
2978 end;
2979 end if;
2980
2981 -- If this is a derived function, establish the proper return type
2982
2983 if Present (Orig_Subp) and then Orig_Subp /= Subp then
2984 Ret_Type := Etype (Orig_Subp);
2985 else
2986 Ret_Type := Etype (Subp);
2987 end if;
2988
2989 -- Create temporaries for the actuals that are expressions, or that are
2990 -- scalars and require copying to preserve semantics.
2991
2992 F := First_Formal (Subp);
2993 A := First_Actual (N);
2994 while Present (F) loop
2995 if Present (Renamed_Object (F)) then
2996
2997 -- If expander is active, it is an error to try to inline a
2998 -- recursive program. In GNATprove mode, just indicate that the
2999 -- inlining will not happen, and mark the subprogram as not always
3000 -- inlined.
3001
3002 if GNATprove_Mode then
3003 Cannot_Inline
3004 ("cannot inline call to recursive subprogram?", N, Subp);
3005 Set_Is_Inlined_Always (Subp, False);
3006 else
3007 Error_Msg_N
3008 ("cannot inline call to recursive subprogram", N);
3009 end if;
3010
3011 return;
3012 end if;
3013
3014 -- Reset Last_Assignment for any parameters of mode out or in out, to
3015 -- prevent spurious warnings about overwriting for assignments to the
3016 -- formal in the inlined code.
3017
3018 if Is_Entity_Name (A) and then Ekind (F) /= E_In_Parameter then
3019 Set_Last_Assignment (Entity (A), Empty);
3020 end if;
3021
3022 -- If the argument may be a controlling argument in a call within
3023 -- the inlined body, we must preserve its classwide nature to insure
3024 -- that dynamic dispatching take place subsequently. If the formal
3025 -- has a constraint it must be preserved to retain the semantics of
3026 -- the body.
3027
3028 if Is_Class_Wide_Type (Etype (F))
3029 or else (Is_Access_Type (Etype (F))
3030 and then Is_Class_Wide_Type (Designated_Type (Etype (F))))
3031 then
3032 Temp_Typ := Etype (F);
3033
3034 elsif Base_Type (Etype (F)) = Base_Type (Etype (A))
3035 and then Etype (F) /= Base_Type (Etype (F))
3036 and then Is_Constrained (Etype (F))
3037 then
3038 Temp_Typ := Etype (F);
3039
3040 else
3041 Temp_Typ := Etype (A);
3042 end if;
3043
3044 -- If the actual is a simple name or a literal, no need to
3045 -- create a temporary, object can be used directly.
3046
3047 -- If the actual is a literal and the formal has its address taken,
3048 -- we cannot pass the literal itself as an argument, so its value
3049 -- must be captured in a temporary. Skip this optimization in
3050 -- GNATprove mode, to make sure any check on a type conversion
3051 -- will be issued.
3052
3053 if (Is_Entity_Name (A)
3054 and then
3055 (not Is_Scalar_Type (Etype (A))
3056 or else Ekind (Entity (A)) = E_Enumeration_Literal)
3057 and then not GNATprove_Mode)
3058
3059 -- When the actual is an identifier and the corresponding formal is
3060 -- used only once in the original body, the formal can be substituted
3061 -- directly with the actual parameter. Skip this optimization in
3062 -- GNATprove mode, to make sure any check on a type conversion
3063 -- will be issued.
3064
3065 or else
3066 (Nkind (A) = N_Identifier
3067 and then Formal_Is_Used_Once (F)
3068 and then not GNATprove_Mode)
3069
3070 or else
3071 (Nkind_In (A, N_Real_Literal,
3072 N_Integer_Literal,
3073 N_Character_Literal)
3074 and then not Address_Taken (F))
3075 then
3076 if Etype (F) /= Etype (A) then
3077 Set_Renamed_Object
3078 (F, Unchecked_Convert_To (Etype (F), Relocate_Node (A)));
3079 else
3080 Set_Renamed_Object (F, A);
3081 end if;
3082
3083 else
3084 Temp := Make_Temporary (Loc, 'C');
3085
3086 -- If the actual for an in/in-out parameter is a view conversion,
3087 -- make it into an unchecked conversion, given that an untagged
3088 -- type conversion is not a proper object for a renaming.
3089
3090 -- In-out conversions that involve real conversions have already
3091 -- been transformed in Expand_Actuals.
3092
3093 if Nkind (A) = N_Type_Conversion
3094 and then Ekind (F) /= E_In_Parameter
3095 then
3096 New_A :=
3097 Make_Unchecked_Type_Conversion (Loc,
3098 Subtype_Mark => New_Occurrence_Of (Etype (F), Loc),
3099 Expression => Relocate_Node (Expression (A)));
3100
3101 -- In GNATprove mode, keep the most precise type of the actual for
3102 -- the temporary variable, when the formal type is unconstrained.
3103 -- Otherwise, the AST may contain unexpected assignment statements
3104 -- to a temporary variable of unconstrained type renaming a local
3105 -- variable of constrained type, which is not expected by
3106 -- GNATprove.
3107
3108 elsif Etype (F) /= Etype (A)
3109 and then (not GNATprove_Mode or else Is_Constrained (Etype (F)))
3110 then
3111 New_A := Unchecked_Convert_To (Etype (F), Relocate_Node (A));
3112 Temp_Typ := Etype (F);
3113
3114 else
3115 New_A := Relocate_Node (A);
3116 end if;
3117
3118 Set_Sloc (New_A, Sloc (N));
3119
3120 -- If the actual has a by-reference type, it cannot be copied,
3121 -- so its value is captured in a renaming declaration. Otherwise
3122 -- declare a local constant initialized with the actual.
3123
3124 -- We also use a renaming declaration for expressions of an array
3125 -- type that is not bit-packed, both for efficiency reasons and to
3126 -- respect the semantics of the call: in most cases the original
3127 -- call will pass the parameter by reference, and thus the inlined
3128 -- code will have the same semantics.
3129
3130 -- Finally, we need a renaming declaration in the case of limited
3131 -- types for which initialization cannot be by copy either.
3132
3133 if Ekind (F) = E_In_Parameter
3134 and then not Is_By_Reference_Type (Etype (A))
3135 and then not Is_Limited_Type (Etype (A))
3136 and then
3137 (not Is_Array_Type (Etype (A))
3138 or else not Is_Object_Reference (A)
3139 or else Is_Bit_Packed_Array (Etype (A)))
3140 then
3141 Decl :=
3142 Make_Object_Declaration (Loc,
3143 Defining_Identifier => Temp,
3144 Constant_Present => True,
3145 Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
3146 Expression => New_A);
3147
3148 else
3149 -- In GNATprove mode, make an explicit copy of input
3150 -- parameters when formal and actual types differ, to make
3151 -- sure any check on the type conversion will be issued.
3152 -- The legality of the copy is ensured by calling first
3153 -- Call_Can_Be_Inlined_In_GNATprove_Mode.
3154
3155 if GNATprove_Mode
3156 and then Ekind (F) /= E_Out_Parameter
3157 and then not Same_Type (Etype (F), Etype (A))
3158 then
3159 pragma Assert (not (Is_By_Reference_Type (Etype (A))));
3160 pragma Assert (not (Is_Limited_Type (Etype (A))));
3161
3162 Append_To (Decls,
3163 Make_Object_Declaration (Loc,
3164 Defining_Identifier => Make_Temporary (Loc, 'C'),
3165 Constant_Present => True,
3166 Object_Definition => New_Occurrence_Of (Temp_Typ, Loc),
3167 Expression => New_Copy_Tree (New_A)));
3168 end if;
3169
3170 Decl :=
3171 Make_Object_Renaming_Declaration (Loc,
3172 Defining_Identifier => Temp,
3173 Subtype_Mark => New_Occurrence_Of (Temp_Typ, Loc),
3174 Name => New_A);
3175 end if;
3176
3177 Append (Decl, Decls);
3178 Set_Renamed_Object (F, Temp);
3179 end if;
3180
3181 Next_Formal (F);
3182 Next_Actual (A);
3183 end loop;
3184
3185 -- Establish target of function call. If context is not assignment or
3186 -- declaration, create a temporary as a target. The declaration for the
3187 -- temporary may be subsequently optimized away if the body is a single
3188 -- expression, or if the left-hand side of the assignment is simple
3189 -- enough, i.e. an entity or an explicit dereference of one.
3190
3191 if Ekind (Subp) = E_Function then
3192 if Nkind (Parent (N)) = N_Assignment_Statement
3193 and then Is_Entity_Name (Name (Parent (N)))
3194 then
3195 Targ := Name (Parent (N));
3196
3197 elsif Nkind (Parent (N)) = N_Assignment_Statement
3198 and then Nkind (Name (Parent (N))) = N_Explicit_Dereference
3199 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3200 then
3201 Targ := Name (Parent (N));
3202
3203 elsif Nkind (Parent (N)) = N_Assignment_Statement
3204 and then Nkind (Name (Parent (N))) = N_Selected_Component
3205 and then Is_Entity_Name (Prefix (Name (Parent (N))))
3206 then
3207 Targ := New_Copy_Tree (Name (Parent (N)));
3208
3209 elsif Nkind (Parent (N)) = N_Object_Declaration
3210 and then Is_Limited_Type (Etype (Subp))
3211 then
3212 Targ := Defining_Identifier (Parent (N));
3213
3214 -- New semantics: In an object declaration avoid an extra copy
3215 -- of the result of a call to an inlined function that returns
3216 -- an unconstrained type
3217
3218 elsif Back_End_Inlining
3219 and then Nkind (Parent (N)) = N_Object_Declaration
3220 and then Is_Unc
3221 then
3222 Targ := Defining_Identifier (Parent (N));
3223
3224 else
3225 -- Replace call with temporary and create its declaration
3226
3227 Temp := Make_Temporary (Loc, 'C');
3228 Set_Is_Internal (Temp);
3229
3230 -- For the unconstrained case, the generated temporary has the
3231 -- same constrained declaration as the result variable. It may
3232 -- eventually be possible to remove that temporary and use the
3233 -- result variable directly.
3234
3235 if Is_Unc and then Nkind (Parent (N)) /= N_Assignment_Statement
3236 then
3237 Decl :=
3238 Make_Object_Declaration (Loc,
3239 Defining_Identifier => Temp,
3240 Object_Definition =>
3241 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3242
3243 Replace_Formals (Decl);
3244
3245 else
3246 Decl :=
3247 Make_Object_Declaration (Loc,
3248 Defining_Identifier => Temp,
3249 Object_Definition => New_Occurrence_Of (Ret_Type, Loc));
3250
3251 Set_Etype (Temp, Ret_Type);
3252 end if;
3253
3254 Set_No_Initialization (Decl);
3255 Append (Decl, Decls);
3256 Rewrite (N, New_Occurrence_Of (Temp, Loc));
3257 Targ := Temp;
3258 end if;
3259 end if;
3260
3261 Insert_Actions (N, Decls);
3262
3263 if Is_Unc_Decl then
3264
3265 -- Special management for inlining a call to a function that returns
3266 -- an unconstrained type and initializes an object declaration: we
3267 -- avoid generating undesired extra calls and goto statements.
3268
3269 -- Given:
3270 -- function Func (...) return String is
3271 -- begin
3272 -- declare
3273 -- Result : String (1 .. 4);
3274 -- begin
3275 -- Proc (Result, ...);
3276 -- return Result;
3277 -- end;
3278 -- end Func;
3279
3280 -- Result : String := Func (...);
3281
3282 -- Replace this object declaration by:
3283
3284 -- Result : String (1 .. 4);
3285 -- Proc (Result, ...);
3286
3287 Remove_Homonym (Targ);
3288
3289 Decl :=
3290 Make_Object_Declaration
3291 (Loc,
3292 Defining_Identifier => Targ,
3293 Object_Definition =>
3294 New_Copy_Tree (Object_Definition (Parent (Targ1))));
3295 Replace_Formals (Decl);
3296 Rewrite (Parent (N), Decl);
3297 Analyze (Parent (N));
3298
3299 -- Avoid spurious warnings since we know that this declaration is
3300 -- referenced by the procedure call.
3301
3302 Set_Never_Set_In_Source (Targ, False);
3303
3304 -- Remove the local declaration of the extended return stmt from the
3305 -- inlined code
3306
3307 Remove (Parent (Targ1));
3308
3309 -- Update the reference to the result (since we have rewriten the
3310 -- object declaration)
3311
3312 declare
3313 Blk_Call_Stmt : Node_Id;
3314
3315 begin
3316 -- Capture the call to the procedure
3317
3318 Blk_Call_Stmt :=
3319 First (Statements (Handled_Statement_Sequence (Blk)));
3320 pragma Assert
3321 (Nkind (Blk_Call_Stmt) = N_Procedure_Call_Statement);
3322
3323 Remove (First (Parameter_Associations (Blk_Call_Stmt)));
3324 Prepend_To (Parameter_Associations (Blk_Call_Stmt),
3325 New_Occurrence_Of (Targ, Loc));
3326 end;
3327
3328 -- Remove the return statement
3329
3330 pragma Assert
3331 (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3332 N_Simple_Return_Statement);
3333
3334 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3335 end if;
3336
3337 -- Traverse the tree and replace formals with actuals or their thunks.
3338 -- Attach block to tree before analysis and rewriting.
3339
3340 Replace_Formals (Blk);
3341 Set_Parent (Blk, N);
3342
3343 if GNATprove_Mode then
3344 null;
3345
3346 elsif not Comes_From_Source (Subp) or else Is_Predef then
3347 Reset_Slocs (Blk);
3348 end if;
3349
3350 if Is_Unc_Decl then
3351
3352 -- No action needed since return statement has been already removed
3353
3354 null;
3355
3356 elsif Present (Exit_Lab) then
3357
3358 -- If there's a single return statement at the end of the subprogram,
3359 -- the corresponding goto statement and the corresponding label are
3360 -- useless.
3361
3362 if Num_Ret = 1
3363 and then
3364 Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
3365 N_Goto_Statement
3366 then
3367 Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
3368 else
3369 Append (Lab_Decl, (Declarations (Blk)));
3370 Append (Exit_Lab, Statements (Handled_Statement_Sequence (Blk)));
3371 end if;
3372 end if;
3373
3374 -- Analyze Blk with In_Inlined_Body set, to avoid spurious errors
3375 -- on conflicting private views that Gigi would ignore. If this is a
3376 -- predefined unit, analyze with checks off, as is done in the non-
3377 -- inlined run-time units.
3378
3379 declare
3380 I_Flag : constant Boolean := In_Inlined_Body;
3381
3382 begin
3383 In_Inlined_Body := True;
3384
3385 if Is_Predef then
3386 declare
3387 Style : constant Boolean := Style_Check;
3388
3389 begin
3390 Style_Check := False;
3391
3392 -- Search for dispatching calls that use the Object.Operation
3393 -- notation using an Object that is a parameter of the inlined
3394 -- function. We reset the decoration of Operation to force
3395 -- the reanalysis of the inlined dispatching call because
3396 -- the actual object has been inlined.
3397
3398 Reset_Dispatching_Calls (Blk);
3399
3400 Analyze (Blk, Suppress => All_Checks);
3401 Style_Check := Style;
3402 end;
3403
3404 else
3405 Analyze (Blk);
3406 end if;
3407
3408 In_Inlined_Body := I_Flag;
3409 end;
3410
3411 if Ekind (Subp) = E_Procedure then
3412 Rewrite_Procedure_Call (N, Blk);
3413
3414 else
3415 Rewrite_Function_Call (N, Blk);
3416
3417 if Is_Unc_Decl then
3418 null;
3419
3420 -- For the unconstrained case, the replacement of the call has been
3421 -- made prior to the complete analysis of the generated declarations.
3422 -- Propagate the proper type now.
3423
3424 elsif Is_Unc then
3425 if Nkind (N) = N_Identifier then
3426 Set_Etype (N, Etype (Entity (N)));
3427 else
3428 Set_Etype (N, Etype (Targ1));
3429 end if;
3430 end if;
3431 end if;
3432
3433 Restore_Env;
3434
3435 -- Cleanup mapping between formals and actuals for other expansions
3436
3437 F := First_Formal (Subp);
3438 while Present (F) loop
3439 Set_Renamed_Object (F, Empty);
3440 Next_Formal (F);
3441 end loop;
3442 end Expand_Inlined_Call;
3443
3444 --------------------------
3445 -- Get_Code_Unit_Entity --
3446 --------------------------
3447
3448 function Get_Code_Unit_Entity (E : Entity_Id) return Entity_Id is
3449 Unit : Entity_Id := Cunit_Entity (Get_Code_Unit (E));
3450
3451 begin
3452 if Ekind (Unit) = E_Package_Body then
3453 Unit := Spec_Entity (Unit);
3454 end if;
3455
3456 return Unit;
3457 end Get_Code_Unit_Entity;
3458
3459 ------------------------------
3460 -- Has_Excluded_Declaration --
3461 ------------------------------
3462
3463 function Has_Excluded_Declaration
3464 (Subp : Entity_Id;
3465 Decls : List_Id) return Boolean
3466 is
3467 D : Node_Id;
3468
3469 function Is_Unchecked_Conversion (D : Node_Id) return Boolean;
3470 -- Nested subprograms make a given body ineligible for inlining, but
3471 -- we make an exception for instantiations of unchecked conversion.
3472 -- The body has not been analyzed yet, so check the name, and verify
3473 -- that the visible entity with that name is the predefined unit.
3474
3475 -----------------------------
3476 -- Is_Unchecked_Conversion --
3477 -----------------------------
3478
3479 function Is_Unchecked_Conversion (D : Node_Id) return Boolean is
3480 Id : constant Node_Id := Name (D);
3481 Conv : Entity_Id;
3482
3483 begin
3484 if Nkind (Id) = N_Identifier
3485 and then Chars (Id) = Name_Unchecked_Conversion
3486 then
3487 Conv := Current_Entity (Id);
3488
3489 elsif Nkind_In (Id, N_Selected_Component, N_Expanded_Name)
3490 and then Chars (Selector_Name (Id)) = Name_Unchecked_Conversion
3491 then
3492 Conv := Current_Entity (Selector_Name (Id));
3493 else
3494 return False;
3495 end if;
3496
3497 return Present (Conv)
3498 and then Is_Predefined_Unit (Get_Source_Unit (Conv))
3499 and then Is_Intrinsic_Subprogram (Conv);
3500 end Is_Unchecked_Conversion;
3501
3502 -- Start of processing for Has_Excluded_Declaration
3503
3504 begin
3505 -- No action needed if the check is not needed
3506
3507 if not Check_Inlining_Restrictions then
3508 return False;
3509 end if;
3510
3511 D := First (Decls);
3512 while Present (D) loop
3513
3514 -- First declarations universally excluded
3515
3516 if Nkind (D) = N_Package_Declaration then
3517 Cannot_Inline
3518 ("cannot inline & (nested package declaration)?", D, Subp);
3519 return True;
3520
3521 elsif Nkind (D) = N_Package_Instantiation then
3522 Cannot_Inline
3523 ("cannot inline & (nested package instantiation)?", D, Subp);
3524 return True;
3525 end if;
3526
3527 -- Then declarations excluded only for front-end inlining
3528
3529 if Back_End_Inlining then
3530 null;
3531
3532 elsif Nkind (D) = N_Task_Type_Declaration
3533 or else Nkind (D) = N_Single_Task_Declaration
3534 then
3535 Cannot_Inline
3536 ("cannot inline & (nested task type declaration)?", D, Subp);
3537 return True;
3538
3539 elsif Nkind (D) = N_Protected_Type_Declaration
3540 or else Nkind (D) = N_Single_Protected_Declaration
3541 then
3542 Cannot_Inline
3543 ("cannot inline & (nested protected type declaration)?",
3544 D, Subp);
3545 return True;
3546
3547 elsif Nkind (D) = N_Subprogram_Body then
3548 Cannot_Inline
3549 ("cannot inline & (nested subprogram)?", D, Subp);
3550 return True;
3551
3552 elsif Nkind (D) = N_Function_Instantiation
3553 and then not Is_Unchecked_Conversion (D)
3554 then
3555 Cannot_Inline
3556 ("cannot inline & (nested function instantiation)?", D, Subp);
3557 return True;
3558
3559 elsif Nkind (D) = N_Procedure_Instantiation then
3560 Cannot_Inline
3561 ("cannot inline & (nested procedure instantiation)?", D, Subp);
3562 return True;
3563
3564 -- Subtype declarations with predicates will generate predicate
3565 -- functions, i.e. nested subprogram bodies, so inlining is not
3566 -- possible.
3567
3568 elsif Nkind (D) = N_Subtype_Declaration
3569 and then Present (Aspect_Specifications (D))
3570 then
3571 declare
3572 A : Node_Id;
3573 A_Id : Aspect_Id;
3574
3575 begin
3576 A := First (Aspect_Specifications (D));
3577 while Present (A) loop
3578 A_Id := Get_Aspect_Id (Chars (Identifier (A)));
3579
3580 if A_Id = Aspect_Predicate
3581 or else A_Id = Aspect_Static_Predicate
3582 or else A_Id = Aspect_Dynamic_Predicate
3583 then
3584 Cannot_Inline
3585 ("cannot inline & (subtype declaration with "
3586 & "predicate)?", D, Subp);
3587 return True;
3588 end if;
3589
3590 Next (A);
3591 end loop;
3592 end;
3593 end if;
3594
3595 Next (D);
3596 end loop;
3597
3598 return False;
3599 end Has_Excluded_Declaration;
3600
3601 ----------------------------
3602 -- Has_Excluded_Statement --
3603 ----------------------------
3604
3605 function Has_Excluded_Statement
3606 (Subp : Entity_Id;
3607 Stats : List_Id) return Boolean
3608 is
3609 S : Node_Id;
3610 E : Node_Id;
3611
3612 begin
3613 -- No action needed if the check is not needed
3614
3615 if not Check_Inlining_Restrictions then
3616 return False;
3617 end if;
3618
3619 S := First (Stats);
3620 while Present (S) loop
3621 if Nkind_In (S, N_Abort_Statement,
3622 N_Asynchronous_Select,
3623 N_Conditional_Entry_Call,
3624 N_Delay_Relative_Statement,
3625 N_Delay_Until_Statement,
3626 N_Selective_Accept,
3627 N_Timed_Entry_Call)
3628 then
3629 Cannot_Inline
3630 ("cannot inline & (non-allowed statement)?", S, Subp);
3631 return True;
3632
3633 elsif Nkind (S) = N_Block_Statement then
3634 if Present (Declarations (S))
3635 and then Has_Excluded_Declaration (Subp, Declarations (S))
3636 then
3637 return True;
3638
3639 elsif Present (Handled_Statement_Sequence (S)) then
3640 if not Back_End_Inlining
3641 and then
3642 Present
3643 (Exception_Handlers (Handled_Statement_Sequence (S)))
3644 then
3645 Cannot_Inline
3646 ("cannot inline& (exception handler)?",
3647 First (Exception_Handlers
3648 (Handled_Statement_Sequence (S))),
3649 Subp);
3650 return True;
3651
3652 elsif Has_Excluded_Statement
3653 (Subp, Statements (Handled_Statement_Sequence (S)))
3654 then
3655 return True;
3656 end if;
3657 end if;
3658
3659 elsif Nkind (S) = N_Case_Statement then
3660 E := First (Alternatives (S));
3661 while Present (E) loop
3662 if Has_Excluded_Statement (Subp, Statements (E)) then
3663 return True;
3664 end if;
3665
3666 Next (E);
3667 end loop;
3668
3669 elsif Nkind (S) = N_If_Statement then
3670 if Has_Excluded_Statement (Subp, Then_Statements (S)) then
3671 return True;
3672 end if;
3673
3674 if Present (Elsif_Parts (S)) then
3675 E := First (Elsif_Parts (S));
3676 while Present (E) loop
3677 if Has_Excluded_Statement (Subp, Then_Statements (E)) then
3678 return True;
3679 end if;
3680
3681 Next (E);
3682 end loop;
3683 end if;
3684
3685 if Present (Else_Statements (S))
3686 and then Has_Excluded_Statement (Subp, Else_Statements (S))
3687 then
3688 return True;
3689 end if;
3690
3691 elsif Nkind (S) = N_Loop_Statement
3692 and then Has_Excluded_Statement (Subp, Statements (S))
3693 then
3694 return True;
3695
3696 elsif Nkind (S) = N_Extended_Return_Statement then
3697 if Present (Handled_Statement_Sequence (S))
3698 and then
3699 Has_Excluded_Statement
3700 (Subp, Statements (Handled_Statement_Sequence (S)))
3701 then
3702 return True;
3703
3704 elsif not Back_End_Inlining
3705 and then Present (Handled_Statement_Sequence (S))
3706 and then
3707 Present (Exception_Handlers
3708 (Handled_Statement_Sequence (S)))
3709 then
3710 Cannot_Inline
3711 ("cannot inline& (exception handler)?",
3712 First (Exception_Handlers (Handled_Statement_Sequence (S))),
3713 Subp);
3714 return True;
3715 end if;
3716 end if;
3717
3718 Next (S);
3719 end loop;
3720
3721 return False;
3722 end Has_Excluded_Statement;
3723
3724 --------------------------
3725 -- Has_Initialized_Type --
3726 --------------------------
3727
3728 function Has_Initialized_Type (E : Entity_Id) return Boolean is
3729 E_Body : constant Node_Id := Subprogram_Body (E);
3730 Decl : Node_Id;
3731
3732 begin
3733 if No (E_Body) then -- imported subprogram
3734 return False;
3735
3736 else
3737 Decl := First (Declarations (E_Body));
3738 while Present (Decl) loop
3739 if Nkind (Decl) = N_Full_Type_Declaration
3740 and then Present (Init_Proc (Defining_Identifier (Decl)))
3741 then
3742 return True;
3743 end if;
3744
3745 Next (Decl);
3746 end loop;
3747 end if;
3748
3749 return False;
3750 end Has_Initialized_Type;
3751
3752 -----------------------
3753 -- Has_Single_Return --
3754 -----------------------
3755
3756 function Has_Single_Return (N : Node_Id) return Boolean is
3757 Return_Statement : Node_Id := Empty;
3758
3759 function Check_Return (N : Node_Id) return Traverse_Result;
3760
3761 ------------------
3762 -- Check_Return --
3763 ------------------
3764
3765 function Check_Return (N : Node_Id) return Traverse_Result is
3766 begin
3767 if Nkind (N) = N_Simple_Return_Statement then
3768 if Present (Expression (N))
3769 and then Is_Entity_Name (Expression (N))
3770 then
3771 if No (Return_Statement) then
3772 Return_Statement := N;
3773 return OK;
3774
3775 elsif Chars (Expression (N)) =
3776 Chars (Expression (Return_Statement))
3777 then
3778 return OK;
3779
3780 else
3781 return Abandon;
3782 end if;
3783
3784 -- A return statement within an extended return is a noop
3785 -- after inlining.
3786
3787 elsif No (Expression (N))
3788 and then
3789 Nkind (Parent (Parent (N))) = N_Extended_Return_Statement
3790 then
3791 return OK;
3792
3793 else
3794 -- Expression has wrong form
3795
3796 return Abandon;
3797 end if;
3798
3799 -- We can only inline a build-in-place function if it has a single
3800 -- extended return.
3801
3802 elsif Nkind (N) = N_Extended_Return_Statement then
3803 if No (Return_Statement) then
3804 Return_Statement := N;
3805 return OK;
3806
3807 else
3808 return Abandon;
3809 end if;
3810
3811 else
3812 return OK;
3813 end if;
3814 end Check_Return;
3815
3816 function Check_All_Returns is new Traverse_Func (Check_Return);
3817
3818 -- Start of processing for Has_Single_Return
3819
3820 begin
3821 if Check_All_Returns (N) /= OK then
3822 return False;
3823
3824 elsif Nkind (Return_Statement) = N_Extended_Return_Statement then
3825 return True;
3826
3827 else
3828 return Present (Declarations (N))
3829 and then Present (First (Declarations (N)))
3830 and then Chars (Expression (Return_Statement)) =
3831 Chars (Defining_Identifier (First (Declarations (N))));
3832 end if;
3833 end Has_Single_Return;
3834
3835 -----------------------------
3836 -- In_Main_Unit_Or_Subunit --
3837 -----------------------------
3838
3839 function In_Main_Unit_Or_Subunit (E : Entity_Id) return Boolean is
3840 Comp : Node_Id := Cunit (Get_Code_Unit (E));
3841
3842 begin
3843 -- Check whether the subprogram or package to inline is within the main
3844 -- unit or its spec or within a subunit. In either case there are no
3845 -- additional bodies to process. If the subprogram appears in a parent
3846 -- of the current unit, the check on whether inlining is possible is
3847 -- done in Analyze_Inlined_Bodies.
3848
3849 while Nkind (Unit (Comp)) = N_Subunit loop
3850 Comp := Library_Unit (Comp);
3851 end loop;
3852
3853 return Comp = Cunit (Main_Unit)
3854 or else Comp = Library_Unit (Cunit (Main_Unit));
3855 end In_Main_Unit_Or_Subunit;
3856
3857 ----------------
3858 -- Initialize --
3859 ----------------
3860
3861 procedure Initialize is
3862 begin
3863 Pending_Descriptor.Init;
3864 Pending_Instantiations.Init;
3865 Inlined_Bodies.Init;
3866 Successors.Init;
3867 Inlined.Init;
3868
3869 for J in Hash_Headers'Range loop
3870 Hash_Headers (J) := No_Subp;
3871 end loop;
3872
3873 Inlined_Calls := No_Elist;
3874 Backend_Calls := No_Elist;
3875 Backend_Inlined_Subps := No_Elist;
3876 Backend_Not_Inlined_Subps := No_Elist;
3877 end Initialize;
3878
3879 ------------------------
3880 -- Instantiate_Bodies --
3881 ------------------------
3882
3883 -- Generic bodies contain all the non-local references, so an
3884 -- instantiation does not need any more context than Standard
3885 -- itself, even if the instantiation appears in an inner scope.
3886 -- Generic associations have verified that the contract model is
3887 -- satisfied, so that any error that may occur in the analysis of
3888 -- the body is an internal error.
3889
3890 procedure Instantiate_Bodies is
3891 J : Nat;
3892 Info : Pending_Body_Info;
3893
3894 begin
3895 if Serious_Errors_Detected = 0 then
3896 Expander_Active := (Operating_Mode = Opt.Generate_Code);
3897 Push_Scope (Standard_Standard);
3898 To_Clean := New_Elmt_List;
3899
3900 if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3901 Start_Generic;
3902 end if;
3903
3904 -- A body instantiation may generate additional instantiations, so
3905 -- the following loop must scan to the end of a possibly expanding
3906 -- set (that's why we can't simply use a FOR loop here).
3907
3908 J := 0;
3909 while J <= Pending_Instantiations.Last
3910 and then Serious_Errors_Detected = 0
3911 loop
3912 Info := Pending_Instantiations.Table (J);
3913
3914 -- If the instantiation node is absent, it has been removed
3915 -- as part of unreachable code.
3916
3917 if No (Info.Inst_Node) then
3918 null;
3919
3920 elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
3921 Instantiate_Package_Body (Info);
3922 Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
3923
3924 else
3925 Instantiate_Subprogram_Body (Info);
3926 end if;
3927
3928 J := J + 1;
3929 end loop;
3930
3931 -- Reset the table of instantiations. Additional instantiations
3932 -- may be added through inlining, when additional bodies are
3933 -- analyzed.
3934
3935 Pending_Instantiations.Init;
3936
3937 -- We can now complete the cleanup actions of scopes that contain
3938 -- pending instantiations (skipped for generic units, since we
3939 -- never need any cleanups in generic units).
3940
3941 if Expander_Active
3942 and then not Is_Generic_Unit (Main_Unit_Entity)
3943 then
3944 Cleanup_Scopes;
3945 elsif Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
3946 End_Generic;
3947 end if;
3948
3949 Pop_Scope;
3950 end if;
3951 end Instantiate_Bodies;
3952
3953 ---------------
3954 -- Is_Nested --
3955 ---------------
3956
3957 function Is_Nested (E : Entity_Id) return Boolean is
3958 Scop : Entity_Id;
3959
3960 begin
3961 Scop := Scope (E);
3962 while Scop /= Standard_Standard loop
3963 if Ekind (Scop) in Subprogram_Kind then
3964 return True;
3965
3966 elsif Ekind (Scop) = E_Task_Type
3967 or else Ekind (Scop) = E_Entry
3968 or else Ekind (Scop) = E_Entry_Family
3969 then
3970 return True;
3971 end if;
3972
3973 Scop := Scope (Scop);
3974 end loop;
3975
3976 return False;
3977 end Is_Nested;
3978
3979 ------------------------
3980 -- List_Inlining_Info --
3981 ------------------------
3982
3983 procedure List_Inlining_Info is
3984 Elmt : Elmt_Id;
3985 Nod : Node_Id;
3986 Count : Nat;
3987
3988 begin
3989 if not Debug_Flag_Dot_J then
3990 return;
3991 end if;
3992
3993 -- Generate listing of calls inlined by the frontend
3994
3995 if Present (Inlined_Calls) then
3996 Count := 0;
3997 Elmt := First_Elmt (Inlined_Calls);
3998 while Present (Elmt) loop
3999 Nod := Node (Elmt);
4000
4001 if In_Extended_Main_Code_Unit (Nod) then
4002 Count := Count + 1;
4003
4004 if Count = 1 then
4005 Write_Str ("List of calls inlined by the frontend");
4006 Write_Eol;
4007 end if;
4008
4009 Write_Str (" ");
4010 Write_Int (Count);
4011 Write_Str (":");
4012 Write_Location (Sloc (Nod));
4013 Write_Str (":");
4014 Output.Write_Eol;
4015 end if;
4016
4017 Next_Elmt (Elmt);
4018 end loop;
4019 end if;
4020
4021 -- Generate listing of calls passed to the backend
4022
4023 if Present (Backend_Calls) then
4024 Count := 0;
4025
4026 Elmt := First_Elmt (Backend_Calls);
4027 while Present (Elmt) loop
4028 Nod := Node (Elmt);
4029
4030 if In_Extended_Main_Code_Unit (Nod) then
4031 Count := Count + 1;
4032
4033 if Count = 1 then
4034 Write_Str ("List of inlined calls passed to the backend");
4035 Write_Eol;
4036 end if;
4037
4038 Write_Str (" ");
4039 Write_Int (Count);
4040 Write_Str (":");
4041 Write_Location (Sloc (Nod));
4042 Output.Write_Eol;
4043 end if;
4044
4045 Next_Elmt (Elmt);
4046 end loop;
4047 end if;
4048
4049 -- Generate listing of subprograms passed to the backend
4050
4051 if Present (Backend_Inlined_Subps) and then Back_End_Inlining then
4052 Count := 0;
4053
4054 Elmt := First_Elmt (Backend_Inlined_Subps);
4055 while Present (Elmt) loop
4056 Nod := Node (Elmt);
4057
4058 Count := Count + 1;
4059
4060 if Count = 1 then
4061 Write_Str
4062 ("List of inlined subprograms passed to the backend");
4063 Write_Eol;
4064 end if;
4065
4066 Write_Str (" ");
4067 Write_Int (Count);
4068 Write_Str (":");
4069 Write_Name (Chars (Nod));
4070 Write_Str (" (");
4071 Write_Location (Sloc (Nod));
4072 Write_Str (")");
4073 Output.Write_Eol;
4074
4075 Next_Elmt (Elmt);
4076 end loop;
4077 end if;
4078
4079 -- Generate listing of subprograms that cannot be inlined by the backend
4080
4081 if Present (Backend_Not_Inlined_Subps) and then Back_End_Inlining then
4082 Count := 0;
4083
4084 Elmt := First_Elmt (Backend_Not_Inlined_Subps);
4085 while Present (Elmt) loop
4086 Nod := Node (Elmt);
4087
4088 Count := Count + 1;
4089
4090 if Count = 1 then
4091 Write_Str
4092 ("List of subprograms that cannot be inlined by the backend");
4093 Write_Eol;
4094 end if;
4095
4096 Write_Str (" ");
4097 Write_Int (Count);
4098 Write_Str (":");
4099 Write_Name (Chars (Nod));
4100 Write_Str (" (");
4101 Write_Location (Sloc (Nod));
4102 Write_Str (")");
4103 Output.Write_Eol;
4104
4105 Next_Elmt (Elmt);
4106 end loop;
4107 end if;
4108 end List_Inlining_Info;
4109
4110 ----------
4111 -- Lock --
4112 ----------
4113
4114 procedure Lock is
4115 begin
4116 Pending_Instantiations.Release;
4117 Pending_Instantiations.Locked := True;
4118 Inlined_Bodies.Release;
4119 Inlined_Bodies.Locked := True;
4120 Successors.Release;
4121 Successors.Locked := True;
4122 Inlined.Release;
4123 Inlined.Locked := True;
4124 end Lock;
4125
4126 --------------------------------
4127 -- Remove_Aspects_And_Pragmas --
4128 --------------------------------
4129
4130 procedure Remove_Aspects_And_Pragmas (Body_Decl : Node_Id) is
4131 procedure Remove_Items (List : List_Id);
4132 -- Remove all useless aspects/pragmas from a particular list
4133
4134 ------------------
4135 -- Remove_Items --
4136 ------------------
4137
4138 procedure Remove_Items (List : List_Id) is
4139 Item : Node_Id;
4140 Item_Id : Node_Id;
4141 Next_Item : Node_Id;
4142
4143 begin
4144 -- Traverse the list looking for an aspect specification or a pragma
4145
4146 Item := First (List);
4147 while Present (Item) loop
4148 Next_Item := Next (Item);
4149
4150 if Nkind (Item) = N_Aspect_Specification then
4151 Item_Id := Identifier (Item);
4152 elsif Nkind (Item) = N_Pragma then
4153 Item_Id := Pragma_Identifier (Item);
4154 else
4155 Item_Id := Empty;
4156 end if;
4157
4158 if Present (Item_Id)
4159 and then Nam_In (Chars (Item_Id), Name_Contract_Cases,
4160 Name_Global,
4161 Name_Depends,
4162 Name_Postcondition,
4163 Name_Precondition,
4164 Name_Refined_Global,
4165 Name_Refined_Depends,
4166 Name_Refined_Post,
4167 Name_Test_Case,
4168 Name_Unmodified,
4169 Name_Unreferenced,
4170 Name_Unused)
4171 then
4172 Remove (Item);
4173 end if;
4174
4175 Item := Next_Item;
4176 end loop;
4177 end Remove_Items;
4178
4179 -- Start of processing for Remove_Aspects_And_Pragmas
4180
4181 begin
4182 Remove_Items (Aspect_Specifications (Body_Decl));
4183 Remove_Items (Declarations (Body_Decl));
4184
4185 -- Pragmas Unmodified, Unreferenced, and Unused may additionally appear
4186 -- in the body of the subprogram.
4187
4188 Remove_Items (Statements (Handled_Statement_Sequence (Body_Decl)));
4189 end Remove_Aspects_And_Pragmas;
4190
4191 --------------------------
4192 -- Remove_Dead_Instance --
4193 --------------------------
4194
4195 procedure Remove_Dead_Instance (N : Node_Id) is
4196 J : Int;
4197
4198 begin
4199 J := 0;
4200 while J <= Pending_Instantiations.Last loop
4201 if Pending_Instantiations.Table (J).Inst_Node = N then
4202 Pending_Instantiations.Table (J).Inst_Node := Empty;
4203 return;
4204 end if;
4205
4206 J := J + 1;
4207 end loop;
4208 end Remove_Dead_Instance;
4209
4210 end Inline;