1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
5 -- B I N D O . G R A P H S --
9 -- Copyright (C) 2019-2023, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 -- For full architecture, see unit Bindo.
28 -- The following unit defines the various graphs used in determining the
29 -- elaboration order of units.
31 with Types
; use Types
;
33 with Bindo
.Units
; use Bindo
.Units
;
36 with GNAT
.Dynamic_HTables
; use GNAT
.Dynamic_HTables
;
37 with GNAT
.Graphs
; use GNAT
.Graphs
;
38 with GNAT
.Lists
; use GNAT
.Lists
;
39 with GNAT
.Sets
; use GNAT
.Sets
;
41 package Bindo
.Graphs
is
43 ---------------------------
44 -- Invocation graph edge --
45 ---------------------------
47 -- The following type denotes an invocation graph edge handle
49 type Invocation_Graph_Edge_Id
is new Natural;
50 No_Invocation_Graph_Edge
: constant Invocation_Graph_Edge_Id
:=
51 Invocation_Graph_Edge_Id
'First;
52 First_Invocation_Graph_Edge
: constant Invocation_Graph_Edge_Id
:=
53 No_Invocation_Graph_Edge
+ 1;
55 procedure Destroy_Invocation_Graph_Edge
56 (Edge
: in out Invocation_Graph_Edge_Id
);
57 pragma Inline
(Destroy_Invocation_Graph_Edge
);
58 -- Destroy invocation graph edge Edge
60 function Hash_Invocation_Graph_Edge
61 (Edge
: Invocation_Graph_Edge_Id
) return Bucket_Range_Type
;
62 pragma Inline
(Hash_Invocation_Graph_Edge
);
63 -- Obtain the hash value of key Edge
65 function Present
(Edge
: Invocation_Graph_Edge_Id
) return Boolean;
66 pragma Inline
(Present
);
67 -- Determine whether invocation graph edge Edge exists
69 package IGE_Lists
is new Doubly_Linked_Lists
70 (Element_Type
=> Invocation_Graph_Edge_Id
,
72 Destroy_Element
=> Destroy_Invocation_Graph_Edge
);
74 ------------------------------
75 -- Invocation graph vertex --
76 ------------------------------
78 -- The following type denotes an invocation graph vertex handle
80 type Invocation_Graph_Vertex_Id
is new Natural;
81 No_Invocation_Graph_Vertex
: constant Invocation_Graph_Vertex_Id
:=
82 Invocation_Graph_Vertex_Id
'First;
83 First_Invocation_Graph_Vertex
: constant Invocation_Graph_Vertex_Id
:=
84 No_Invocation_Graph_Vertex
+ 1;
86 function Hash_Invocation_Graph_Vertex
87 (Vertex
: Invocation_Graph_Vertex_Id
) return Bucket_Range_Type
;
88 pragma Inline
(Hash_Invocation_Graph_Vertex
);
89 -- Obtain the hash value of key Vertex
91 function Present
(Vertex
: Invocation_Graph_Vertex_Id
) return Boolean;
92 pragma Inline
(Present
);
93 -- Determine whether invocation graph vertex Vertex exists
95 package IGV_Sets
is new Membership_Sets
96 (Element_Type
=> Invocation_Graph_Vertex_Id
,
98 Hash
=> Hash_Invocation_Graph_Vertex
);
100 -------------------------
101 -- Library graph cycle --
102 -------------------------
104 type Library_Graph_Cycle_Id
is new Natural;
105 No_Library_Graph_Cycle
: constant Library_Graph_Cycle_Id
:=
106 Library_Graph_Cycle_Id
'First;
107 First_Library_Graph_Cycle
: constant Library_Graph_Cycle_Id
:=
108 No_Library_Graph_Cycle
+ 1;
110 procedure Destroy_Library_Graph_Cycle
111 (Cycle
: in out Library_Graph_Cycle_Id
);
112 pragma Inline
(Destroy_Library_Graph_Cycle
);
113 -- Destroy library graph cycle Cycle
115 function Hash_Library_Graph_Cycle
116 (Cycle
: Library_Graph_Cycle_Id
) return Bucket_Range_Type
;
117 pragma Inline
(Hash_Library_Graph_Cycle
);
118 -- Obtain the hash value of key Cycle
120 function Present
(Cycle
: Library_Graph_Cycle_Id
) return Boolean;
121 pragma Inline
(Present
);
122 -- Determine whether library graph cycle Cycle exists
124 package LGC_Lists
is new Doubly_Linked_Lists
125 (Element_Type
=> Library_Graph_Cycle_Id
,
127 Destroy_Element
=> Destroy_Library_Graph_Cycle
);
129 ------------------------
130 -- Library graph edge --
131 ------------------------
133 -- The following type denotes a library graph edge handle
135 type Library_Graph_Edge_Id
is new Natural;
136 No_Library_Graph_Edge
: constant Library_Graph_Edge_Id
:=
137 Library_Graph_Edge_Id
'First;
138 First_Library_Graph_Edge
: constant Library_Graph_Edge_Id
:=
139 No_Library_Graph_Edge
+ 1;
141 procedure Destroy_Library_Graph_Edge
142 (Edge
: in out Library_Graph_Edge_Id
);
143 pragma Inline
(Destroy_Library_Graph_Edge
);
144 -- Destroy library graph edge Edge
146 function Hash_Library_Graph_Edge
147 (Edge
: Library_Graph_Edge_Id
) return Bucket_Range_Type
;
148 pragma Inline
(Hash_Library_Graph_Edge
);
149 -- Obtain the hash value of key Edge
151 function Present
(Edge
: Library_Graph_Edge_Id
) return Boolean;
152 pragma Inline
(Present
);
153 -- Determine whether library graph edge Edge exists
155 package LGE_Lists
is new Doubly_Linked_Lists
156 (Element_Type
=> Library_Graph_Edge_Id
,
158 Destroy_Element
=> Destroy_Library_Graph_Edge
);
160 package LGE_Sets
is new Membership_Sets
161 (Element_Type
=> Library_Graph_Edge_Id
,
163 Hash
=> Hash_Library_Graph_Edge
);
165 --------------------------
166 -- Library graph vertex --
167 --------------------------
169 -- The following type denotes a library graph vertex handle
171 type Library_Graph_Vertex_Id
is new Natural;
172 No_Library_Graph_Vertex
: constant Library_Graph_Vertex_Id
:=
173 Library_Graph_Vertex_Id
'First;
174 First_Library_Graph_Vertex
: constant Library_Graph_Vertex_Id
:=
175 No_Library_Graph_Vertex
+ 1;
177 procedure Destroy_Library_Graph_Vertex
178 (Vertex
: in out Library_Graph_Vertex_Id
);
179 pragma Inline
(Destroy_Library_Graph_Vertex
);
180 -- Destroy library graph vertex Vertex
182 function Hash_Library_Graph_Vertex
183 (Vertex
: Library_Graph_Vertex_Id
) return Bucket_Range_Type
;
184 pragma Inline
(Hash_Library_Graph_Vertex
);
185 -- Obtain the hash value of key Vertex
187 function Present
(Vertex
: Library_Graph_Vertex_Id
) return Boolean;
188 pragma Inline
(Present
);
189 -- Determine whether library graph vertex Vertex exists
191 package LGV_Lists
is new Doubly_Linked_Lists
192 (Element_Type
=> Library_Graph_Vertex_Id
,
194 Destroy_Element
=> Destroy_Library_Graph_Vertex
);
196 package LGV_Sets
is new Membership_Sets
197 (Element_Type
=> Library_Graph_Vertex_Id
,
199 Hash
=> Hash_Library_Graph_Vertex
);
205 package Library_Graphs
is
207 -- The following type represents the various kinds of library graph
208 -- cycles. The ordering of kinds is significant, where a literal with
209 -- lower ordinal has a higher precedence than one with higher ordinal.
211 type Library_Graph_Cycle_Kind
is
212 (Elaborate_Body_Cycle
,
213 -- A cycle that involves at least one spec-body pair, where the
214 -- spec is subject to pragma Elaborate_Body. This is the highest
218 -- A cycle that involves at least one Elaborate edge
221 -- A cycle that involves at least one Elaborate_All edge
224 -- A cycle that involves at least one edge which is a byproduct of
225 -- the forced-elaboration-order file.
228 -- A cycle that involves at least one invocation edge. This is the
229 -- lowest precedence cycle.
233 -- The following type represents the various kinds of library edges. The
234 -- order is important here, and corresponds to the order in which edges
235 -- are added to the graph. See Add_Edge_Kind_Check for details. If
236 -- changes are made such that new edge kinds are added or similar, we
237 -- need to make sure this type matches the code in Add_Edge_Kind_Check,
238 -- and Add_Edge_Kind_Check matches the order of edge adding. Likewise,
239 -- if the edge-adding order changes, we need consistency between this
240 -- enumeration type, the edge-adding order, and Add_Edge_Kind_Check.
242 type Library_Graph_Edge_Kind
is
243 (Spec_Before_Body_Edge
,
244 -- Successor denotes a body, Predecessor denotes a spec
247 -- Successor withs Predecessor, and has pragma Elaborate for it
250 -- Successor withs Predecessor, and has pragma Elaborate_All for it
253 -- Successor withs Predecessor
256 -- Successor is forced to with Predecessor by virtue of an existing
257 -- elaboration order provided in a file.
260 -- An invocation construct in unit Successor invokes a target in unit
263 Body_Before_Spec_Edge
,
264 -- Successor denotes spec, Predecessor denotes a body. This is a
265 -- special edge kind used only during the discovery of components.
266 -- Note that a body can never be elaborated before its spec.
274 -- The following type denotes a library graph handle. Each instance must
275 -- be created using routine Create.
277 type Library_Graph
is private;
278 Nil
: constant Library_Graph
;
280 type LGE_Predicate_Ptr
is access function
282 Edge
: Library_Graph_Edge_Id
) return Boolean;
284 type LGV_Comparator_Ptr
is access function
286 Vertex
: Library_Graph_Vertex_Id
;
287 Compared_To
: Library_Graph_Vertex_Id
) return Precedence_Kind
;
289 type LGV_Predicate_Ptr
is access function
291 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
293 ----------------------
294 -- Graph operations --
295 ----------------------
299 Pred
: Library_Graph_Vertex_Id
;
300 Succ
: Library_Graph_Vertex_Id
;
301 Kind
: Library_Graph_Edge_Kind
;
302 Activates_Task
: Boolean);
303 pragma Inline
(Add_Edge
);
304 -- Create a new edge in library graph G with source vertex Pred and
305 -- destination vertex Succ. Kind denotes the nature of the edge. Flag
306 -- Activates_Task should be set when the edge involves task activation.
311 pragma Inline
(Add_Vertex
);
312 -- Create a new vertex in library graph G. U_Id is the unit the vertex
316 (Initial_Vertices
: Positive;
317 Initial_Edges
: Positive) return Library_Graph
;
318 pragma Inline
(Create
);
319 -- Create a new empty graph with vertex capacity Initial_Vertices and
320 -- edge capacity Initial_Edges.
322 procedure Destroy
(G
: in out Library_Graph
);
323 pragma Inline
(Destroy
);
324 -- Destroy the contents of library graph G, rendering it unusable
326 procedure Find_Components
(G
: Library_Graph
);
327 pragma Inline
(Find_Components
);
328 -- Find all components in library graph G
330 procedure Find_Cycles
(G
: Library_Graph
);
331 pragma Inline
(Find_Cycles
);
332 -- Find all cycles in library graph G
334 function Highest_Precedence_Cycle
335 (G
: Library_Graph
) return Library_Graph_Cycle_Id
;
336 pragma Inline
(Highest_Precedence_Cycle
);
337 -- Obtain the cycle with highest precedence among all other cycles of
340 function Present
(G
: Library_Graph
) return Boolean;
341 pragma Inline
(Present
);
342 -- Determine whether library graph G exists
344 -----------------------
345 -- Vertex attributes --
346 -----------------------
350 Vertex
: Library_Graph_Vertex_Id
) return Component_Id
;
351 pragma Inline
(Component
);
352 -- Obtain the component where vertex Vertex of library graph G resides
354 function Corresponding_Item
356 Vertex
: Library_Graph_Vertex_Id
) return Library_Graph_Vertex_Id
;
357 pragma Inline
(Corresponding_Item
);
358 -- Obtain the complementary vertex which represents the corresponding
359 -- spec or body of vertex Vertex of library graph G.
361 function Corresponding_Vertex
363 U_Id
: Unit_Id
) return Library_Graph_Vertex_Id
;
364 pragma Inline
(Corresponding_Vertex
);
365 -- Obtain the corresponding vertex of library graph G which represents
368 procedure Decrement_Pending_Predecessors
370 Vertex
: Library_Graph_Vertex_Id
;
371 Edge
: Library_Graph_Edge_Id
);
372 pragma Inline
(Decrement_Pending_Predecessors
);
373 -- Decrease the number of pending predecessors vertex Vertex which was
374 -- reached via edge Edge of library graph G must wait until it can be
379 Vertex
: Library_Graph_Vertex_Id
) return File_Name_Type
;
380 pragma Inline
(File_Name
);
381 -- Obtain the name of the file where vertex Vertex of library graph G
384 function In_Elaboration_Order
386 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
387 pragma Inline
(In_Elaboration_Order
);
388 -- Determine whether vertex Vertex of library graph G is already in some
389 -- elaboration order.
391 function Invocation_Graph_Encoding
393 Vertex
: Library_Graph_Vertex_Id
)
394 return Invocation_Graph_Encoding_Kind
;
395 pragma Inline
(Invocation_Graph_Encoding
);
396 -- Obtain the encoding format used to capture information related to
397 -- invocation vertices and edges that reside within vertex Vertex of
402 Vertex
: Library_Graph_Vertex_Id
) return Unit_Name_Type
;
403 pragma Inline
(Name
);
404 -- Obtain the name of the unit which vertex Vertex of library graph G
407 procedure Pending_Predecessors_For_Elaboration
409 Vertex
: Library_Graph_Vertex_Id
;
410 Strong_Preds
: out Natural;
411 Weak_Preds
: out Natural);
412 pragma Inline
(Pending_Predecessors_For_Elaboration
);
413 -- Obtain the number of pending strong and weak predecessors of vertex
414 -- Vertex of library graph G, taking into account Elaborate_Body pairs.
415 -- Strong predecessors are returned in Strong_Preds. Weak predecessors
416 -- are returned in Weak_Preds.
418 function Pending_Strong_Predecessors
420 Vertex
: Library_Graph_Vertex_Id
) return Natural;
421 pragma Inline
(Pending_Strong_Predecessors
);
422 -- Obtain the number of pending strong predecessors vertex Vertex of
423 -- library graph G must wait on until it can be elaborated.
425 function Pending_Weak_Predecessors
427 Vertex
: Library_Graph_Vertex_Id
) return Natural;
428 pragma Inline
(Pending_Weak_Predecessors
);
429 -- Obtain the number of pending weak predecessors vertex Vertex of
430 -- library graph G must wait on until it can be elaborated.
432 procedure Set_Corresponding_Item
434 Vertex
: Library_Graph_Vertex_Id
;
435 Val
: Library_Graph_Vertex_Id
);
436 pragma Inline
(Set_Corresponding_Item
);
437 -- Set the complementary vertex which represents the corresponding
438 -- spec or body of vertex Vertex of library graph G to value Val.
440 procedure Set_In_Elaboration_Order
442 Vertex
: Library_Graph_Vertex_Id
;
443 Val
: Boolean := True);
444 pragma Inline
(Set_In_Elaboration_Order
);
445 -- Mark vertex Vertex of library graph G as included in some elaboration
446 -- order depending on value Val.
450 Vertex
: Library_Graph_Vertex_Id
) return Unit_Id
;
451 pragma Inline
(Unit
);
452 -- Obtain the unit vertex Vertex of library graph G represents
454 ---------------------
455 -- Edge attributes --
456 ---------------------
458 function Activates_Task
460 Edge
: Library_Graph_Edge_Id
) return Boolean;
461 pragma Inline
(Activates_Task
);
462 -- Determine whether edge Edge of library graph G activates a task
466 Edge
: Library_Graph_Edge_Id
) return Library_Graph_Edge_Kind
;
467 pragma Inline
(Kind
);
468 -- Obtain the nature of edge Edge of library graph G
472 Edge
: Library_Graph_Edge_Id
) return Library_Graph_Vertex_Id
;
473 pragma Inline
(Predecessor
);
474 -- Obtain the predecessor vertex of edge Edge of library graph G
478 Edge
: Library_Graph_Edge_Id
) return Library_Graph_Vertex_Id
;
479 pragma Inline
(Successor
);
480 -- Obtain the successor vertex of edge Edge of library graph G
482 --------------------------
483 -- Component attributes --
484 --------------------------
486 procedure Decrement_Pending_Predecessors
489 Edge
: Library_Graph_Edge_Id
);
490 pragma Inline
(Decrement_Pending_Predecessors
);
491 -- Decrease the number of pending predecessors component Comp which was
492 -- reached via edge Edge of library graph G must wait on until it can be
495 function Pending_Strong_Predecessors
497 Comp
: Component_Id
) return Natural;
498 pragma Inline
(Pending_Strong_Predecessors
);
499 -- Obtain the number of pending strong predecessors component Comp of
500 -- library graph G must wait on until it can be elaborated.
502 function Pending_Weak_Predecessors
504 Comp
: Component_Id
) return Natural;
505 pragma Inline
(Pending_Weak_Predecessors
);
506 -- Obtain the number of pending weak predecessors component Comp of
507 -- library graph G must wait on until it can be elaborated.
509 ----------------------
510 -- Cycle attributes --
511 ----------------------
513 function Invocation_Edge_Count
515 Cycle
: Library_Graph_Cycle_Id
) return Natural;
516 pragma Inline
(Invocation_Edge_Count
);
517 -- Obtain the number of invocation edges in cycle Cycle of library
522 Cycle
: Library_Graph_Cycle_Id
) return Library_Graph_Cycle_Kind
;
523 pragma Inline
(Kind
);
524 -- Obtain the nature of cycle Cycle of library graph G
528 Cycle
: Library_Graph_Cycle_Id
) return Natural;
529 pragma Inline
(Length
);
530 -- Obtain the length of cycle Cycle of library graph G
536 function Complementary_Vertex
538 Vertex
: Library_Graph_Vertex_Id
;
539 Force_Complement
: Boolean) return Library_Graph_Vertex_Id
;
540 pragma Inline
(Complementary_Vertex
);
541 -- Obtain the complementary vertex of vertex Vertex of library graph G
544 -- * If Vertex is the spec of an Elaborate_Body pair, return the body
545 -- * If Vertex is the body of an Elaborate_Body pair, return the spec
547 -- This behavior can be forced by setting flag Force_Complement to True.
549 function Contains_Elaborate_All_Edge
551 Cycle
: Library_Graph_Cycle_Id
) return Boolean;
552 pragma Inline
(Contains_Elaborate_All_Edge
);
553 -- Determine whether cycle Cycle of library graph G contains an
554 -- Elaborate_All edge.
556 function Contains_Static_Successor_Edge
558 Cycle
: Library_Graph_Cycle_Id
) return Boolean;
559 pragma Inline
(Contains_Static_Successor_Edge
);
560 -- Determine whether cycle Cycle of library graph G contains an edge
561 -- where the successor was compiled using the static model.
563 function Contains_Task_Activation
565 Cycle
: Library_Graph_Cycle_Id
) return Boolean;
566 pragma Inline
(Contains_Task_Activation
);
567 -- Determine whether cycle Cycle of library graph G contains an
568 -- invocation edge where the path it represents involves a task
571 function Has_Elaborate_All_Cycle
(G
: Library_Graph
) return Boolean;
572 pragma Inline
(Has_Elaborate_All_Cycle
);
573 -- Determine whether library graph G contains a cycle involving pragma
576 function Has_No_Elaboration_Code
578 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
579 pragma Inline
(Has_No_Elaboration_Code
);
580 -- Determine whether vertex Vertex of library graph G represents a unit
581 -- that lacks elaboration code.
583 function In_Same_Component
585 Left
: Library_Graph_Vertex_Id
;
586 Right
: Library_Graph_Vertex_Id
) return Boolean;
587 pragma Inline
(In_Same_Component
);
588 -- Determine whether vertices Left and Right of library graph G reside
589 -- in the same component.
593 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
594 pragma Inline
(Is_Body
);
595 -- Determine whether vertex Vertex of library graph G denotes a body
597 function Is_Body_Of_Spec_With_Elaborate_Body
599 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
600 pragma Inline
(Is_Body_Of_Spec_With_Elaborate_Body
);
601 -- Determine whether vertex Vertex of library graph G denotes a body
602 -- with a corresponding spec, and the spec has pragma Elaborate_Body.
604 function Is_Body_With_Spec
606 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
607 pragma Inline
(Is_Body_With_Spec
);
608 -- Determine whether vertex Vertex of library graph G denotes a body
609 -- with a corresponding spec.
611 function Is_Dynamically_Elaborated
613 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
614 pragma Inline
(Is_Dynamically_Elaborated
);
615 -- Determine whether vertex Vertex of library graph G was compiled
616 -- using the dynamic model.
618 function Is_Elaborable_Component
620 Comp
: Component_Id
) return Boolean;
621 pragma Inline
(Is_Elaborable_Component
);
622 -- Determine whether component Comp of library graph G is not waiting on
623 -- any predecessors, and can thus be elaborated.
625 function Is_Elaborable_Vertex
627 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
628 pragma Inline
(Is_Elaborable_Vertex
);
629 -- Determine whether vertex Vertex of library graph G is not waiting on
630 -- any predecessors, and can thus be elaborated.
632 function Is_Elaborate_All_Edge
634 Edge
: Library_Graph_Edge_Id
) return Boolean;
635 pragma Inline
(Is_Elaborate_All_Edge
);
636 -- Determine whether edge Edge of library graph G is an edge whose
637 -- predecessor is subject to pragma Elaborate_All.
639 function Is_Elaborate_Body_Edge
641 Edge
: Library_Graph_Edge_Id
) return Boolean;
642 pragma Inline
(Is_Elaborate_Body_Edge
);
643 -- Determine whether edge Edge of library graph G has a successor
644 -- that is either a spec subject to pragma Elaborate_Body, or a body
645 -- that completes such a spec.
647 function Is_Elaborate_Edge
649 Edge
: Library_Graph_Edge_Id
) return Boolean;
650 pragma Inline
(Is_Elaborate_Edge
);
651 -- Determine whether edge Edge of library graph G is an edge whose
652 -- predecessor is subject to pragma Elaborate.
654 function Is_Elaborate_Body_Pair
656 Spec_Vertex
: Library_Graph_Vertex_Id
;
657 Body_Vertex
: Library_Graph_Vertex_Id
) return Boolean;
658 pragma Inline
(Is_Elaborate_Body_Pair
);
659 -- Determine whether vertices Spec_Vertex and Body_Vertex of library
660 -- graph G denote a spec subject to Elaborate_Body and its completing
663 function Is_Forced_Edge
665 Edge
: Library_Graph_Edge_Id
) return Boolean;
666 pragma Inline
(Is_Forced_Edge
);
667 -- Determine whether edge Edge of library graph G is a byproduct of the
668 -- forced-elaboration-order file.
670 function Is_Internal_Unit
672 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
673 pragma Inline
(Is_Internal_Unit
);
674 -- Determine whether vertex Vertex of library graph G denotes an
677 function Is_Invocation_Edge
679 Edge
: Library_Graph_Edge_Id
) return Boolean;
680 pragma Inline
(Is_Invocation_Edge
);
681 -- Determine whether edge Edge of library graph G came from the
682 -- traversal of the invocation graph.
684 function Is_Predefined_Unit
686 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
687 pragma Inline
(Is_Predefined_Unit
);
688 -- Determine whether vertex Vertex of library graph G denotes a
691 function Is_Preelaborated_Unit
693 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
694 pragma Inline
(Is_Preelaborated_Unit
);
695 -- Determine whether vertex Vertex of library graph G denotes a unit
696 -- subject to pragma Pure or Preelaborable.
700 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
701 pragma Inline
(Is_Spec
);
702 -- Determine whether vertex Vertex of library graph G denotes a spec
704 function Is_Spec_Before_Body_Edge
706 Edge
: Library_Graph_Edge_Id
) return Boolean;
707 pragma Inline
(Is_Spec_Before_Body_Edge
);
708 -- Determine whether edge Edge of library graph G links a predecessor
709 -- spec and a successor body belonging to the same unit.
711 function Is_Spec_With_Body
713 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
714 pragma Inline
(Is_Spec_With_Body
);
715 -- Determine whether vertex Vertex of library graph G denotes a spec
716 -- with a corresponding body.
718 function Is_Spec_With_Elaborate_Body
720 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
721 pragma Inline
(Is_Spec_With_Elaborate_Body
);
722 -- Determine whether vertex Vertex of library graph G denotes a spec
723 -- with a corresponding body, and is subject to pragma Elaborate_Body.
725 function Is_Weakly_Elaborable_Vertex
727 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
728 pragma Inline
(Is_Weakly_Elaborable_Vertex
);
729 -- Determine whether vertex Vertex of library graph G is waiting on
730 -- weak predecessors only, in which case it can be elaborated assuming
731 -- that the weak edges will not be exercised at elaboration time.
733 function Is_With_Edge
735 Edge
: Library_Graph_Edge_Id
) return Boolean;
736 pragma Inline
(Is_With_Edge
);
737 -- Determine whether edge Edge of library graph G is the result of a
738 -- with dependency between its successor and predecessor.
740 function Needs_Elaboration
742 Vertex
: Library_Graph_Vertex_Id
) return Boolean;
743 pragma Inline
(Needs_Elaboration
);
744 -- Determine whether vertex Vertex of library graph G represents a unit
745 -- that needs to be elaborated.
749 Vertex
: Library_Graph_Vertex_Id
) return Library_Graph_Vertex_Id
;
750 pragma Inline
(Proper_Body
);
751 -- Obtain the body of vertex Vertex of library graph G
755 Vertex
: Library_Graph_Vertex_Id
) return Library_Graph_Vertex_Id
;
756 pragma Inline
(Proper_Spec
);
757 -- Obtain the spec of vertex Vertex of library graph G
763 function Library_Graph_Edge_Count
765 Kind
: Library_Graph_Edge_Kind
) return Natural;
766 pragma Inline
(Library_Graph_Edge_Count
);
767 -- Obtain the total number of edges of kind Kind in library graph G
769 function Number_Of_Component_Vertices
771 Comp
: Component_Id
) return Natural;
772 pragma Inline
(Number_Of_Component_Vertices
);
773 -- Obtain the total number of vertices component Comp of library graph
776 function Number_Of_Components
(G
: Library_Graph
) return Natural;
777 pragma Inline
(Number_Of_Components
);
778 -- Obtain the total number of components in library graph G
780 function Number_Of_Cycles
(G
: Library_Graph
) return Natural;
781 pragma Inline
(Number_Of_Cycles
);
782 -- Obtain the total number of cycles in library graph G
784 function Number_Of_Edges
(G
: Library_Graph
) return Natural;
785 pragma Inline
(Number_Of_Edges
);
786 -- Obtain the total number of edges in library graph G
788 function Number_Of_Edges_To_Successors
790 Vertex
: Library_Graph_Vertex_Id
) return Natural;
791 pragma Inline
(Number_Of_Edges_To_Successors
);
792 -- Obtain the total number of edges to successors vertex Vertex of
793 -- library graph G has.
795 function Number_Of_Vertices
(G
: Library_Graph
) return Natural;
796 pragma Inline
(Number_Of_Vertices
);
797 -- Obtain the total number of vertices in library graph G
803 -- The following type represents an iterator over all cycles of a
806 type All_Cycle_Iterator
is private;
808 function Has_Next
(Iter
: All_Cycle_Iterator
) return Boolean;
809 pragma Inline
(Has_Next
);
810 -- Determine whether iterator Iter has more cycles to examine
812 function Iterate_All_Cycles
813 (G
: Library_Graph
) return All_Cycle_Iterator
;
814 pragma Inline
(Iterate_All_Cycles
);
815 -- Obtain an iterator over all cycles of library graph G
818 (Iter
: in out All_Cycle_Iterator
;
819 Cycle
: out Library_Graph_Cycle_Id
);
820 pragma Inline
(Next
);
821 -- Return the current cycle referenced by iterator Iter and advance to
822 -- the next available cycle.
824 -- The following type represents an iterator over all edges of a library
827 type All_Edge_Iterator
is private;
829 function Has_Next
(Iter
: All_Edge_Iterator
) return Boolean;
830 pragma Inline
(Has_Next
);
831 -- Determine whether iterator Iter has more edges to examine
833 function Iterate_All_Edges
(G
: Library_Graph
) return All_Edge_Iterator
;
834 pragma Inline
(Iterate_All_Edges
);
835 -- Obtain an iterator over all edges of library graph G
838 (Iter
: in out All_Edge_Iterator
;
839 Edge
: out Library_Graph_Edge_Id
);
840 pragma Inline
(Next
);
841 -- Return the current edge referenced by iterator Iter and advance to
842 -- the next available edge.
844 -- The following type represents an iterator over all vertices of a
847 type All_Vertex_Iterator
is private;
849 function Has_Next
(Iter
: All_Vertex_Iterator
) return Boolean;
850 pragma Inline
(Has_Next
);
851 -- Determine whether iterator Iter has more vertices to examine
853 function Iterate_All_Vertices
854 (G
: Library_Graph
) return All_Vertex_Iterator
;
855 pragma Inline
(Iterate_All_Vertices
);
856 -- Obtain an iterator over all vertices of library graph G
859 (Iter
: in out All_Vertex_Iterator
;
860 Vertex
: out Library_Graph_Vertex_Id
);
861 pragma Inline
(Next
);
862 -- Return the current vertex referenced by iterator Iter and advance
863 -- to the next available vertex.
865 -- The following type represents an iterator over all components of a
868 type Component_Iterator
is private;
870 function Has_Next
(Iter
: Component_Iterator
) return Boolean;
871 pragma Inline
(Has_Next
);
872 -- Determine whether iterator Iter has more components to examine
874 function Iterate_Components
875 (G
: Library_Graph
) return Component_Iterator
;
876 pragma Inline
(Iterate_Components
);
877 -- Obtain an iterator over all components of library graph G
880 (Iter
: in out Component_Iterator
;
881 Comp
: out Component_Id
);
882 pragma Inline
(Next
);
883 -- Return the current component referenced by iterator Iter and advance
884 -- to the next available component.
886 -- The following type represents an iterator over all vertices of a
889 type Component_Vertex_Iterator
is private;
891 function Has_Next
(Iter
: Component_Vertex_Iterator
) return Boolean;
892 pragma Inline
(Has_Next
);
893 -- Determine whether iterator Iter has more vertices to examine
895 function Iterate_Component_Vertices
897 Comp
: Component_Id
) return Component_Vertex_Iterator
;
898 pragma Inline
(Iterate_Component_Vertices
);
899 -- Obtain an iterator over all vertices of component Comp of library
903 (Iter
: in out Component_Vertex_Iterator
;
904 Vertex
: out Library_Graph_Vertex_Id
);
905 pragma Inline
(Next
);
906 -- Return the current vertex referenced by iterator Iter and advance
907 -- to the next available vertex.
909 -- The following type represents an iterator over all edges that form a
912 type Edges_Of_Cycle_Iterator
is private;
914 function Has_Next
(Iter
: Edges_Of_Cycle_Iterator
) return Boolean;
915 pragma Inline
(Has_Next
);
916 -- Determine whether iterator Iter has more edges to examine
918 function Iterate_Edges_Of_Cycle
920 Cycle
: Library_Graph_Cycle_Id
) return Edges_Of_Cycle_Iterator
;
921 pragma Inline
(Iterate_Edges_Of_Cycle
);
922 -- Obtain an iterator over all edges that form cycle Cycle of library
926 (Iter
: in out Edges_Of_Cycle_Iterator
;
927 Edge
: out Library_Graph_Edge_Id
);
928 pragma Inline
(Next
);
929 -- Return the current edge referenced by iterator Iter and advance to
930 -- the next available edge.
932 -- The following type represents an iterator over all edges that reach
933 -- successors starting from a particular predecessor vertex.
935 type Edges_To_Successors_Iterator
is private;
937 function Has_Next
(Iter
: Edges_To_Successors_Iterator
) return Boolean;
938 pragma Inline
(Has_Next
);
939 -- Determine whether iterator Iter has more edges to examine
941 function Iterate_Edges_To_Successors
943 Vertex
: Library_Graph_Vertex_Id
) return Edges_To_Successors_Iterator
;
944 pragma Inline
(Iterate_Edges_To_Successors
);
945 -- Obtain an iterator over all edges to successors with predecessor
946 -- vertex Vertex of library graph G.
949 (Iter
: in out Edges_To_Successors_Iterator
;
950 Edge
: out Library_Graph_Edge_Id
);
951 pragma Inline
(Next
);
952 -- Return the current edge referenced by iterator Iter and advance to
953 -- the next available edge.
961 -- The following type represents the attributes of a library graph
964 type Library_Graph_Vertex_Attributes
is record
965 Corresponding_Item
: Library_Graph_Vertex_Id
:=
966 No_Library_Graph_Vertex
;
967 -- The reference to the corresponding spec or body. This attribute is
970 -- * If predicate Is_Body_With_Spec is True, the reference denotes
971 -- the corresponding spec.
973 -- * If predicate Is_Spec_With_Body is True, the reference denotes
974 -- the corresponding body.
976 -- * Otherwise the attribute remains empty.
978 In_Elaboration_Order
: Boolean := False;
979 -- Set when this vertex is elaborated
981 Pending_Strong_Predecessors
: Natural := 0;
982 -- The number of pending strong predecessor vertices this vertex must
983 -- wait on before it can be elaborated.
985 Pending_Weak_Predecessors
: Natural := 0;
986 -- The number of weak predecessor vertices this vertex must wait on
987 -- before it can be elaborated.
989 Unit
: Unit_Id
:= No_Unit_Id
;
990 -- The reference to unit this vertex represents
993 No_Library_Graph_Vertex_Attributes
:
994 constant Library_Graph_Vertex_Attributes
:=
995 (Corresponding_Item
=> No_Library_Graph_Vertex
,
996 In_Elaboration_Order
=> False,
997 Pending_Strong_Predecessors
=> 0,
998 Pending_Weak_Predecessors
=> 0,
1001 procedure Destroy_Library_Graph_Vertex_Attributes
1002 (Attrs
: in out Library_Graph_Vertex_Attributes
);
1003 pragma Inline
(Destroy_Library_Graph_Vertex_Attributes
);
1004 -- Destroy the contents of attributes Attrs
1006 package LGV_Tables
is new Dynamic_Hash_Tables
1007 (Key_Type
=> Library_Graph_Vertex_Id
,
1008 Value_Type
=> Library_Graph_Vertex_Attributes
,
1009 No_Value
=> No_Library_Graph_Vertex_Attributes
,
1010 Expansion_Threshold
=> 1.5,
1011 Expansion_Factor
=> 2,
1012 Compression_Threshold
=> 0.3,
1013 Compression_Factor
=> 2,
1015 Destroy_Value
=> Destroy_Library_Graph_Vertex_Attributes
,
1016 Hash
=> Hash_Library_Graph_Vertex
);
1022 -- The following type represents the attributes of a library graph edge
1024 type Library_Graph_Edge_Attributes
is record
1025 Activates_Task
: Boolean := False;
1026 -- Set for an invocation edge, where at least one of the paths the
1027 -- edge represents activates a task.
1029 Kind
: Library_Graph_Edge_Kind
:= No_Edge
;
1030 -- The nature of the library graph edge
1033 No_Library_Graph_Edge_Attributes
:
1034 constant Library_Graph_Edge_Attributes
:=
1035 (Activates_Task
=> False,
1038 procedure Destroy_Library_Graph_Edge_Attributes
1039 (Attrs
: in out Library_Graph_Edge_Attributes
);
1040 pragma Inline
(Destroy_Library_Graph_Edge_Attributes
);
1041 -- Destroy the contents of attributes Attrs
1043 package LGE_Tables
is new Dynamic_Hash_Tables
1044 (Key_Type
=> Library_Graph_Edge_Id
,
1045 Value_Type
=> Library_Graph_Edge_Attributes
,
1046 No_Value
=> No_Library_Graph_Edge_Attributes
,
1047 Expansion_Threshold
=> 1.5,
1048 Expansion_Factor
=> 2,
1049 Compression_Threshold
=> 0.3,
1050 Compression_Factor
=> 2,
1052 Destroy_Value
=> Destroy_Library_Graph_Edge_Attributes
,
1053 Hash
=> Hash_Library_Graph_Edge
);
1059 -- The following type represents the attributes of a component
1061 type Component_Attributes
is record
1062 Pending_Strong_Predecessors
: Natural := 0;
1063 -- The number of pending strong predecessor components this component
1064 -- must wait on before it can be elaborated.
1066 Pending_Weak_Predecessors
: Natural := 0;
1067 -- The number of pending weak predecessor components this component
1068 -- must wait on before it can be elaborated.
1071 No_Component_Attributes
: constant Component_Attributes
:=
1072 (Pending_Strong_Predecessors
=> 0,
1073 Pending_Weak_Predecessors
=> 0);
1075 procedure Destroy_Component_Attributes
1076 (Attrs
: in out Component_Attributes
);
1077 pragma Inline
(Destroy_Component_Attributes
);
1078 -- Destroy the contents of attributes Attrs
1080 package Component_Tables
is new Dynamic_Hash_Tables
1081 (Key_Type
=> Component_Id
,
1082 Value_Type
=> Component_Attributes
,
1083 No_Value
=> No_Component_Attributes
,
1084 Expansion_Threshold
=> 1.5,
1085 Expansion_Factor
=> 2,
1086 Compression_Threshold
=> 0.3,
1087 Compression_Factor
=> 2,
1089 Destroy_Value
=> Destroy_Component_Attributes
,
1090 Hash
=> Hash_Component
);
1096 -- The following type represents the attributes of a cycle
1098 type Library_Graph_Cycle_Attributes
is record
1099 Invocation_Edge_Count
: Natural := 0;
1100 -- The number of invocation edges within the cycle
1102 Kind
: Library_Graph_Cycle_Kind
:= No_Cycle_Kind
;
1103 -- The nature of the cycle
1105 Path
: LGE_Lists
.Doubly_Linked_List
:= LGE_Lists
.Nil
;
1106 -- The path of edges that form the cycle
1109 No_Library_Graph_Cycle_Attributes
:
1110 constant Library_Graph_Cycle_Attributes
:=
1111 (Invocation_Edge_Count
=> 0,
1112 Kind
=> No_Cycle_Kind
,
1113 Path
=> LGE_Lists
.Nil
);
1115 procedure Destroy_Library_Graph_Cycle_Attributes
1116 (Attrs
: in out Library_Graph_Cycle_Attributes
);
1117 pragma Inline
(Destroy_Library_Graph_Cycle_Attributes
);
1118 -- Destroy the contents of attributes Attrs
1120 function Hash_Library_Graph_Cycle_Attributes
1121 (Attrs
: Library_Graph_Cycle_Attributes
) return Bucket_Range_Type
;
1122 pragma Inline
(Hash_Library_Graph_Cycle_Attributes
);
1123 -- Obtain the hash of key Attrs
1125 function Same_Library_Graph_Cycle_Attributes
1126 (Left
: Library_Graph_Cycle_Attributes
;
1127 Right
: Library_Graph_Cycle_Attributes
) return Boolean;
1128 pragma Inline
(Same_Library_Graph_Cycle_Attributes
);
1129 -- Determine whether cycle attributes Left and Right are the same
1131 package LGC_Tables
is new Dynamic_Hash_Tables
1132 (Key_Type
=> Library_Graph_Cycle_Id
,
1133 Value_Type
=> Library_Graph_Cycle_Attributes
,
1134 No_Value
=> No_Library_Graph_Cycle_Attributes
,
1135 Expansion_Threshold
=> 1.5,
1136 Expansion_Factor
=> 2,
1137 Compression_Threshold
=> 0.3,
1138 Compression_Factor
=> 2,
1140 Destroy_Value
=> Destroy_Library_Graph_Cycle_Attributes
,
1141 Hash
=> Hash_Library_Graph_Cycle
);
1143 --------------------
1144 -- Recorded edges --
1145 --------------------
1147 -- The following type represents a relation between a predecessor and
1148 -- successor vertices.
1150 type Predecessor_Successor_Relation
is record
1151 Predecessor
: Library_Graph_Vertex_Id
:= No_Library_Graph_Vertex
;
1152 -- The source vertex
1154 Successor
: Library_Graph_Vertex_Id
:= No_Library_Graph_Vertex
;
1155 -- The destination vertex
1158 No_Predecessor_Successor_Relation
:
1159 constant Predecessor_Successor_Relation
:=
1160 (Predecessor
=> No_Library_Graph_Vertex
,
1161 Successor
=> No_Library_Graph_Vertex
);
1163 function Hash_Predecessor_Successor_Relation
1164 (Rel
: Predecessor_Successor_Relation
) return Bucket_Range_Type
;
1165 pragma Inline
(Hash_Predecessor_Successor_Relation
);
1166 -- Obtain the hash value of key Rel
1168 package RE_Sets
is new Membership_Sets
1169 (Element_Type
=> Predecessor_Successor_Relation
,
1171 Hash
=> Hash_Predecessor_Successor_Relation
);
1177 type Library_Graph_Edge_Counts
is
1178 array (Library_Graph_Edge_Kind
) of Natural;
1184 package Unit_Tables
is new Dynamic_Hash_Tables
1185 (Key_Type
=> Unit_Id
,
1186 Value_Type
=> Library_Graph_Vertex_Id
,
1187 No_Value
=> No_Library_Graph_Vertex
,
1188 Expansion_Threshold
=> 1.5,
1189 Expansion_Factor
=> 2,
1190 Compression_Threshold
=> 0.3,
1191 Compression_Factor
=> 2,
1193 Destroy_Value
=> Destroy_Library_Graph_Vertex
,
1200 package DG
is new Directed_Graphs
1201 (Vertex_Id
=> Library_Graph_Vertex_Id
,
1202 No_Vertex
=> No_Library_Graph_Vertex
,
1203 Hash_Vertex
=> Hash_Library_Graph_Vertex
,
1205 Edge_Id
=> Library_Graph_Edge_Id
,
1206 No_Edge
=> No_Library_Graph_Edge
,
1207 Hash_Edge
=> Hash_Library_Graph_Edge
,
1210 -- The following type represents the attributes of a library graph
1212 type Library_Graph_Attributes
is record
1213 Component_Attributes
: Component_Tables
.Dynamic_Hash_Table
:=
1214 Component_Tables
.Nil
;
1215 -- The map of component -> component attributes for all components in
1218 Counts
: Library_Graph_Edge_Counts
:= (others => 0);
1221 Cycle_Attributes
: LGC_Tables
.Dynamic_Hash_Table
:= LGC_Tables
.Nil
;
1222 -- The map of cycle -> cycle attributes for all cycles in the graph
1224 Cycles
: LGC_Lists
.Doubly_Linked_List
:= LGC_Lists
.Nil
;
1225 -- The list of all cycles in the graph, sorted based on precedence
1227 Edge_Attributes
: LGE_Tables
.Dynamic_Hash_Table
:= LGE_Tables
.Nil
;
1228 -- The map of edge -> edge attributes for all edges in the graph
1230 Graph
: DG
.Directed_Graph
:= DG
.Nil
;
1231 -- The underlying graph describing the relations between edges and
1234 Recorded_Edges
: RE_Sets
.Membership_Set
:= RE_Sets
.Nil
;
1235 -- The set of recorded edges, used to prevent duplicate edges in the
1238 Unit_To_Vertex
: Unit_Tables
.Dynamic_Hash_Table
:= Unit_Tables
.Nil
;
1239 -- The map of unit -> vertex
1241 Vertex_Attributes
: LGV_Tables
.Dynamic_Hash_Table
:= LGV_Tables
.Nil
;
1242 -- The map of vertex -> vertex attributes for all vertices in the
1246 type Library_Graph
is access Library_Graph_Attributes
;
1247 Nil
: constant Library_Graph
:= null;
1253 type All_Cycle_Iterator
is new LGC_Lists
.Iterator
;
1254 type All_Edge_Iterator
is new DG
.All_Edge_Iterator
;
1255 type All_Vertex_Iterator
is new DG
.All_Vertex_Iterator
;
1256 type Component_Iterator
is new DG
.Component_Iterator
;
1257 type Component_Vertex_Iterator
is new DG
.Component_Vertex_Iterator
;
1258 type Edges_Of_Cycle_Iterator
is new LGE_Lists
.Iterator
;
1259 type Edges_To_Successors_Iterator
is new DG
.Outgoing_Edge_Iterator
;
1262 -----------------------
1263 -- Invocation_Graphs --
1264 -----------------------
1266 package Invocation_Graphs
is
1272 -- The following type denotes an invocation graph handle. Each instance
1273 -- must be created using routine Create.
1275 type Invocation_Graph
is private;
1276 Nil
: constant Invocation_Graph
;
1278 ----------------------
1279 -- Graph operations --
1280 ----------------------
1283 (G
: Invocation_Graph
;
1284 Source
: Invocation_Graph_Vertex_Id
;
1285 Target
: Invocation_Graph_Vertex_Id
;
1286 IR_Id
: Invocation_Relation_Id
);
1287 pragma Inline
(Add_Edge
);
1288 -- Create a new edge in invocation graph G with source vertex Source and
1289 -- destination vertex Target. IR_Id is the invocation relation the edge
1292 procedure Add_Vertex
1293 (G
: Invocation_Graph
;
1294 IC_Id
: Invocation_Construct_Id
;
1295 Body_Vertex
: Library_Graph_Vertex_Id
;
1296 Spec_Vertex
: Library_Graph_Vertex_Id
);
1297 pragma Inline
(Add_Vertex
);
1298 -- Create a new vertex in invocation graph G. IC_Id is the invocation
1299 -- construct the vertex describes. Body_Vertex denotes the library graph
1300 -- vertex where the invocation construct's body is declared. Spec_Vertex
1301 -- is the library graph vertex where the invocation construct's spec is
1305 (Initial_Vertices
: Positive;
1306 Initial_Edges
: Positive;
1307 Lib_Graph
: Library_Graphs
.Library_Graph
)
1308 return Invocation_Graph
;
1309 pragma Inline
(Create
);
1310 -- Create a new empty graph with vertex capacity Initial_Vertices
1311 -- and edge capacity Initial_Edges. Lib_Graph is the library graph
1312 -- corresponding to this invocation graph.
1314 function Get_Lib_Graph
1315 (G
: Invocation_Graph
) return Library_Graphs
.Library_Graph
;
1316 pragma Inline
(Get_Lib_Graph
);
1317 -- Return the library graph corresponding to this invocation graph
1319 procedure Destroy
(G
: in out Invocation_Graph
);
1320 pragma Inline
(Destroy
);
1321 -- Destroy the contents of invocation graph G, rendering it unusable
1323 function Present
(G
: Invocation_Graph
) return Boolean;
1324 pragma Inline
(Present
);
1325 -- Determine whether invocation graph G exists
1327 -----------------------
1328 -- Vertex attributes --
1329 -----------------------
1331 function Body_Vertex
1332 (G
: Invocation_Graph
;
1333 Vertex
: Invocation_Graph_Vertex_Id
) return Library_Graph_Vertex_Id
;
1334 pragma Inline
(Body_Vertex
);
1335 -- Obtain the library graph vertex where the body of the invocation
1336 -- construct represented by vertex Vertex of invocation graph G is
1340 (G
: Invocation_Graph
;
1341 Vertex
: Invocation_Graph_Vertex_Id
) return Nat
;
1342 pragma Inline
(Column
);
1343 -- Obtain the column number where the invocation construct vertex Vertex
1344 -- of invocation graph G describes.
1347 (G
: Invocation_Graph
;
1348 Vertex
: Invocation_Graph_Vertex_Id
) return Invocation_Construct_Id
;
1349 pragma Inline
(Construct
);
1350 -- Obtain the invocation construct vertex Vertex of invocation graph G
1353 function Corresponding_Vertex
1354 (G
: Invocation_Graph
;
1355 IS_Id
: Invocation_Signature_Id
) return Invocation_Graph_Vertex_Id
;
1356 pragma Inline
(Corresponding_Vertex
);
1357 -- Obtain the vertex of invocation graph G that corresponds to signature
1361 (G
: Invocation_Graph
;
1362 Vertex
: Invocation_Graph_Vertex_Id
) return Nat
;
1363 pragma Inline
(Line
);
1364 -- Obtain the line number where the invocation construct vertex Vertex
1365 -- of invocation graph G describes.
1368 (G
: Invocation_Graph
;
1369 Vertex
: Invocation_Graph_Vertex_Id
) return Name_Id
;
1370 pragma Inline
(Name
);
1371 -- Obtain the name of the construct vertex Vertex of invocation graph G
1374 function Spec_Vertex
1375 (G
: Invocation_Graph
;
1376 Vertex
: Invocation_Graph_Vertex_Id
) return Library_Graph_Vertex_Id
;
1377 pragma Inline
(Spec_Vertex
);
1378 -- Obtain the library graph vertex where the spec of the invocation
1379 -- construct represented by vertex Vertex of invocation graph G is
1382 ---------------------
1383 -- Edge attributes --
1384 ---------------------
1387 (G
: Invocation_Graph
;
1388 Edge
: Invocation_Graph_Edge_Id
) return Name_Id
;
1389 pragma Inline
(Extra
);
1390 -- Obtain the extra name used in error diagnostics of edge Edge of
1391 -- invocation graph G.
1394 (G
: Invocation_Graph
;
1395 Edge
: Invocation_Graph_Edge_Id
) return Invocation_Kind
;
1396 pragma Inline
(Kind
);
1397 -- Obtain the nature of edge Edge of invocation graph G
1400 (G
: Invocation_Graph
;
1401 Edge
: Invocation_Graph_Edge_Id
) return Invocation_Relation_Id
;
1402 pragma Inline
(Relation
);
1403 -- Obtain the relation edge Edge of invocation graph G describes
1406 (G
: Invocation_Graph
;
1407 Edge
: Invocation_Graph_Edge_Id
) return Invocation_Graph_Vertex_Id
;
1408 pragma Inline
(Target
);
1409 -- Obtain the target vertex edge Edge of invocation graph G designates
1415 function Invocation_Graph_Edge_Count
1416 (G
: Invocation_Graph
;
1417 Kind
: Invocation_Kind
) return Natural;
1418 pragma Inline
(Invocation_Graph_Edge_Count
);
1419 -- Obtain the total number of edges of kind Kind in invocation graph G
1421 function Number_Of_Edges
(G
: Invocation_Graph
) return Natural;
1422 pragma Inline
(Number_Of_Edges
);
1423 -- Obtain the total number of edges in invocation graph G
1425 function Number_Of_Edges_To_Targets
1426 (G
: Invocation_Graph
;
1427 Vertex
: Invocation_Graph_Vertex_Id
) return Natural;
1428 pragma Inline
(Number_Of_Edges_To_Targets
);
1429 -- Obtain the total number of edges to targets vertex Vertex of
1430 -- invocation graph G has.
1432 function Number_Of_Elaboration_Roots
1433 (G
: Invocation_Graph
) return Natural;
1434 pragma Inline
(Number_Of_Elaboration_Roots
);
1435 -- Obtain the total number of elaboration roots in invocation graph G
1437 function Number_Of_Vertices
(G
: Invocation_Graph
) return Natural;
1438 pragma Inline
(Number_Of_Vertices
);
1439 -- Obtain the total number of vertices in invocation graph G
1445 -- The following type represents an iterator over all edges of an
1446 -- invocation graph.
1448 type All_Edge_Iterator
is private;
1450 function Has_Next
(Iter
: All_Edge_Iterator
) return Boolean;
1451 pragma Inline
(Has_Next
);
1452 -- Determine whether iterator Iter has more edges to examine
1454 function Iterate_All_Edges
1455 (G
: Invocation_Graph
) return All_Edge_Iterator
;
1456 pragma Inline
(Iterate_All_Edges
);
1457 -- Obtain an iterator over all edges of invocation graph G
1460 (Iter
: in out All_Edge_Iterator
;
1461 Edge
: out Invocation_Graph_Edge_Id
);
1462 pragma Inline
(Next
);
1463 -- Return the current edge referenced by iterator Iter and advance to
1464 -- the next available edge.
1466 -- The following type represents an iterator over all vertices of an
1467 -- invocation graph.
1469 type All_Vertex_Iterator
is private;
1471 function Has_Next
(Iter
: All_Vertex_Iterator
) return Boolean;
1472 pragma Inline
(Has_Next
);
1473 -- Determine whether iterator Iter has more vertices to examine
1475 function Iterate_All_Vertices
1476 (G
: Invocation_Graph
) return All_Vertex_Iterator
;
1477 pragma Inline
(Iterate_All_Vertices
);
1478 -- Obtain an iterator over all vertices of invocation graph G
1481 (Iter
: in out All_Vertex_Iterator
;
1482 Vertex
: out Invocation_Graph_Vertex_Id
);
1483 pragma Inline
(Next
);
1484 -- Return the current vertex referenced by iterator Iter and advance
1485 -- to the next available vertex.
1487 -- The following type represents an iterator over all edges that reach
1488 -- targets starting from a particular source vertex.
1490 type Edges_To_Targets_Iterator
is private;
1492 function Has_Next
(Iter
: Edges_To_Targets_Iterator
) return Boolean;
1493 pragma Inline
(Has_Next
);
1494 -- Determine whether iterator Iter has more edges to examine
1496 function Iterate_Edges_To_Targets
1497 (G
: Invocation_Graph
;
1498 Vertex
: Invocation_Graph_Vertex_Id
) return Edges_To_Targets_Iterator
;
1499 pragma Inline
(Iterate_Edges_To_Targets
);
1500 -- Obtain an iterator over all edges to targets with source vertex
1501 -- Vertex of invocation graph G.
1504 (Iter
: in out Edges_To_Targets_Iterator
;
1505 Edge
: out Invocation_Graph_Edge_Id
);
1506 pragma Inline
(Next
);
1507 -- Return the current edge referenced by iterator Iter and advance to
1508 -- the next available edge.
1510 -- The following type represents an iterator over all vertices of an
1511 -- invocation graph that denote the elaboration procedure or a spec or
1512 -- a body, referred to as elaboration root.
1514 type Elaboration_Root_Iterator
is private;
1516 function Has_Next
(Iter
: Elaboration_Root_Iterator
) return Boolean;
1517 pragma Inline
(Has_Next
);
1518 -- Determine whether iterator Iter has more elaboration roots to examine
1520 function Iterate_Elaboration_Roots
1521 (G
: Invocation_Graph
) return Elaboration_Root_Iterator
;
1522 pragma Inline
(Iterate_Elaboration_Roots
);
1523 -- Obtain an iterator over all elaboration roots of invocation graph G
1526 (Iter
: in out Elaboration_Root_Iterator
;
1527 Root
: out Invocation_Graph_Vertex_Id
);
1528 pragma Inline
(Next
);
1529 -- Return the current elaboration root referenced by iterator Iter and
1530 -- advance to the next available elaboration root.
1538 procedure Destroy_Invocation_Graph_Vertex
1539 (Vertex
: in out Invocation_Graph_Vertex_Id
);
1540 pragma Inline
(Destroy_Invocation_Graph_Vertex
);
1541 -- Destroy invocation graph vertex Vertex
1543 -- The following type represents the attributes of an invocation graph
1546 type Invocation_Graph_Vertex_Attributes
is record
1547 Body_Vertex
: Library_Graph_Vertex_Id
:= No_Library_Graph_Vertex
;
1548 -- Reference to the library graph vertex where the body of this
1551 Construct
: Invocation_Construct_Id
:= No_Invocation_Construct
;
1552 -- Reference to the invocation construct this vertex represents
1554 Spec_Vertex
: Library_Graph_Vertex_Id
:= No_Library_Graph_Vertex
;
1555 -- Reference to the library graph vertex where the spec of this
1559 No_Invocation_Graph_Vertex_Attributes
:
1560 constant Invocation_Graph_Vertex_Attributes
:=
1561 (Body_Vertex
=> No_Library_Graph_Vertex
,
1562 Construct
=> No_Invocation_Construct
,
1563 Spec_Vertex
=> No_Library_Graph_Vertex
);
1565 procedure Destroy_Invocation_Graph_Vertex_Attributes
1566 (Attrs
: in out Invocation_Graph_Vertex_Attributes
);
1567 pragma Inline
(Destroy_Invocation_Graph_Vertex_Attributes
);
1568 -- Destroy the contents of attributes Attrs
1570 package IGV_Tables
is new Dynamic_Hash_Tables
1571 (Key_Type
=> Invocation_Graph_Vertex_Id
,
1572 Value_Type
=> Invocation_Graph_Vertex_Attributes
,
1573 No_Value
=> No_Invocation_Graph_Vertex_Attributes
,
1574 Expansion_Threshold
=> 1.5,
1575 Expansion_Factor
=> 2,
1576 Compression_Threshold
=> 0.3,
1577 Compression_Factor
=> 2,
1579 Destroy_Value
=> Destroy_Invocation_Graph_Vertex_Attributes
,
1580 Hash
=> Hash_Invocation_Graph_Vertex
);
1586 procedure Destroy_Invocation_Graph_Edge
1587 (Edge
: in out Invocation_Graph_Edge_Id
);
1588 pragma Inline
(Destroy_Invocation_Graph_Edge
);
1589 -- Destroy invocation graph edge Edge
1591 -- The following type represents the attributes of an invocation graph
1594 type Invocation_Graph_Edge_Attributes
is record
1595 Relation
: Invocation_Relation_Id
:= No_Invocation_Relation
;
1596 -- Reference to the invocation relation this edge represents
1599 No_Invocation_Graph_Edge_Attributes
:
1600 constant Invocation_Graph_Edge_Attributes
:=
1601 (Relation
=> No_Invocation_Relation
);
1603 procedure Destroy_Invocation_Graph_Edge_Attributes
1604 (Attrs
: in out Invocation_Graph_Edge_Attributes
);
1605 pragma Inline
(Destroy_Invocation_Graph_Edge_Attributes
);
1606 -- Destroy the contents of attributes Attrs
1608 package IGE_Tables
is new Dynamic_Hash_Tables
1609 (Key_Type
=> Invocation_Graph_Edge_Id
,
1610 Value_Type
=> Invocation_Graph_Edge_Attributes
,
1611 No_Value
=> No_Invocation_Graph_Edge_Attributes
,
1612 Expansion_Threshold
=> 1.5,
1613 Expansion_Factor
=> 2,
1614 Compression_Threshold
=> 0.3,
1615 Compression_Factor
=> 2,
1617 Destroy_Value
=> Destroy_Invocation_Graph_Edge_Attributes
,
1618 Hash
=> Hash_Invocation_Graph_Edge
);
1624 -- The following type represents a relation between a source and target
1627 type Source_Target_Relation
is record
1628 Source
: Invocation_Graph_Vertex_Id
:= No_Invocation_Graph_Vertex
;
1629 -- The source vertex
1631 Target
: Invocation_Graph_Vertex_Id
:= No_Invocation_Graph_Vertex
;
1632 -- The destination vertex
1635 No_Source_Target_Relation
:
1636 constant Source_Target_Relation
:=
1637 (Source
=> No_Invocation_Graph_Vertex
,
1638 Target
=> No_Invocation_Graph_Vertex
);
1640 function Hash_Source_Target_Relation
1641 (Rel
: Source_Target_Relation
) return Bucket_Range_Type
;
1642 pragma Inline
(Hash_Source_Target_Relation
);
1643 -- Obtain the hash value of key Rel
1645 package Relation_Sets
is new Membership_Sets
1646 (Element_Type
=> Source_Target_Relation
,
1648 Hash
=> Hash_Source_Target_Relation
);
1654 type Invocation_Graph_Edge_Counts
is array (Invocation_Kind
) of Natural;
1660 function Hash_Invocation_Signature
1661 (IS_Id
: Invocation_Signature_Id
) return Bucket_Range_Type
;
1662 pragma Inline
(Hash_Invocation_Signature
);
1663 -- Obtain the hash value of key IS_Id
1665 package Signature_Tables
is new Dynamic_Hash_Tables
1666 (Key_Type
=> Invocation_Signature_Id
,
1667 Value_Type
=> Invocation_Graph_Vertex_Id
,
1668 No_Value
=> No_Invocation_Graph_Vertex
,
1669 Expansion_Threshold
=> 1.5,
1670 Expansion_Factor
=> 2,
1671 Compression_Threshold
=> 0.3,
1672 Compression_Factor
=> 2,
1674 Destroy_Value
=> Destroy_Invocation_Graph_Vertex
,
1675 Hash
=> Hash_Invocation_Signature
);
1677 -----------------------
1678 -- Elaboration roots --
1679 -----------------------
1681 package IGV_Sets
is new Membership_Sets
1682 (Element_Type
=> Invocation_Graph_Vertex_Id
,
1684 Hash
=> Hash_Invocation_Graph_Vertex
);
1690 package DG
is new Directed_Graphs
1691 (Vertex_Id
=> Invocation_Graph_Vertex_Id
,
1692 No_Vertex
=> No_Invocation_Graph_Vertex
,
1693 Hash_Vertex
=> Hash_Invocation_Graph_Vertex
,
1695 Edge_id
=> Invocation_Graph_Edge_Id
,
1696 No_Edge
=> No_Invocation_Graph_Edge
,
1697 Hash_Edge
=> Hash_Invocation_Graph_Edge
,
1700 -- The following type represents the attributes of an invocation graph
1702 type Invocation_Graph_Attributes
is record
1703 Counts
: Invocation_Graph_Edge_Counts
:= (others => 0);
1706 Edge_Attributes
: IGE_Tables
.Dynamic_Hash_Table
:= IGE_Tables
.Nil
;
1707 -- The map of edge -> edge attributes for all edges in the graph
1709 Graph
: DG
.Directed_Graph
:= DG
.Nil
;
1710 -- The underlying graph describing the relations between edges and
1713 Relations
: Relation_Sets
.Membership_Set
:= Relation_Sets
.Nil
;
1714 -- The set of relations between source and targets, used to prevent
1715 -- duplicate edges in the graph.
1717 Roots
: IGV_Sets
.Membership_Set
:= IGV_Sets
.Nil
;
1718 -- The set of elaboration root vertices
1720 Signature_To_Vertex
: Signature_Tables
.Dynamic_Hash_Table
:=
1721 Signature_Tables
.Nil
;
1722 -- The map of signature -> vertex
1724 Vertex_Attributes
: IGV_Tables
.Dynamic_Hash_Table
:= IGV_Tables
.Nil
;
1725 -- The map of vertex -> vertex attributes for all vertices in the
1728 Lib_Graph
: Library_Graphs
.Library_Graph
;
1731 type Invocation_Graph
is access Invocation_Graph_Attributes
;
1732 Nil
: constant Invocation_Graph
:= null;
1738 type All_Edge_Iterator
is new DG
.All_Edge_Iterator
;
1739 type All_Vertex_Iterator
is new DG
.All_Vertex_Iterator
;
1740 type Edges_To_Targets_Iterator
is new DG
.Outgoing_Edge_Iterator
;
1741 type Elaboration_Root_Iterator
is new IGV_Sets
.Iterator
;
1742 end Invocation_Graphs
;