From 92c7734db7af1395be571c5ec023a38fb7b42adf Mon Sep 17 00:00:00 2001 From: Hristian Kirtchev Date: Mon, 8 Jul 2019 08:13:43 +0000 Subject: [PATCH] [Ada] New algorithm for Elaboration order v4.0 This patch introduces several changes to the new elaboration order mechanism: * The concept of "strong" and "weak" edges is introduced. Strong edges are the byproduct of language-defined relations between units, such as with clauses. Weak edges are the byproduct of specilative invocations at elaboration time, which may or may not take place depending on control flow. * The elaboration order algorithm has been heavily modified to make use of the strong and weak edges, and operate on units compiled with different elaboration models. * The elaboration order algorithm employs the following logic: - Maintain two sets of vertices, one for all elaborable vertices, and one for all waiting vertices. - Pick the best elaborable vertex, and elaborate its component. - If no such elaborable vertex is available, pick the best weakly elaborable vertex whose unit has been compiled with the dynamic model, and elaborate its component. - If no such weakly elaborable vertex is available, then either all vertices were already elaborated, or the graph contains a cycle. The elaboration of a component employs the same logic, with an added step where all successors of some predecessor currently being elaborated are notified that they have one fewer predecessor to wait on. This may cause certain successors to become elaborable, in which case they are moved from the set of waiting vertices to the set of elaborable vertices. * Three new GNATbind debug switches are introduced, -d_a, -d_b, and -d_e, to eliminate the effects of pragmas Elaborate_All, Elaborate_Body, and Elaborate respectively. * The section on terminology is updated to include new entries. 2019-07-08 Hristian Kirtchev gcc/ada/ * bindo.adb: Update the section on terminology to include new concepts. Update the section on switches to include new entries. * bindo.ads: Add type Precedence_Kind. * bindo-builders.adb: Add with and use clauses for Debug and Bindo.Validators. Add use clauses for Bindo.Validators.Invocation_Graph_Validators and Bindo.Validators.Library_Graph_Validators. (Build_Invocation_Graph): Validate the graph immediately after it was built. (Build_Library_Graph): Update the parameter profile. The creation of the graph is now elaboration model-agnostic. Validate the graph immediately after it was built. (Create_With_Edge): Create regular with edges for Elaborate and Elaborate_All edges when the appropriate debug switches are in effect. * bindo-builders.ads (Build_Library_Graph): Update the parameter profile. * bindo-diagnostics.adb (Diagnose_Cycle): Track the presence of an Elaborate_All edge throughout the inspection of the cycle's edges. (Output_Dynamic_Model_Suggestions): Output the suggestion only when the cycle contains at least one weak edge where the successor was statically elaborated. (Output_Elaborate_Body_Transition, Output_Forced_Transition, Output_With_Transition): Update the assertions. * bindo-elaborators.adb: Remove use clauses for Bindo.Validators.Invocation_Graph_Validators and Bindo.Validators.Library_Graph_Validators. Remove strings Add_To_All_Candidates_Msg and Add_To_Comp_Candidates_Msg. Remove type String_Ptr. (Add_Vertex, Add_Vertex_If_Elaborable, Create_All_Candidates_Set Create_Component_Candidates_Set): Remove. (Create_Component_Vertex_Sets, Create_Vertex_Sets): New routine. (Elaborate_Component): Update the parameter profile and the comment on usage. Reimplement the elaboration of a component. The algorithm will now attempt to elaborate as many vertices possible. If this is not possible, and a weakly elaborable vertex is available use unit was compiled using the dynamic model, the algorithm will elaborate it. (Elaborate_Library_Graph): Reimplement the elaboration of the graph. The algorithm will now attempt to elaborate as many vertices along with their components as possible. If this is not possible, and a weakly elaborable vertex is available use unit was compiled using the dynamic model, the algorithm will elaborate it along with its component. (Elaborate_Units): Merge with the functionality of Elaborate_Units_Common. (Elaborate_Units_Common, Elaborate_Units_Dynamic, Elaborate_Units_Static): Remove. (Elaborate_Vertex): Update the parameter profile and the comment on usage. Reimplemented. (Find_Best_Candidate): Remove. (Find_Best_Elaborable_Vertex, Find_Best_Vertex, Find_Best_Weakly_Elaborable_Vertex, Has_Elaborable_Body, Insert_Elaborable_Successor, Insert_Vertex): New routines. (Is_Better_Candidate): Remove. (Is_Better_Elaborable_Vertex, Is_Better_Weakly_Elaborable_Vertex, Is_Suitable_Elaborable_Vertex, Is_Suitable_Weakly_Elaborable_Vertex): New routines. (Trace_Candidate_Vertices): Remove. (Trace_Component): Output the number of strong and weak predecessors. (Trace_Unelaborated_Vertices): Remove. (Trace_Vertex): Output the number of strong and weak predecessors. (Trace_Vertices): New routine. (Update_Successor, Update_Successors): Update the parameter profile and the comment on usage. * bindo-graphs.adb: Remove type Precedence_Kind. (Add_Edge_With_Return): Update the increment of pending predecessors. (Add_Vertex): Provide default values for strong and weak predecessors. (Complementary_Vertex): Move the initial declaration to the spec. Update the parameter profile and the comment on usage. (Contains_Weak_Static_Successor): New routine. (Create): Update the parameter profile. The creation of the graph is now elaboration model-agnostic. (Decrement_Pending_Predecessors): Update the parameter profile and the comment on usage. Reimplemented. (Delete_Edge): Update the decrement of pending predecesors. (Has_Elaborate_Body): Do not treat a vertex as being subject to Elaborate_Body when a debug switch is in effect. (Increment_Pending_Predecessors): Update the parameter profile and the comment on usage. Reimplemented. (Is_Elaborable_Component): Reimplemented. (Is_Elaborable_Vertex): Move the initial declaration to the spec. Reimplemented. (Is_Elaborate_Body_Pair): New routine. (Is_Dynamically_Elaborated): Update the parameter profile. Reimplemented. (Is_Weakly_Elaborable_Vertex): New routine. (Pending_Predecessors): Removed. (Pending_Predecessors_For_Elaboration, Pending_Strong_Predecessors, Pending_Weak_Predecessors, Update_Pending_Predecessors): New routines. (Update_Pending_Predecessors_Of_Components): Update the increment of pending predecessors. * bindo-graphs.ads: Update the components of type Component_Attributes. Update the components of type Library_Graph_Attributes. Update the components of type Library_Graph_Vertex_Attributes. Update the initialization of No_Component_Attributes. Update the initialization of No_Library_Graph_Vertex_Attributes. (Complementary_Vertex, Contains_Weak_Static_Successor): New routines. (Create): Update the parameter profile and the comment on usage. (Decrement_Pending_Predecessors, Is_Dynamically_Elaborated): Update the parameter profile and the comment on usage. (Is_Elaborate_Body_Pair, Is_Weakly_Elaborable_Vertex): New routines. (Pending_Predecessors): Removed. (Pending_Predecessors_For_Elaboration, Pending_Strong_Predecessors, Pending_Weak_Predecessors): New routines. * bindo-writers.adb (Write_Components): Moved from the spec. (Write_Component): Output the strong and weak predecessors. (Write_Library_Graph): Output the components as part of the graph. (Write_Library_Graph_Vertex): Output the strong and weak predecessors. * bindo-writers.ads (Write_Components): Moved to the body. * debug.adb: Add and document new GNATbind switches -d_a, -d_b, -d_e. * bindo-validators.adb: Minor reformattings. From-SVN: r273209 --- gcc/ada/ChangeLog | 130 +++ gcc/ada/bindo-builders.adb | 36 +- gcc/ada/bindo-builders.ads | 6 +- gcc/ada/bindo-diagnostics.adb | 45 +- gcc/ada/bindo-elaborators.adb | 1907 +++++++++++++++++++-------------- gcc/ada/bindo-graphs.adb | 527 ++++++--- gcc/ada/bindo-graphs.ads | 156 ++- gcc/ada/bindo-validators.adb | 12 +- gcc/ada/bindo-writers.adb | 23 +- gcc/ada/bindo-writers.ads | 3 - gcc/ada/bindo.adb | 48 +- gcc/ada/bindo.ads | 10 + gcc/ada/debug.adb | 17 +- 13 files changed, 1845 insertions(+), 1075 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 3bbc1cfc5da..e6eac08a802 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,133 @@ +2019-07-08 Hristian Kirtchev + + * bindo.adb: Update the section on terminology to include new + concepts. Update the section on switches to include new + entries. + * bindo.ads: Add type Precedence_Kind. + * bindo-builders.adb: Add with and use clauses for Debug and + Bindo.Validators. Add use clauses for + Bindo.Validators.Invocation_Graph_Validators and + Bindo.Validators.Library_Graph_Validators. + (Build_Invocation_Graph): Validate the graph immediately after + it was built. + (Build_Library_Graph): Update the parameter profile. The + creation of the graph is now elaboration model-agnostic. + Validate the graph immediately after it was built. + (Create_With_Edge): Create regular with edges for Elaborate and + Elaborate_All edges when the appropriate debug switches are in + effect. + * bindo-builders.ads (Build_Library_Graph): Update the parameter + profile. + * bindo-diagnostics.adb (Diagnose_Cycle): Track the presence of + an Elaborate_All edge throughout the inspection of the cycle's + edges. + (Output_Dynamic_Model_Suggestions): Output the suggestion only + when the cycle contains at least one weak edge where the + successor was statically elaborated. + (Output_Elaborate_Body_Transition, Output_Forced_Transition, + Output_With_Transition): Update the assertions. + * bindo-elaborators.adb: Remove use clauses for + Bindo.Validators.Invocation_Graph_Validators and + Bindo.Validators.Library_Graph_Validators. Remove strings + Add_To_All_Candidates_Msg and Add_To_Comp_Candidates_Msg. + Remove type String_Ptr. + (Add_Vertex, Add_Vertex_If_Elaborable, Create_All_Candidates_Set + Create_Component_Candidates_Set): Remove. + (Create_Component_Vertex_Sets, Create_Vertex_Sets): New routine. + (Elaborate_Component): Update the parameter profile and the + comment on usage. Reimplement the elaboration of a component. + The algorithm will now attempt to elaborate as many vertices + possible. If this is not possible, and a weakly elaborable + vertex is available use unit was compiled using the dynamic + model, the algorithm will elaborate it. + (Elaborate_Library_Graph): Reimplement the elaboration of the + graph. The algorithm will now attempt to elaborate as many + vertices along with their components as possible. If this is not + possible, and a weakly elaborable vertex is available use unit + was compiled using the dynamic model, the algorithm will + elaborate it along with its component. + (Elaborate_Units): Merge with the functionality of + Elaborate_Units_Common. + (Elaborate_Units_Common, Elaborate_Units_Dynamic, + Elaborate_Units_Static): Remove. + (Elaborate_Vertex): Update the parameter profile and the comment + on usage. Reimplemented. + (Find_Best_Candidate): Remove. + (Find_Best_Elaborable_Vertex, Find_Best_Vertex, + Find_Best_Weakly_Elaborable_Vertex, Has_Elaborable_Body, + Insert_Elaborable_Successor, Insert_Vertex): New routines. + (Is_Better_Candidate): Remove. + (Is_Better_Elaborable_Vertex, + Is_Better_Weakly_Elaborable_Vertex, + Is_Suitable_Elaborable_Vertex, + Is_Suitable_Weakly_Elaborable_Vertex): New routines. + (Trace_Candidate_Vertices): Remove. + (Trace_Component): Output the number of strong and weak + predecessors. + (Trace_Unelaborated_Vertices): Remove. + (Trace_Vertex): Output the number of strong and weak + predecessors. + (Trace_Vertices): New routine. + (Update_Successor, Update_Successors): Update the parameter + profile and the comment on usage. + * bindo-graphs.adb: Remove type Precedence_Kind. + (Add_Edge_With_Return): Update the increment of pending + predecessors. + (Add_Vertex): Provide default values for strong and weak + predecessors. + (Complementary_Vertex): Move the initial declaration to the + spec. Update the parameter profile and the comment on usage. + (Contains_Weak_Static_Successor): New routine. + (Create): Update the parameter profile. The creation of the + graph is now elaboration model-agnostic. + (Decrement_Pending_Predecessors): Update the parameter profile + and the comment on usage. Reimplemented. + (Delete_Edge): Update the decrement of pending predecesors. + (Has_Elaborate_Body): Do not treat a vertex as being subject to + Elaborate_Body when a debug switch is in effect. + (Increment_Pending_Predecessors): Update the parameter profile + and the comment on usage. Reimplemented. + (Is_Elaborable_Component): Reimplemented. + (Is_Elaborable_Vertex): Move the initial declaration to the + spec. Reimplemented. + (Is_Elaborate_Body_Pair): New routine. + (Is_Dynamically_Elaborated): Update the parameter profile. + Reimplemented. + (Is_Weakly_Elaborable_Vertex): New routine. + (Pending_Predecessors): Removed. + (Pending_Predecessors_For_Elaboration, + Pending_Strong_Predecessors, Pending_Weak_Predecessors, + Update_Pending_Predecessors): New routines. + (Update_Pending_Predecessors_Of_Components): Update the + increment of pending predecessors. + * bindo-graphs.ads: Update the components of type + Component_Attributes. Update the components of type + Library_Graph_Attributes. Update the components of type + Library_Graph_Vertex_Attributes. Update the initialization of + No_Component_Attributes. Update the initialization of + No_Library_Graph_Vertex_Attributes. + (Complementary_Vertex, Contains_Weak_Static_Successor): New + routines. + (Create): Update the parameter profile and the comment on usage. + (Decrement_Pending_Predecessors, Is_Dynamically_Elaborated): + Update the parameter profile and the comment on usage. + (Is_Elaborate_Body_Pair, Is_Weakly_Elaborable_Vertex): New + routines. + (Pending_Predecessors): Removed. + (Pending_Predecessors_For_Elaboration, + Pending_Strong_Predecessors, Pending_Weak_Predecessors): New + routines. + * bindo-writers.adb (Write_Components): Moved from the spec. + (Write_Component): Output the strong and weak predecessors. + (Write_Library_Graph): Output the components as part of the + graph. + (Write_Library_Graph_Vertex): Output the strong and weak + predecessors. + * bindo-writers.ads (Write_Components): Moved to the body. + * debug.adb: Add and document new GNATbind switches -d_a, -d_b, + -d_e. + * bindo-validators.adb: Minor reformattings. + 2019-07-08 Bob Duff * libgnat/g-sercom.ads, libgnat/g-sercom__linux.adb (Data_Rate): diff --git a/gcc/ada/bindo-builders.adb b/gcc/ada/bindo-builders.adb index f4b8e42fe08..233891d12e4 100644 --- a/gcc/ada/bindo-builders.adb +++ b/gcc/ada/bindo-builders.adb @@ -25,12 +25,18 @@ with Binderr; use Binderr; with Butil; use Butil; +with Debug; use Debug; with Opt; use Opt; with Output; use Output; with Types; use Types; with Bindo.Units; use Bindo.Units; +with Bindo.Validators; +use Bindo.Validators; +use Bindo.Validators.Invocation_Graph_Validators; +use Bindo.Validators.Library_Graph_Validators; + with GNAT; use GNAT; with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables; @@ -104,6 +110,8 @@ package body Bindo.Builders is For_Each_Elaborable_Unit (Create_Vertices'Access); For_Each_Elaborable_Unit (Create_Edges'Access); + Validate_Invocation_Graph (Inv_Graph); + return Inv_Graph; end Build_Invocation_Graph; @@ -365,24 +373,22 @@ package body Bindo.Builders is -- Build_Library_Graph -- ------------------------- - function Build_Library_Graph - (Dynamically_Elaborated : Boolean) return Library_Graph - is + function Build_Library_Graph return Library_Graph is begin -- Prepare the global data Lib_Graph := Create - (Initial_Vertices => Number_Of_Elaborable_Units, - Initial_Edges => Number_Of_Elaborable_Units, - Dynamically_Elaborated => Dynamically_Elaborated); + (Initial_Vertices => Number_Of_Elaborable_Units, + Initial_Edges => Number_Of_Elaborable_Units); For_Each_Elaborable_Unit (Create_Vertex'Access); For_Each_Elaborable_Unit (Create_Spec_And_Body_Edge'Access); For_Each_Elaborable_Unit (Create_With_Edges'Access); - Create_Forced_Edges; + Validate_Library_Graph (Lib_Graph); + return Lib_Graph; end Build_Library_Graph; @@ -549,9 +555,13 @@ package body Bindo.Builders is Withed_Vertex := Corresponding_Vertex (Lib_Graph, Withed_U_Id); - -- The with comes with pragma Elaborate + -- The with comes with pragma Elaborate. Treat the edge as a with + -- edge when switch -d_e (ignore the effects of pragma Elaborate) + -- is in effect. - if Withed_Rec.Elaborate then + if Withed_Rec.Elaborate + and then not Debug_Flag_Underscore_E + then Kind := Elaborate_Edge; -- The withed unit is a spec with a completing body. Add an edge @@ -568,9 +578,13 @@ package body Bindo.Builders is Kind => Kind); end if; - -- The with comes with pragma Elaborate_All + -- The with comes with pragma Elaborate_All. Treat the edge as a with + -- edge when switch -d_a (ignore the effects of pragma Elaborate_All) + -- is in effect. - elsif Withed_Rec.Elaborate_All then + elsif Withed_Rec.Elaborate_All + and then not Debug_Flag_Underscore_A + then Kind := Elaborate_All_Edge; -- Otherwise this is a regular with diff --git a/gcc/ada/bindo-builders.ads b/gcc/ada/bindo-builders.ads index 0e8519fd1eb..54c39e4820a 100644 --- a/gcc/ada/bindo-builders.ads +++ b/gcc/ada/bindo-builders.ads @@ -56,11 +56,9 @@ package Bindo.Builders is ---------------------------- package Library_Graph_Builders is - function Build_Library_Graph - (Dynamically_Elaborated : Boolean) return Library_Graph; + function Build_Library_Graph return Library_Graph; -- Return a new library graph that reflects the dependencies between - -- all units of the bind. Flag Dynamically_Elaborated must be set when - -- the main library unit was compiled using the dynamic model. + -- all units of the bind. end Library_Graph_Builders; diff --git a/gcc/ada/bindo-diagnostics.adb b/gcc/ada/bindo-diagnostics.adb index 0c9da465063..0c1a924a1d6 100644 --- a/gcc/ada/bindo-diagnostics.adb +++ b/gcc/ada/bindo-diagnostics.adb @@ -285,9 +285,9 @@ package body Bindo.Diagnostics is end loop; end Diagnose_All_Cycles; - -------------------------- + ---------------------------- -- Diagnose_Circularities -- - -------------------------- + ---------------------------- procedure Diagnose_Circularities (Inv_Graph : Invocation_Graph; @@ -374,6 +374,12 @@ package body Bindo.Diagnostics is -- taking into account the predecessors and successors involved, as -- well as the nature of the edge. + Elaborate_All_Active := + Elaborate_All_Active + or else Is_Elaborate_All_Edge + (G => Lib_Graph, + Edge => Current_Edge); + Output_Transition (Inv_Graph => Inv_Graph, Lib_Graph => Lib_Graph, @@ -533,12 +539,12 @@ package body Bindo.Diagnostics is pragma Assert (Present (G)); pragma Assert (Present (Cycle)); - -- The cycle contains at least one invocation edge and the main library - -- unit was compiled with the static model. Using the dynamic model may - -- eliminate the invocation edge, and thus the cycle. + -- The cycle contains at least one invocation edge where the successor + -- was statically elaborated. Using the dynamic model may eliminate an + -- invocation edge, and thus the cycle. if Invocation_Edge_Count (G, Cycle) > 0 - and then not Is_Dynamically_Elaborated (G) + and then Contains_Weak_Static_Successor (G, Cycle) then Error_Msg_Info (" use the dynamic elaboration model (compiler switch -gnatE)"); @@ -703,10 +709,11 @@ package body Bindo.Diagnostics is -- Expected_Destination else - pragma Assert (Is_Spec_With_Body (G, Actual_Destination)); - pragma Assert (Is_Body_With_Spec (G, Expected_Destination)); pragma Assert - (Proper_Body (G, Actual_Destination) = Expected_Destination); + (Is_Elaborate_Body_Pair + (G => G, + Spec_Vertex => Actual_Destination, + Body_Vertex => Expected_Destination)); Error_Msg_Unit_1 := Name (G, Source); Error_Msg_Unit_2 := Name (G, Actual_Destination); @@ -922,13 +929,11 @@ package body Bindo.Diagnostics is -- Expected_Destination else - pragma Assert (Is_Spec_With_Body (G, Actual_Destination)); - pragma Assert (Is_Spec_With_Elaborate_Body (G, Actual_Destination)); - pragma Assert (Is_Body_With_Spec (G, Expected_Destination)); - pragma Assert - (Is_Body_Of_Spec_With_Elaborate_Body (G, Expected_Destination)); pragma Assert - (Proper_Body (G, Actual_Destination) = Expected_Destination); + (Is_Elaborate_Body_Pair + (G => G, + Spec_Vertex => Actual_Destination, + Body_Vertex => Expected_Destination)); Error_Msg_Unit_1 := Name (G, Source); Error_Msg_Unit_2 := Name (G, Actual_Destination); @@ -1392,13 +1397,11 @@ package body Bindo.Diagnostics is -- Expected_Destination else - pragma Assert (Is_Spec_With_Body (G, Actual_Destination)); - pragma Assert (Is_Spec_With_Elaborate_Body (G, Actual_Destination)); - pragma Assert (Is_Body_With_Spec (G, Expected_Destination)); - pragma Assert - (Is_Body_Of_Spec_With_Elaborate_Body (G, Expected_Destination)); pragma Assert - (Proper_Body (G, Actual_Destination) = Expected_Destination); + (Is_Elaborate_Body_Pair + (G => G, + Spec_Vertex => Actual_Destination, + Body_Vertex => Expected_Destination)); Error_Msg_Unit_1 := Name (G, Source); Error_Msg_Unit_2 := Name (G, Actual_Destination); diff --git a/gcc/ada/bindo-elaborators.adb b/gcc/ada/bindo-elaborators.adb index 762198bd691..192e4a228ed 100644 --- a/gcc/ada/bindo-elaborators.adb +++ b/gcc/ada/bindo-elaborators.adb @@ -46,8 +46,6 @@ use Bindo.Units; with Bindo.Validators; use Bindo.Validators; use Bindo.Validators.Elaboration_Order_Validators; -use Bindo.Validators.Invocation_Graph_Validators; -use Bindo.Validators.Library_Graph_Validators; with Bindo.Writers; use Bindo.Writers; @@ -76,76 +74,61 @@ package body Bindo.Elaborators is ---------------------------------------------- package body Invocation_And_Library_Graph_Elaborators is - Add_To_All_Candidates_Msg : aliased String := - "add vertex to all candidates"; - Add_To_Comp_Candidates_Msg : aliased String := - "add vertex to component candidates"; - - ----------- - -- Types -- - ----------- - - type String_Ptr is access all String; ----------------------- -- Local subprograms -- ----------------------- - procedure Add_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Set : LGV_Sets.Membership_Set; - Msg : String; - Step : Elaboration_Order_Step; - Indent : Indentation_Level); - pragma Inline (Add_Vertex); - -- Add vertex Vertex of library graph G to membership set Set. Msg is - -- a message emitted for tracing purposes. Step is the current step in - -- the elaboration order. Indent is the desired indentation level for - -- tracing. - - procedure Add_Vertex_If_Elaborable - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Set : LGV_Sets.Membership_Set; - Msg : String; - Step : Elaboration_Order_Step; - Indent : Indentation_Level); - pragma Inline (Add_Vertex_If_Elaborable); - -- Add vertex Vertex of library graph G to membership set Set if it can - -- be elaborated. Msg is a message emitted for tracing purposes. Step is - -- the current step in the elaboration order. Indent is the desired - -- indentation level for tracing. - - function Create_All_Candidates_Set - (G : Library_Graph; - Step : Elaboration_Order_Step) return LGV_Sets.Membership_Set; - pragma Inline (Create_All_Candidates_Set); - -- Collect all elaborable candidate vertices of library graph G in a - -- set. Step is the current step in the elaboration order. - - function Create_Component_Candidates_Set - (G : Library_Graph; - Comp : Component_Id; - Step : Elaboration_Order_Step) return LGV_Sets.Membership_Set; - pragma Inline (Create_Component_Candidates_Set); - -- Collect all elaborable candidate vertices that appear in component - -- Comp of library graph G in a set. Step is the current step in the - -- elaboration order. + procedure Create_Component_Vertex_Sets + (G : Library_Graph; + Comp : Component_Id; + Elaborable_Vertices : out LGV_Sets.Membership_Set; + Waiting_Vertices : out LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step); + pragma Inline (Create_Component_Vertex_Sets); + -- Split all vertices of component Comp of library graph G as follows: + -- + -- * Elaborable vertices are added to set Elaborable_Vertices. + -- + -- * Vertices that are still waiting on their predecessors to be + -- elaborated are added to set Waiting_Vertices. + -- + -- Step is the current step in the elaboration order. + + procedure Create_Vertex_Sets + (G : Library_Graph; + Elaborable_Vertices : out LGV_Sets.Membership_Set; + Waiting_Vertices : out LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step); + pragma Inline (Create_Vertex_Sets); + -- Split all vertices of library graph G as follows: + -- + -- * Elaborable vertices are added to set Elaborable_Vertices. + -- + -- * Vertices that are still waiting on their predecessors to be + -- elaborated are added to set Waiting_Vertices. + -- + -- Step is the current step in the elaboration order. procedure Elaborate_Component - (G : Library_Graph; - Comp : Component_Id; - All_Candidates : LGV_Sets.Membership_Set; - Remaining_Vertices : in out Natural; - Order : in out Unit_Id_Table; - Step : Elaboration_Order_Step); + (G : Library_Graph; + Comp : Component_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Order : in out Unit_Id_Table; + Step : Elaboration_Order_Step); pragma Inline (Elaborate_Component); - -- Elaborate as many vertices as possible that appear in component - -- Comp of library graph G. All_Candidates is the set of all elaborable - -- vertices across the whole library graph. Remaining_Vertices is the - -- number of vertices that remain to be elaborated. Order denotes the - -- elaboration order. Step is the current step in the elaboration order. + -- Elaborate as many vertices as possible that appear in component Comp + -- of library graph G. The sets contain vertices arranged as follows: + -- + -- * All_Elaborable_Vertices - all elaborable vertices in the library + -- graph. + -- + -- * All_Waiting_Vertices - all vertices in the library graph that are + -- waiting on predecessors to be elaborated. + -- + -- Order is the elaboration order. Step denotes the current step in the + -- elaboration order. procedure Elaborate_Library_Graph (G : Library_Graph; @@ -156,81 +139,149 @@ package body Bindo.Elaborators is -- the elaboration order. Status is the condition of the elaboration -- order. - procedure Elaborate_Units_Common - (Use_Inv_Graph : Boolean; - Is_Dyn_Elab : Boolean; - Inv_Graph : out Invocation_Graph; - Lib_Graph : out Library_Graph; - Order : out Unit_Id_Table; - Status : out Elaboration_Order_Status); - pragma Inline (Elaborate_Units_Common); - -- Find the elaboration order of all units in the bind. Use_Inv_Graph - -- should be set when library graph Lib_Graph is to be augmented with - -- information from invocation graph Inv_Graph. Is_Dyn_Elab should be - -- set when the main library unit was compiled using the dynamic model. - -- Order is the elaboration order. Status is the condition of the - -- elaboration order. - - procedure Elaborate_Units_Dynamic (Order : out Unit_Id_Table); - pragma Inline (Elaborate_Units_Dynamic); - -- Find the elaboration order of all units in the bind using the dynamic - -- model. Order is the elaboration order. In the event where no ordering - -- is possible, this routine diagnoses the issue(s) and raises exception - -- Unrecoverable_Error. - - procedure Elaborate_Units_Static (Order : out Unit_Id_Table); - pragma Inline (Elaborate_Units_Static); - -- Find the elaboration order of all units in the bind using the static - -- model. Order is the elaboration order. In the event where no ordering - -- is possible, this routine diagnoses the issue(s) and raises exception - -- Unrecoverable_Error. - procedure Elaborate_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Remaining_Vertices : in out Natural; - Order : in out Unit_Id_Table; - Step : Elaboration_Order_Step; - Indent : Indentation_Level); + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Order : in out Unit_Id_Table; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); pragma Inline (Elaborate_Vertex); -- Elaborate vertex Vertex of library graph G by adding its unit to -- elaboration order Order. The routine updates awaiting successors - -- where applicable. All_Candidates denotes the set of all elaborable - -- vertices across the whole library graph. Comp_Candidates is the set - -- of all elaborable vertices in the component of Vertex. Parameter - -- Remaining_Vertices denotes the number of vertices that remain to - -- be elaborated. Step is the current step in the elaboration order. + -- where applicable. The sets contain vertices arranged as follows: + -- + -- * All_Elaborable_Vertices - all elaborable vertices in the library + -- graph. + -- + -- * All_Waiting_Vertices - all vertices in the library graph that are + -- waiting on predecessors to be elaborated. + -- + -- * Comp_Elaborable_Vertices - all elaborable vertices found in the + -- component of Vertex. + -- + -- * Comp_Waiting_Vertices - all vertices found in the component of + -- Vertex that are still waiting on predecessors to be elaborated. + -- + -- Order denotes the elaboration order. Step is the current step in the + -- elaboration order. Indent denotes the desired indentation level for + -- tracing. + + function Find_Best_Elaborable_Vertex + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) return Library_Graph_Vertex_Id; + pragma Inline (Find_Best_Elaborable_Vertex); + -- Find the best vertex of library graph G from membership set S that + -- can be elaborated. Step is the current step in the elaboration order. -- Indent is the desired indentation level for tracing. - function Find_Best_Candidate + type Comparator_Ptr is access function + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind; + + type Predicate_Ptr is access function + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; + + function Find_Best_Vertex + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Is_Suitable_Vertex : Predicate_Ptr; + Compare_Vertices : Comparator_Ptr; + Initial_Best_Msg : String; + Subsequent_Best_Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) + return Library_Graph_Vertex_Id; + pragma Inline (Find_Best_Vertex); + -- Find the best vertex of library graph G from membership set S which + -- satisfies predicate Is_Suitable_Vertex and is preferred by comparator + -- Compare_Vertices. Initial_Best_Msg is emitted on the first candidate + -- vertex. Subsequent_Best_Msg is emitted whenever a better vertex is + -- discovered. Step is the current step in the elaboration order. Indent + -- is the desired indentation level for tracing. + + function Find_Best_Weakly_Elaborable_Vertex (G : Library_Graph; Set : LGV_Sets.Membership_Set; Step : Elaboration_Order_Step; Indent : Indentation_Level) return Library_Graph_Vertex_Id; - pragma Inline (Find_Best_Candidate); - -- Find the most suitable vertex of library graph G for elaboration from - -- membership set Set. Step denotes the current step in the elaboration + pragma Inline (Find_Best_Weakly_Elaborable_Vertex); + -- Find the best vertex of library graph G from membership set S that + -- can be weakly elaborated. Step is the current step in the elaboration -- order. Indent is the desired indentation level for tracing. - function Is_Better_Candidate - (G : Library_Graph; - Best_Candidate : Library_Graph_Vertex_Id; - New_Candidate : Library_Graph_Vertex_Id) return Boolean; - pragma Inline (Is_Better_Candidate); - -- Determine whether new candidate vertex New_Candidate of library graph - -- G is a more suitable choice for elaboration compared to the current - -- best candidate Best_Candidate. + function Has_Elaborable_Body + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; + pragma Inline (Has_Elaborable_Body); + -- Determine whether vertex Vertex of library graph G has a body that is + -- elaborable. It is assumed that the vertex has been elaborated. + + procedure Insert_Elaborable_Successor + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); + pragma Inline (Insert_Elaborable_Successor); + -- Add elaborable successor Vertex of library graph G to membership set + -- Elaborable_Vertices and remove it from both All_Waiting_Vertices and + -- Comp_Waiting_Vertices. Msg is a message emitted for tracing purposes. + -- Step is the current step in the elaboration order. Indent denotes the + -- desired indentation level for tracing. + + procedure Insert_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Set : LGV_Sets.Membership_Set; + Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); + pragma Inline (Insert_Vertex); + -- Add vertex Vertex of library graph G to membership set Set. Msg is + -- a message emitted for tracing purposes. Step is the current step in + -- the elaboration order. Indent is the desired indentation level for + -- tracing. - procedure Trace_Candidate_Vertices - (G : Library_Graph; - Set : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step); - pragma Inline (Trace_Candidate_Vertices); - -- Write the candidate vertices of library graph G present in membership - -- set Set to standard output. Formal Step denotes the current step in - -- the elaboration order. + function Is_Better_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind; + pragma Inline (Is_Better_Elaborable_Vertex); + -- Determine whether vertex Vertex of library graph G is a better choice + -- for elaboration compared to vertex Compared_To. + + function Is_Better_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind; + pragma Inline (Is_Better_Weakly_Elaborable_Vertex); + -- Determine whether vertex Vertex of library graph G is a better choice + -- for weak elaboration compared to vertex Compared_To. + + function Is_Suitable_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; + pragma Inline (Is_Suitable_Elaborable_Vertex); + -- Determine whether vertex Vertex of library graph G is suitable for + -- elaboration. + + function Is_Suitable_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; + pragma Inline (Is_Suitable_Weakly_Elaborable_Vertex); + -- Determine whether vertex Vertex of library graph G is suitable for + -- weak elaboration. procedure Trace_Component (G : Library_Graph; @@ -246,15 +297,6 @@ package body Bindo.Elaborators is pragma Inline (Trace_Step); -- Write current step Step of the elaboration order to standard output - procedure Trace_Unelaborated_Vertices - (G : Library_Graph; - Count : Natural; - Step : Elaboration_Order_Step); - pragma Inline (Trace_Unelaborated_Vertices); - -- Write the remaining unelaborated vertices of library graph G to - -- standard output. Count is the number of vertices that remain to - -- be elaborated. Step is the current step in the elaboration order. - procedure Trace_Vertex (G : Library_Graph; Vertex : Library_Graph_Vertex_Id; @@ -267,220 +309,202 @@ package body Bindo.Elaborators is -- current step in the elaboration order. Indent denotes the desired -- indentation level for tracing. + procedure Trace_Vertices + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Set_Msg : String; + Vertex_Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); + pragma Inline (Trace_Vertices); + -- Write the candidate vertices of library graph G present in membership + -- set Set to standard output, starting with message Set_Msg. Vertex_Msg + -- is the message emitted prior to each vertex. Step denotes the current + -- step in the elaboration order. Indent denotes the desired indentation + -- level for tracing. + procedure Update_Successor - (G : Library_Graph; - Pred : Library_Graph_Vertex_Id; - Succ : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step; - Indent : Indentation_Level); + (G : Library_Graph; + Edge : Library_Graph_Edge_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); pragma Inline (Update_Successor); - -- Notify successor vertex Succ of library graph G along with its - -- component that their predecessor Pred has just been elaborated. - -- This may cause new vertices to become elaborable, and thus be added - -- to one of the two sets. All_Candidates is the set of all elaborable - -- vertices across the whole library graph. Comp_Candidates is the set - -- of all elaborable vertices in the component of Pred. Step is the - -- current step in the elaboration order. Indent denotes the desired - -- indentation level for tracing. + -- Notify the successor of edge Edge of library graph G along with its + -- component that their predecessor has just been elaborated. This may + -- cause new vertices to become elaborable. The sets contain vertices + -- arranged as follows: + -- + -- * All_Elaborable_Vertices - all elaborable vertices in the library + -- graph. + -- + -- * All_Waiting_Vertices - all vertices in the library graph that are + -- waiting on predecessors to be elaborated. + -- + -- * Comp_Elaborable_Vertices - all elaborable vertices found in the + -- component of Vertex. + -- + -- * Comp_Waiting_Vertices - all vertices found in the component of + -- Vertex that are still waiting on predecessors to be elaborated. + -- + -- Step is the current step in the elaboration order. Indent denotes the + -- desired indentation level for tracing. procedure Update_Successors - (G : Library_Graph; - Pred : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step; - Indent : Indentation_Level); + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level); pragma Inline (Update_Successors); - -- Notify all successors along with their components that their - -- predecessor vertex Pred of ligrary graph G has just been elaborated. - -- This may cause new vertices to become elaborable, and thus be added - -- to one of the two sets. All_Candidates is the set of all elaborable - -- vertices across the whole library graph. Comp_Candidates is the set - -- of all elaborable vertices in the component of Pred. Step is the - -- current step in the elaboration order. Indent denotes the desired - -- indentation level for tracing. - - ---------------- - -- Add_Vertex -- - ---------------- - - procedure Add_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Set : LGV_Sets.Membership_Set; - Msg : String; - Step : Elaboration_Order_Step; - Indent : Indentation_Level) + -- Notify all successors of vertex Vertex of library graph G along with + -- their components that their predecessor has just been elaborated. + -- This may cause new vertices to become elaborable. The sets contain + -- vertices arranged as follows: + -- + -- * All_Elaborable_Vertices - all elaborable vertices in the library + -- graph. + -- + -- * All_Waiting_Vertices - all vertices in the library graph that are + -- waiting on predecessors to be elaborated. + -- + -- * Comp_Elaborable_Vertices - all elaborable vertices found in the + -- component of Vertex. + -- + -- * Comp_Waiting_Vertices - all vertices found in the component of + -- Vertex that are still waiting on predecessors to be elaborated. + -- + -- Step is the current step in the elaboration order. Indent denotes the + -- desired indentation level for tracing. + + ---------------------------------- + -- Create_Component_Vertex_Sets -- + ---------------------------------- + + procedure Create_Component_Vertex_Sets + (G : Library_Graph; + Comp : Component_Id; + Elaborable_Vertices : out LGV_Sets.Membership_Set; + Waiting_Vertices : out LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step) is - begin - pragma Assert (Present (Vertex)); - pragma Assert (Needs_Elaboration (G, Vertex)); - pragma Assert (LGV_Sets.Present (Set)); - - -- Add vertex only when it is not present in the set. This is not - -- strictly necessary because the set implementation handles this - -- case, however the check eliminates spurious traces. - - if not LGV_Sets.Contains (Set, Vertex) then - Trace_Vertex - (G => G, - Vertex => Vertex, - Msg => Msg, - Step => Step, - Indent => Indent); - - LGV_Sets.Insert (Set, Vertex); - end if; - end Add_Vertex; + pragma Assert (Present (G)); + pragma Assert (Present (Comp)); - ------------------------------ - -- Add_Vertex_If_Elaborable -- - ------------------------------ + Num_Of_Vertices : constant Natural := + Number_Of_Component_Vertices (G, Comp); - procedure Add_Vertex_If_Elaborable - (G : Library_Graph; + Iter : Component_Vertex_Iterator; Vertex : Library_Graph_Vertex_Id; - Set : LGV_Sets.Membership_Set; - Msg : String; - Step : Elaboration_Order_Step; - Indent : Indentation_Level) - is - Extra_Vertex : Library_Graph_Vertex_Id; begin - pragma Assert (Present (G)); - pragma Assert (Present (Vertex)); - pragma Assert (Needs_Elaboration (G, Vertex)); - pragma Assert (LGV_Sets.Present (Set)); - - if Is_Elaborable_Vertex (G, Vertex) then - Add_Vertex - (G => G, - Vertex => Vertex, - Set => Set, - Msg => Msg, - Step => Step, - Indent => Indent); - - -- Assume that there is no extra vertex that needs to be added + Elaborable_Vertices := LGV_Sets.Create (Num_Of_Vertices); + Waiting_Vertices := LGV_Sets.Create (Num_Of_Vertices); - Extra_Vertex := No_Library_Graph_Vertex; - - -- A spec-body pair where the spec carries pragma Elaborate_Body - -- must be treated as one vertex for elaboration purposes. If one - -- of them is elaborable, then the other is also elaborable. This - -- property is guaranteed by predicate Is_Elaborable_Vertex. - - if Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then - Extra_Vertex := Proper_Spec (G, Vertex); - pragma Assert (Present (Extra_Vertex)); + Iter := Iterate_Component_Vertices (G, Comp); + while Has_Next (Iter) loop + Next (Iter, Vertex); - elsif Is_Spec_With_Elaborate_Body (G, Vertex) then - Extra_Vertex := Proper_Body (G, Vertex); - pragma Assert (Present (Extra_Vertex)); - end if; + -- Add the vertex to the proper set depending on whether it can be + -- elaborated. - if Present (Extra_Vertex) then - pragma Assert (Needs_Elaboration (G, Extra_Vertex)); + if Is_Elaborable_Vertex (G, Vertex) then + Insert_Vertex + (G => G, + Vertex => Vertex, + Set => Elaborable_Vertices, + Msg => "add elaborable component vertex", + Step => Step, + Indent => No_Indentation); - Add_Vertex + else + Insert_Vertex (G => G, - Vertex => Extra_Vertex, - Set => Set, - Msg => Msg, + Vertex => Vertex, + Set => Waiting_Vertices, + Msg => "add waiting component vertex", Step => Step, - Indent => Indent); + Indent => No_Indentation); end if; - end if; - end Add_Vertex_If_Elaborable; + end loop; + end Create_Component_Vertex_Sets; - ------------------------------- - -- Create_All_Candidates_Set -- - ------------------------------- + ------------------------ + -- Create_Vertex_Sets -- + ------------------------ - function Create_All_Candidates_Set - (G : Library_Graph; - Step : Elaboration_Order_Step) return LGV_Sets.Membership_Set + procedure Create_Vertex_Sets + (G : Library_Graph; + Elaborable_Vertices : out LGV_Sets.Membership_Set; + Waiting_Vertices : out LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step) is + pragma Assert (Present (G)); + + Num_Of_Vertices : constant Natural := Number_Of_Vertices (G); + Iter : Library_Graphs.All_Vertex_Iterator; - Set : LGV_Sets.Membership_Set; Vertex : Library_Graph_Vertex_Id; begin - pragma Assert (Present (G)); + Elaborable_Vertices := LGV_Sets.Create (Num_Of_Vertices); + Waiting_Vertices := LGV_Sets.Create (Num_Of_Vertices); - Set := LGV_Sets.Create (Number_Of_Vertices (G)); Iter := Iterate_All_Vertices (G); while Has_Next (Iter) loop Next (Iter, Vertex); - Add_Vertex_If_Elaborable - (G => G, - Vertex => Vertex, - Set => Set, - Msg => Add_To_All_Candidates_Msg, - Step => Step, - Indent => No_Indentation); - end loop; - - return Set; - end Create_All_Candidates_Set; - - ------------------------------------- - -- Create_Component_Candidates_Set -- - ------------------------------------- - - function Create_Component_Candidates_Set - (G : Library_Graph; - Comp : Component_Id; - Step : Elaboration_Order_Step) return LGV_Sets.Membership_Set - is - Iter : Component_Vertex_Iterator; - Set : LGV_Sets.Membership_Set; - Vertex : Library_Graph_Vertex_Id; - - begin - pragma Assert (Present (G)); - pragma Assert (Present (Comp)); + -- Add the vertex to the proper set depending on whether it can be + -- elaborated. - Set := LGV_Sets.Create (Number_Of_Component_Vertices (G, Comp)); - Iter := Iterate_Component_Vertices (G, Comp); - while Has_Next (Iter) loop - Next (Iter, Vertex); + if Is_Elaborable_Vertex (G, Vertex) then + Insert_Vertex + (G => G, + Vertex => Vertex, + Set => Elaborable_Vertices, + Msg => "add elaborable vertex", + Step => Step, + Indent => No_Indentation); - Add_Vertex_If_Elaborable - (G => G, - Vertex => Vertex, - Set => Set, - Msg => Add_To_Comp_Candidates_Msg, - Step => Step, - Indent => No_Indentation); + else + Insert_Vertex + (G => G, + Vertex => Vertex, + Set => Waiting_Vertices, + Msg => "add waiting vertex", + Step => Step, + Indent => No_Indentation); + end if; end loop; - - return Set; - end Create_Component_Candidates_Set; + end Create_Vertex_Sets; ------------------------- -- Elaborate_Component -- ------------------------- procedure Elaborate_Component - (G : Library_Graph; - Comp : Component_Id; - All_Candidates : LGV_Sets.Membership_Set; - Remaining_Vertices : in out Natural; - Order : in out Unit_Id_Table; - Step : Elaboration_Order_Step) + (G : Library_Graph; + Comp : Component_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Order : in out Unit_Id_Table; + Step : Elaboration_Order_Step) is - Candidate : Library_Graph_Vertex_Id; - Comp_Candidates : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Vertex : Library_Graph_Vertex_Id; begin pragma Assert (Present (G)); pragma Assert (Present (Comp)); - pragma Assert (LGV_Sets.Present (All_Candidates)); + pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (All_Waiting_Vertices)); Trace_Component (G => G, @@ -488,35 +512,81 @@ package body Bindo.Elaborators is Msg => "elaborating component", Step => Step); - Comp_Candidates := Create_Component_Candidates_Set (G, Comp, Step); + -- Divide all vertices of the component into an elaborable and + -- waiting vertex set. + + Create_Component_Vertex_Sets + (G => G, + Comp => Comp, + Elaborable_Vertices => Comp_Elaborable_Vertices, + Waiting_Vertices => Comp_Waiting_Vertices, + Step => Step); loop - Candidate := - Find_Best_Candidate + Trace_Vertices + (G => G, + Set => Comp_Elaborable_Vertices, + Set_Msg => "elaborable component vertices", + Vertex_Msg => "elaborable component vertex", + Step => Step, + Indent => Nested_Indentation); + + Trace_Vertices + (G => G, + Set => Comp_Waiting_Vertices, + Set_Msg => "waiting component vertices", + Vertex_Msg => "waiting component vertex", + Step => Step, + Indent => Nested_Indentation); + + Vertex := + Find_Best_Elaborable_Vertex (G => G, - Set => Comp_Candidates, + Set => Comp_Elaborable_Vertices, Step => Step, Indent => Nested_Indentation); - -- Stop the elaboration of the component when there is no suitable - -- candidate. This indicates that either all vertices within the - -- component have been elaborated, or the library graph contains a - -- circularity. + -- The component lacks an elaborable vertex. This indicates that + -- either all vertices of the component have been elaborated or + -- the graph has a circularity. Locate the best weak vertex that + -- was compiled with the dynamic model to elaborate from the set + -- waiting vertices. This action assumes that certain invocations + -- will not take place at elaboration time. An order produced in + -- this fashion may fail an ABE check at run time. + + if not Present (Vertex) then + Vertex := + Find_Best_Weakly_Elaborable_Vertex + (G => G, + Set => Comp_Waiting_Vertices, + Step => Step, + Indent => Nested_Indentation); + end if; + + -- Stop the elaboration when either all vertices of the component + -- have been elaborated, or the graph contains a circularity. + + exit when not Present (Vertex); - exit when not Present (Candidate); + -- Try to elaborate as many vertices within the component as + -- possible. Each successful elaboration signals the appropriate + -- successors and components that they have one less predecessor + -- to wait on. Elaborate_Vertex - (G => G, - Vertex => Candidate, - All_Candidates => All_Candidates, - Comp_Candidates => Comp_Candidates, - Remaining_Vertices => Remaining_Vertices, - Order => Order, - Step => Step, - Indent => Nested_Indentation); + (G => G, + Vertex => Vertex, + All_Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Elaborable_Vertices => Comp_Elaborable_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Order => Order, + Step => Step, + Indent => Nested_Indentation); end loop; - LGV_Sets.Destroy (Comp_Candidates); + LGV_Sets.Destroy (Comp_Elaborable_Vertices); + LGV_Sets.Destroy (Comp_Waiting_Vertices); end Elaborate_Component; ----------------------------- @@ -528,73 +598,97 @@ package body Bindo.Elaborators is Order : out Unit_Id_Table; Status : out Elaboration_Order_Status) is - All_Candidates : LGV_Sets.Membership_Set; - Candidate : Library_Graph_Vertex_Id; - Remaining_Vertices : Natural; - Step : Elaboration_Order_Step; + Elaborable_Vertices : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Vertex : Library_Graph_Vertex_Id; + Waiting_Vertices : LGV_Sets.Membership_Set; begin pragma Assert (Present (G)); Step := Initial_Step; - All_Candidates := Create_All_Candidates_Set (G, Step); - Remaining_Vertices := Number_Of_Vertices (G); + -- Divide all vertices of the library graph into an elaborable and + -- waiting vertex set. + + Create_Vertex_Sets + (G => G, + Elaborable_Vertices => Elaborable_Vertices, + Waiting_Vertices => Waiting_Vertices, + Step => Step); loop Step := Step + 1; - Trace_Candidate_Vertices - (G => G, - Set => All_Candidates, - Step => Step); - - Trace_Unelaborated_Vertices - (G => G, - Count => Remaining_Vertices, - Step => Step); - - Candidate := - Find_Best_Candidate + Trace_Vertices + (G => G, + Set => Elaborable_Vertices, + Set_Msg => "elaborable vertices", + Vertex_Msg => "elaborable vertex", + Step => Step, + Indent => No_Indentation); + + Trace_Vertices + (G => G, + Set => Waiting_Vertices, + Set_Msg => "waiting vertices", + Vertex_Msg => "waiting vertex", + Step => Step, + Indent => No_Indentation); + + Vertex := + Find_Best_Elaborable_Vertex (G => G, - Set => All_Candidates, + Set => Elaborable_Vertices, Step => Step, Indent => No_Indentation); - -- Stop the elaboration when there is no suitable candidate. This - -- indicates that either all units were elaborated or the library - -- graph contains a circularity. + -- The graph lacks an elaborable vertex. This indicates that + -- either all vertices have been elaborated or the graph has a + -- circularity. Find the best weak vertex that was compiled with + -- the dynamic model to elaborate from set of waiting vertices. + -- This action assumes that certain invocations will not take + -- place at elaboration time. An order produced in this fashion + -- may fail an ABE check at run time. + + if not Present (Vertex) then + Vertex := + Find_Best_Weakly_Elaborable_Vertex + (G => G, + Set => Waiting_Vertices, + Step => Step, + Indent => No_Indentation); + end if; + + -- Stop the elaboration when either all vertices of the graph have + -- been elaborated, or the graph contains a circularity. - exit when not Present (Candidate); + exit when not Present (Vertex); - -- Elaborate the component of the candidate vertex by trying to - -- elaborate as many vertices within the component as possible. - -- Each successful elaboration signals the appropriate successors - -- and their components that they have one less predecessor to - -- wait on. This may add new candidates to set All_Candidates. + -- Elaborate the component of the vertex by trying to elaborate as + -- many vertices within the component as possible. Each successful + -- elaboration signals the appropriate successors and components + -- that they have one less predecessor to wait on. Elaborate_Component - (G => G, - Comp => Component (G, Candidate), - All_Candidates => All_Candidates, - Remaining_Vertices => Remaining_Vertices, - Order => Order, - Step => Step); + (G => G, + Comp => Component (G, Vertex), + All_Elaborable_Vertices => Elaborable_Vertices, + All_Waiting_Vertices => Waiting_Vertices, + Order => Order, + Step => Step); end loop; - LGV_Sets.Destroy (All_Candidates); - - -- The library graph contains an Elaborate_All circularity when - -- at least one edge subject to the related pragma appears in a - -- component. + -- The graph contains an Elaborate_All circularity when at least one + -- edge subject to the related pragma appears in a component. if Has_Elaborate_All_Cycle (G) then Status := Order_Has_Elaborate_All_Circularity; - -- The library contains a circularity when at least one vertex failed + -- The graph contains a circularity when at least one vertex failed -- to elaborate. - elsif Remaining_Vertices /= 0 then + elsif LGV_Sets.Size (Waiting_Vertices) /= 0 then Status := Order_Has_Circularity; -- Otherwise the elaboration order is satisfactory @@ -602,6 +696,9 @@ package body Bindo.Elaborators is else Status := Order_OK; end if; + + LGV_Sets.Destroy (Elaborable_Vertices); + LGV_Sets.Destroy (Waiting_Vertices); end Elaborate_Library_Graph; --------------------- @@ -612,271 +709,114 @@ package body Bindo.Elaborators is (Order : out Unit_Id_Table; Main_Lib_File : File_Name_Type) is - Main_Lib_Unit : constant Unit_Id := - Corresponding_Unit (Unit_Name_Type (Main_Lib_File)); + pragma Unreferenced (Main_Lib_File); - begin - pragma Assert (Present (Main_Lib_Unit)); + Inv_Graph : Invocation_Graph; + Lib_Graph : Library_Graph; + Status : Elaboration_Order_Status; + begin -- Initialize all unit-related data structures and gather all units -- that need elaboration. Initialize_Units; Collect_Elaborable_Units; - Write_ALI_Tables; - - -- Choose the proper elaboration strategy based on whether the main - -- library unit was compiled using the dynamic model. - - if Is_Dynamically_Elaborated (Main_Lib_Unit) then - Elaborate_Units_Dynamic (Order); - else - Elaborate_Units_Static (Order); - end if; - - Validate_Elaboration_Order (Order); - Write_Elaboration_Order (Order); - - -- Enumerate the sources referenced in the closure of the order - - Write_Unit_Closure (Order); - - -- Destroy all unit-delated data structures - - Finalize_Units; - - exception - when others => - Finalize_Units; - raise; - end Elaborate_Units; - - ---------------------------- - -- Elaborate_Units_Common -- - ---------------------------- - - procedure Elaborate_Units_Common - (Use_Inv_Graph : Boolean; - Is_Dyn_Elab : Boolean; - Inv_Graph : out Invocation_Graph; - Lib_Graph : out Library_Graph; - Order : out Unit_Id_Table; - Status : out Elaboration_Order_Status) - is - begin - -- Create, validate, and output the library graph that captures the - -- dependencies between library items. - - Lib_Graph := Build_Library_Graph (Is_Dyn_Elab); - Validate_Library_Graph (Lib_Graph); - Write_Library_Graph (Lib_Graph); - - -- Create, validate, output, and use the invocation graph that - -- represents the flow of execusion only when requested by the - -- caller. + -- Create the library graph that captures the dependencies between + -- library items. - if Use_Inv_Graph then - Inv_Graph := Build_Invocation_Graph (Lib_Graph); - Validate_Invocation_Graph (Inv_Graph); - Write_Invocation_Graph (Inv_Graph); + Lib_Graph := Build_Library_Graph; - -- Otherwise the invocation graph is not used. Create a dummy graph - -- as this allows for a uniform behavior on the caller side. + -- Create the invocation graph that represents the flow of execution - else - Inv_Graph := - Invocation_Graphs.Create - (Initial_Vertices => 1, - Initial_Edges => 1); - end if; + Inv_Graph := Build_Invocation_Graph (Lib_Graph); -- Traverse the invocation graph starting from elaboration code in -- order to discover transitions of the execution flow from a unit -- to a unit that result in extra edges within the library graph. Augment_Library_Graph (Inv_Graph, Lib_Graph); - Write_Library_Graph (Lib_Graph); - -- Create and output the component graph by collapsing all library - -- items into library units and traversing the library graph. + -- Create the component graph by collapsing all library items into + -- library units and traversing the library graph. - Find_Components (Lib_Graph); - Write_Components (Lib_Graph); + Find_Components (Lib_Graph); - -- Traverse the library graph to determine the elaboration order of - -- units. + -- Output the contents of the ALI tables and both graphs to standard + -- output now that they have been fully decorated. - Elaborate_Library_Graph - (G => Lib_Graph, - Order => Order, - Status => Status); - end Elaborate_Units_Common; - - ----------------------------- - -- Elaborate_Units_Dynamic -- - ----------------------------- + Write_ALI_Tables; + Write_Invocation_Graph (Inv_Graph); + Write_Library_Graph (Lib_Graph); - procedure Elaborate_Units_Dynamic (Order : out Unit_Id_Table) is - Dyn_Inv_Graph : Invocation_Graph; - Dyn_Lib_Graph : Library_Graph; - Dyn_Order : Unit_Id_Table; - Mix_Inv_Graph : Invocation_Graph; - Mix_Lib_Graph : Library_Graph; - Mix_Order : Unit_Id_Table; - Status : Elaboration_Order_Status; + -- Traverse the library graph to determine the elaboration order of + -- units. - begin - -- Attempt to elaborate the units in the library graph by mixing in - -- the information from the invocation graph. This assumes that all - -- invocations will take place at elaboration time. - - Elaborate_Units_Common - (Use_Inv_Graph => True, - Is_Dyn_Elab => True, - Inv_Graph => Mix_Inv_Graph, - Lib_Graph => Mix_Lib_Graph, - Order => Mix_Order, - Status => Status); + Elaborate_Library_Graph (Lib_Graph, Order, Status); -- The elaboration order is satisfactory if Status = Order_OK then - Order := Mix_Order; + Validate_Elaboration_Order (Order); - -- Output the dependencies of vertices when switch -e (output + -- Output the dependencies among units when switch -e (output -- complete list of elaboration order dependencies) is active. - Write_Dependencies (Mix_Lib_Graph); - - -- The library graph contains an Elaborate_All circularity. There is - -- no point in re-elaborating the units without the information from - -- the invocation graph because the circularity will persist. - - elsif Status = Order_Has_Elaborate_All_Circularity then - Diagnose_Circularities - (Inv_Graph => Mix_Inv_Graph, - Lib_Graph => Mix_Lib_Graph); - - -- Otherwise the library graph contains a circularity, or the extra - -- information provided by the invocation graph caused a circularity. - -- Re-elaborate the units without using the invocation graph. This - -- assumes that all invocations will not take place at elaboration - -- time. - - else - pragma Assert (Status = Order_Has_Circularity); - - Elaborate_Units_Common - (Use_Inv_Graph => False, - Is_Dyn_Elab => True, - Inv_Graph => Dyn_Inv_Graph, - Lib_Graph => Dyn_Lib_Graph, - Order => Dyn_Order, - Status => Status); - - -- The elaboration order is satisfactory. The elaboration of the - -- program may still fail at runtime with an ABE. - - if Status = Order_OK then - Order := Dyn_Order; - - -- Output the dependencies of vertices when switch -e (output - -- complete list of elaboration order dependencies) is active. - - Write_Dependencies (Dyn_Lib_Graph); - - -- Otherwise the library graph contains a circularity without the - -- extra information provided by the invocation graph. Diagnose - -- the circularity. - - else - Diagnose_Circularities - (Inv_Graph => Dyn_Inv_Graph, - Lib_Graph => Dyn_Lib_Graph); - end if; - - Destroy (Dyn_Inv_Graph); - Destroy (Dyn_Lib_Graph); - end if; - - Destroy (Mix_Inv_Graph); - Destroy (Mix_Lib_Graph); - - -- Halt the bind as there is no satisfactory elaboration order - - if Status /= Order_OK then - raise Unrecoverable_Error; - end if; - end Elaborate_Units_Dynamic; + Write_Dependencies (Lib_Graph); - ---------------------------- - -- Elaborate_Units_Static -- - ---------------------------- + -- Output the elaboration order when switch -l (output chosen + -- elaboration order) is in effect. - procedure Elaborate_Units_Static (Order : out Unit_Id_Table) is - Inv_Graph : Invocation_Graph; - Lib_Graph : Library_Graph; - Status : Elaboration_Order_Status; + Write_Elaboration_Order (Order); - begin - -- Attempt to elaborate the units in the library graph by mixing in - -- the information from the invocation graph. This assumes that all - -- invocations will take place at elaboration time. - - Elaborate_Units_Common - (Use_Inv_Graph => True, - Is_Dyn_Elab => False, - Inv_Graph => Inv_Graph, - Lib_Graph => Lib_Graph, - Order => Order, - Status => Status); - - -- The elaboration order is satisfactory. Output the dependencies of - -- vertices when switch -e (output complete list of elaboration order - -- dependencies) is active. + -- Output the sources referenced in the closure of the order when + -- switch -R (list sources referenced in closure) is in effect. - if Status = Order_OK then - Write_Dependencies (Lib_Graph); + Write_Unit_Closure (Order); - -- Otherwise the augmented library graph contains a circularity + -- Otherwise the library graph contains at least one circularity else - Diagnose_Circularities - (Inv_Graph => Inv_Graph, - Lib_Graph => Lib_Graph); + Diagnose_Circularities (Inv_Graph, Lib_Graph); end if; Destroy (Inv_Graph); Destroy (Lib_Graph); - -- Halt the bind as there is no satisfactory elaboration order + -- Destroy all unit-related data structures + + Finalize_Units; + + -- Halt the bind when there is no satisfactory elaboration order if Status /= Order_OK then raise Unrecoverable_Error; end if; - end Elaborate_Units_Static; + end Elaborate_Units; ---------------------- -- Elaborate_Vertex -- ---------------------- procedure Elaborate_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Remaining_Vertices : in out Natural; - Order : in out Unit_Id_Table; - Step : Elaboration_Order_Step; - Indent : Indentation_Level) + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Order : in out Unit_Id_Table; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) is begin pragma Assert (Present (G)); pragma Assert (Present (Vertex)); pragma Assert (Needs_Elaboration (G, Vertex)); - pragma Assert (LGV_Sets.Present (All_Candidates)); - pragma Assert (LGV_Sets.Present (Comp_Candidates)); + pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (All_Waiting_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices)); Trace_Vertex (G => G, @@ -885,14 +825,20 @@ package body Bindo.Elaborators is Step => Step, Indent => Indent); - -- Remove the vertex from both candidate sets. This is needed when + -- Remove the vertex from both elaborable sets. This is needed when -- the vertex is both an overall best candidate among all vertices, - -- and the best candidate within the component. There is no need to - -- check that the vertex is present in either set because the set - -- implementation handles this case. + -- and the best candidate within the component. + + LGV_Sets.Delete (All_Elaborable_Vertices, Vertex); + LGV_Sets.Delete (Comp_Elaborable_Vertices, Vertex); - LGV_Sets.Delete (All_Candidates, Vertex); - LGV_Sets.Delete (Comp_Candidates, Vertex); + -- Remove the vertex from both waiting sets. This is needed when a + -- weakly elaborable vertex is both an overall best candidate among + -- all waiting vertices and the best waiting candidate within the + -- component. + + LGV_Sets.Delete (All_Waiting_Vertices, Vertex); + LGV_Sets.Delete (Comp_Waiting_Vertices, Vertex); -- Mark the vertex as elaborated in order to prevent further attempts -- to re-elaborate it. @@ -903,202 +849,469 @@ package body Bindo.Elaborators is Unit_Id_Tables.Append (Order, Unit (G, Vertex)); - -- There is now one fewer vertex to elaborate - - Remaining_Vertices := Remaining_Vertices - 1; - -- Notify all successors and their components that they have one -- fewer predecessor to wait on. This may cause some successors to -- be included in one of the sets. Update_Successors - (G => G, - Pred => Vertex, - All_Candidates => All_Candidates, - Comp_Candidates => Comp_Candidates, - Step => Step, - Indent => Indent + Nested_Indentation); - - -- The vertex denotes a spec with a completing body, and is subject - -- to pragma Elaborate_Body. Elaborate the body in order to satisfy - -- the semantics of the pragma. - - if Is_Spec_With_Elaborate_Body (G, Vertex) then + (G => G, + Vertex => Vertex, + All_Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Elaborable_Vertices => Comp_Elaborable_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Step => Step, + Indent => Indent + Nested_Indentation); + + -- Elaborate an eligible completing body immediately after its spec. + -- This action satisfies the semantics of pragma Elaborate_Body. In + -- addition, it ensures that a body will not "drift" too far from its + -- spec in case invocation edges are removed from the library graph. + + if Has_Elaborable_Body (G, Vertex) then Elaborate_Vertex - (G => G, - Vertex => Proper_Body (G, Vertex), - All_Candidates => All_Candidates, - Comp_Candidates => Comp_Candidates, - Remaining_Vertices => Remaining_Vertices, - Order => Order, - Step => Step, - Indent => Indent); + (G => G, + Vertex => Proper_Body (G, Vertex), + All_Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Elaborable_Vertices => Comp_Elaborable_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Order => Order, + Step => Step, + Indent => Indent); end if; end Elaborate_Vertex; - ------------------------- - -- Find_Best_Candidate -- - ------------------------- + --------------------------------- + -- Find_Best_Elaborable_Vertex -- + --------------------------------- - function Find_Best_Candidate + function Find_Best_Elaborable_Vertex (G : Library_Graph; Set : LGV_Sets.Membership_Set; Step : Elaboration_Order_Step; Indent : Indentation_Level) return Library_Graph_Vertex_Id is - Best : Library_Graph_Vertex_Id; - Current : Library_Graph_Vertex_Id; - Iter : LGV_Sets.Iterator; + begin + pragma Assert (Present (G)); + pragma Assert (LGV_Sets.Present (Set)); + + return + Find_Best_Vertex + (G => G, + Set => Set, + Is_Suitable_Vertex => + Is_Suitable_Elaborable_Vertex'Access, + Compare_Vertices => + Is_Better_Elaborable_Vertex'Access, + Initial_Best_Msg => "initial best elaborable vertex", + Subsequent_Best_Msg => "better elaborable vertex", + Step => Step, + Indent => Indent); + end Find_Best_Elaborable_Vertex; + + ---------------------- + -- Find_Best_Vertex -- + ---------------------- + + function Find_Best_Vertex + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Is_Suitable_Vertex : Predicate_Ptr; + Compare_Vertices : Comparator_Ptr; + Initial_Best_Msg : String; + Subsequent_Best_Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) + return Library_Graph_Vertex_Id + is + Best_Vertex : Library_Graph_Vertex_Id; + Current_Vertex : Library_Graph_Vertex_Id; + Iter : LGV_Sets.Iterator; begin pragma Assert (Present (G)); pragma Assert (LGV_Sets.Present (Set)); + pragma Assert (Is_Suitable_Vertex /= null); + pragma Assert (Compare_Vertices /= null); -- Assume that there is no candidate - Best := No_Library_Graph_Vertex; + Best_Vertex := No_Library_Graph_Vertex; - -- Inspect all vertices in the set, looking for the best candidate to - -- elaborate. + -- Inspect all vertices in the set, looking for the best candidate + -- according to the comparator. Iter := LGV_Sets.Iterate (Set); while LGV_Sets.Has_Next (Iter) loop - LGV_Sets.Next (Iter, Current); - pragma Assert (Needs_Elaboration (G, Current)); + LGV_Sets.Next (Iter, Current_Vertex); + pragma Assert (Needs_Elaboration (G, Current_Vertex)); + + if Is_Suitable_Vertex.all (G, Current_Vertex) then + + -- A previous iteration already picked the best candidate. + -- Update the best candidate when the current vertex is a + -- better choice. + + if Present (Best_Vertex) then + if Compare_Vertices.all + (G => G, + Vertex => Current_Vertex, + Compared_To => Best_Vertex) = Higher_Precedence + then + Best_Vertex := Current_Vertex; + + Trace_Vertex + (G => G, + Vertex => Best_Vertex, + Msg => Subsequent_Best_Msg, + Step => Step, + Indent => Indent); + end if; + + -- Otherwise this is the first candidate + + else + Best_Vertex := Current_Vertex; + + Trace_Vertex + (G => G, + Vertex => Best_Vertex, + Msg => Initial_Best_Msg, + Step => Step, + Indent => Indent); + end if; + end if; + end loop; - -- Update the best candidate when there is no such candidate + return Best_Vertex; + end Find_Best_Vertex; - if not Present (Best) then - Best := Current; + ---------------------------------------- + -- Find_Best_Weakly_Elaborable_Vertex -- + ---------------------------------------- - Trace_Vertex - (G => G, - Vertex => Best, - Msg => "initial best candidate vertex", - Step => Step, - Indent => Indent); + function Find_Best_Weakly_Elaborable_Vertex + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) return Library_Graph_Vertex_Id + is + begin + pragma Assert (Present (G)); + pragma Assert (LGV_Sets.Present (Set)); - -- Update the best candidate when the current vertex is a better - -- choice. + return + Find_Best_Vertex + (G => G, + Set => Set, + Is_Suitable_Vertex => + Is_Suitable_Weakly_Elaborable_Vertex'Access, + Compare_Vertices => + Is_Better_Weakly_Elaborable_Vertex'Access, + Initial_Best_Msg => "initial best weakly elaborable vertex", + Subsequent_Best_Msg => "better weakly elaborable vertex", + Step => Step, + Indent => Indent); + end Find_Best_Weakly_Elaborable_Vertex; - elsif Is_Better_Candidate - (G => G, - Best_Candidate => Best, - New_Candidate => Current) - then - Best := Current; + ------------------------- + -- Has_Elaborable_Body -- + ------------------------- - Trace_Vertex - (G => G, - Vertex => Best, - Msg => "best candidate vertex", - Step => Step, - Indent => Indent); - end if; - end loop; + function Has_Elaborable_Body + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); - return Best; - end Find_Best_Candidate; + -- The body of an already-elaborated spec subject to Elaborate_Body + -- is always elaborable. - ------------------------- - -- Is_Better_Candidate -- - ------------------------- + if Is_Spec_With_Elaborate_Body (G, Vertex) then + return True; + + elsif Is_Spec_With_Body (G, Vertex) then + return Is_Elaborable_Vertex (G, Proper_Body (G, Vertex)); + end if; + + return False; + end Has_Elaborable_Body; + + --------------------------------- + -- Insert_Elaborable_Successor -- + --------------------------------- + + procedure Insert_Elaborable_Successor + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) + is + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + pragma Assert (LGV_Sets.Present (Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (All_Waiting_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices)); + + Complement : constant Library_Graph_Vertex_Id := + Complementary_Vertex + (G => G, + Vertex => Vertex, + Force_Complement => False); + + begin + -- Remove the successor from both waiting vertex sets because it may + -- be the best vertex to elaborate across the whole graph and within + -- its component. + + LGV_Sets.Delete (All_Waiting_Vertices, Vertex); + LGV_Sets.Delete (Comp_Waiting_Vertices, Vertex); + + Insert_Vertex + (G => G, + Vertex => Vertex, + Set => Elaborable_Vertices, + Msg => Msg, + Step => Step, + Indent => Indent); + + if Present (Complement) then + + -- Remove the complement of the successor from both waiting vertex + -- sets because it may be the best vertex to elaborate across the + -- whole graph and within its component. + + LGV_Sets.Delete (All_Waiting_Vertices, Complement); + LGV_Sets.Delete (Comp_Waiting_Vertices, Complement); + + Insert_Vertex + (G => G, + Vertex => Complement, + Set => Elaborable_Vertices, + Msg => Msg, + Step => Step, + Indent => Indent); + end if; + end Insert_Elaborable_Successor; + + ------------------- + -- Insert_Vertex -- + ------------------- + + procedure Insert_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Set : LGV_Sets.Membership_Set; + Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + pragma Assert (Needs_Elaboration (G, Vertex)); + pragma Assert (LGV_Sets.Present (Set)); + + -- Nothing to do when the vertex is already present in the set - function Is_Better_Candidate - (G : Library_Graph; - Best_Candidate : Library_Graph_Vertex_Id; - New_Candidate : Library_Graph_Vertex_Id) return Boolean + if LGV_Sets.Contains (Set, Vertex) then + return; + end if; + + Trace_Vertex + (G => G, + Vertex => Vertex, + Msg => Msg, + Step => Step, + Indent => Indent); + + -- Add the vertex to the set + + LGV_Sets.Insert (Set, Vertex); + end Insert_Vertex; + + --------------------------------- + -- Is_Better_Elaborable_Vertex -- + --------------------------------- + + function Is_Better_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind is begin pragma Assert (Present (G)); - pragma Assert (Present (Best_Candidate)); - pragma Assert (Present (New_Candidate)); + pragma Assert (Present (Vertex)); + pragma Assert (Present (Compared_To)); + + -- Prefer a spec with Elaborate_Body over its corresponding body + + if Is_Elaborate_Body_Pair + (G => G, + Spec_Vertex => Vertex, + Body_Vertex => Compared_To) + then + return Higher_Precedence; + + elsif Is_Elaborate_Body_Pair + (G => G, + Spec_Vertex => Compared_To, + Body_Vertex => Vertex) + then + return Lower_Precedence; -- Prefer a predefined unit over a non-predefined unit - if Is_Predefined_Unit (G, Best_Candidate) - and then not Is_Predefined_Unit (G, New_Candidate) + elsif Is_Predefined_Unit (G, Vertex) + and then not Is_Predefined_Unit (G, Compared_To) then - return False; + return Higher_Precedence; - elsif not Is_Predefined_Unit (G, Best_Candidate) - and then Is_Predefined_Unit (G, New_Candidate) + elsif not Is_Predefined_Unit (G, Vertex) + and then Is_Predefined_Unit (G, Compared_To) then - return True; + return Lower_Precedence; - -- Prefer an internal unit over a non-iternal unit + -- Prefer an internal unit over a non-internal unit - elsif Is_Internal_Unit (G, Best_Candidate) - and then not Is_Internal_Unit (G, New_Candidate) + elsif Is_Internal_Unit (G, Vertex) + and then not Is_Internal_Unit (G, Compared_To) then - return False; + return Higher_Precedence; - elsif not Is_Internal_Unit (G, Best_Candidate) - and then Is_Internal_Unit (G, New_Candidate) + elsif not Is_Internal_Unit (G, Vertex) + and then Is_Internal_Unit (G, Compared_To) then - return True; + return Lower_Precedence; -- Prefer a preelaborated unit over a non-preelaborated unit - elsif Is_Preelaborated_Unit (G, Best_Candidate) - and then not Is_Preelaborated_Unit (G, New_Candidate) + elsif Is_Preelaborated_Unit (G, Vertex) + and then not Is_Preelaborated_Unit (G, Compared_To) then - return False; + return Higher_Precedence; - elsif not Is_Preelaborated_Unit (G, Best_Candidate) - and then Is_Preelaborated_Unit (G, New_Candidate) + elsif not Is_Preelaborated_Unit (G, Vertex) + and then Is_Preelaborated_Unit (G, Compared_To) then - return True; + return Lower_Precedence; -- Otherwise default to lexicographical order to ensure deterministic -- behavior. + elsif Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then + return Higher_Precedence; + else - return - Uname_Less (Name (G, Best_Candidate), Name (G, New_Candidate)); + return Lower_Precedence; end if; - end Is_Better_Candidate; + end Is_Better_Elaborable_Vertex; - ------------------------------ - -- Trace_Candidate_Vertices -- - ------------------------------ + ---------------------------------------- + -- Is_Better_Weakly_Elaborable_Vertex -- + ---------------------------------------- - procedure Trace_Candidate_Vertices - (G : Library_Graph; - Set : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step) + function Is_Better_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Compared_To : Library_Graph_Vertex_Id) return Precedence_Kind is - Iter : LGV_Sets.Iterator; - Vertex : Library_Graph_Vertex_Id; + Comp_Strong_Preds : Natural; + Comp_Weak_Preds : Natural; + Vertex_Strong_Preds : Natural; + Vertex_Weak_Preds : Natural; begin pragma Assert (Present (G)); - pragma Assert (LGV_Sets.Present (Set)); + pragma Assert (Present (Vertex)); + pragma Assert (Present (Compared_To)); - -- Nothing to do when switch -d_T (output elaboration order and cycle - -- detection trace information) is not in effect. + -- Obtain the number of pending predecessors for both candidates, + -- taking into account Elaborate_Body pairs. - if not Debug_Flag_Underscore_TT then - return; + Pending_Predecessors_For_Elaboration + (G => G, + Vertex => Vertex, + Strong_Preds => Vertex_Strong_Preds, + Weak_Preds => Vertex_Weak_Preds); + + Pending_Predecessors_For_Elaboration + (G => G, + Vertex => Compared_To, + Strong_Preds => Comp_Strong_Preds, + Weak_Preds => Comp_Weak_Preds); + + -- Neither candidate should be waiting on strong predecessors, + -- otherwise the candidate cannot be weakly elaborated. + + pragma Assert (Vertex_Strong_Preds = 0); + pragma Assert (Comp_Strong_Preds = 0); + + -- Prefer a unit with fewer weak predecessors over a unit with more + -- weak predecessors. + + if Vertex_Weak_Preds < Comp_Weak_Preds then + return Higher_Precedence; + + elsif Vertex_Weak_Preds > Comp_Weak_Preds then + return Lower_Precedence; + + -- Otherwise default to lexicographical order to ensure deterministic + -- behavior. + + elsif Uname_Less (Name (G, Vertex), Name (G, Compared_To)) then + return Higher_Precedence; + + else + return Lower_Precedence; end if; + end Is_Better_Weakly_Elaborable_Vertex; - Trace_Step (Step); - Write_Str ("candidate vertices: "); - Write_Int (Int (LGV_Sets.Size (Set))); - Write_Eol; + ----------------------------------- + -- Is_Suitable_Elaborable_Vertex -- + ----------------------------------- - Iter := LGV_Sets.Iterate (Set); - while LGV_Sets.Has_Next (Iter) loop - LGV_Sets.Next (Iter, Vertex); + function Is_Suitable_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); - Trace_Vertex - (G => G, - Vertex => Vertex, - Msg => "candidate vertex", - Step => Step, - Indent => Nested_Indentation); - end loop; - end Trace_Candidate_Vertices; + -- A vertex is suitable for elaboration as long it is not waiting on + -- any predecessors, ignoring the static or dynamic model. + + return Is_Elaborable_Vertex (G, Vertex); + end Is_Suitable_Elaborable_Vertex; + + ------------------------------------------ + -- Is_Suitable_Weakly_Elaborable_Vertex -- + ------------------------------------------ + + function Is_Suitable_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + + -- A vertex is suitable for weak elaboration when it is waiting on + -- weak predecessors only, and the unit it represents was compiled + -- using the dynamic model. + + return + Is_Dynamically_Elaborated (G, Vertex) + and then Is_Weakly_Elaborable_Vertex (G, Vertex); + end Is_Suitable_Weakly_Elaborable_Vertex; --------------------- -- Trace_Component -- @@ -1130,8 +1343,14 @@ package body Bindo.Elaborators is Trace_Step (Step); Indent_By (Nested_Indentation); - Write_Str ("pending predecessors: "); - Write_Num (Int (Pending_Predecessors (G, Comp))); + Write_Str ("pending strong predecessors: "); + Write_Num (Int (Pending_Strong_Predecessors (G, Comp))); + Write_Eol; + + Trace_Step (Step); + Indent_By (Nested_Indentation); + Write_Str ("pending weak predecessors : "); + Write_Num (Int (Pending_Weak_Predecessors (G, Comp))); Write_Eol; end Trace_Component; @@ -1154,50 +1373,6 @@ package body Bindo.Elaborators is Write_Str (": "); end Trace_Step; - --------------------------------- - -- Trace_Unelaborated_Vertices -- - --------------------------------- - - procedure Trace_Unelaborated_Vertices - (G : Library_Graph; - Count : Natural; - Step : Elaboration_Order_Step) - is - Iter : Library_Graphs.All_Vertex_Iterator; - Vertex : Library_Graph_Vertex_Id; - - begin - pragma Assert (Present (G)); - - -- Nothing to do when switch -d_T (output elaboration order and cycle - -- detection trace information) is not in effect. - - if not Debug_Flag_Underscore_TT then - return; - end if; - - Trace_Step (Step); - Write_Str ("remaining unelaborated vertices: "); - Write_Int (Int (Count)); - Write_Eol; - - Iter := Iterate_All_Vertices (G); - while Has_Next (Iter) loop - Next (Iter, Vertex); - - if Needs_Elaboration (G, Vertex) - and then not In_Elaboration_Order (G, Vertex) - then - Trace_Vertex - (G => G, - Vertex => Vertex, - Msg => "remaining vertex", - Step => Step, - Indent => Nested_Indentation); - end if; - end loop; - end Trace_Unelaborated_Vertices; - ------------------ -- Trace_Vertex -- ------------------ @@ -1247,37 +1422,104 @@ package body Bindo.Elaborators is Trace_Step (Step); Indent_By (Attr_Indent); - Write_Str ("pending predecessors: "); - Write_Num (Int (Pending_Predecessors (G, Vertex))); + Write_Str ("pending strong predecessors: "); + Write_Num (Int (Pending_Strong_Predecessors (G, Vertex))); + Write_Eol; + + Trace_Step (Step); + Indent_By (Attr_Indent); + Write_Str ("pending weak predecessors : "); + Write_Num (Int (Pending_Weak_Predecessors (G, Vertex))); Write_Eol; Trace_Step (Step); Indent_By (Attr_Indent); - Write_Str ("pending components : "); - Write_Num (Int (Pending_Predecessors (G, Comp))); + Write_Str ("pending strong components : "); + Write_Num (Int (Pending_Strong_Predecessors (G, Comp))); + Write_Eol; + + Trace_Step (Step); + Indent_By (Attr_Indent); + Write_Str ("pending weak components : "); + Write_Num (Int (Pending_Weak_Predecessors (G, Comp))); Write_Eol; end Trace_Vertex; + -------------------- + -- Trace_Vertices -- + -------------------- + + procedure Trace_Vertices + (G : Library_Graph; + Set : LGV_Sets.Membership_Set; + Set_Msg : String; + Vertex_Msg : String; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) + is + Vertex_Indent : constant Indentation_Level := + Indent + Nested_Indentation; + + Iter : LGV_Sets.Iterator; + Vertex : Library_Graph_Vertex_Id; + + begin + pragma Assert (Present (G)); + pragma Assert (LGV_Sets.Present (Set)); + + -- Nothing to do when switch -d_T (output elaboration order and cycle + -- detection trace information) is not in effect. + + if not Debug_Flag_Underscore_TT then + return; + end if; + + Trace_Step (Step); + Indent_By (Indent); + Write_Str (Set_Msg); + Write_Str (": "); + Write_Int (Int (LGV_Sets.Size (Set))); + Write_Eol; + + Iter := LGV_Sets.Iterate (Set); + while LGV_Sets.Has_Next (Iter) loop + LGV_Sets.Next (Iter, Vertex); + + Trace_Vertex + (G => G, + Vertex => Vertex, + Msg => Vertex_Msg, + Step => Step, + Indent => Vertex_Indent); + end loop; + end Trace_Vertices; + ---------------------- -- Update_Successor -- ---------------------- procedure Update_Successor - (G : Library_Graph; - Pred : Library_Graph_Vertex_Id; - Succ : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step; - Indent : Indentation_Level) + (G : Library_Graph; + Edge : Library_Graph_Edge_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) is pragma Assert (Present (G)); - pragma Assert (Present (Pred)); + pragma Assert (Present (Edge)); + pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (All_Waiting_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices)); + + Pred : constant Library_Graph_Vertex_Id := Predecessor (G, Edge); + Succ : constant Library_Graph_Vertex_Id := Successor (G, Edge); + pragma Assert (Needs_Elaboration (G, Pred)); - pragma Assert (Present (Succ)); pragma Assert (Needs_Elaboration (G, Succ)); - pragma Assert (LGV_Sets.Present (All_Candidates)); - pragma Assert (LGV_Sets.Present (Comp_Candidates)); In_Different_Components : constant Boolean := not In_Same_Component @@ -1289,10 +1531,8 @@ package body Bindo.Elaborators is Vertex_Indent : constant Indentation_Level := Indent + Nested_Indentation; - Candidate : Library_Graph_Vertex_Id; - Iter : Component_Vertex_Iterator; - Msg : String_Ptr; - Set : LGV_Sets.Membership_Set; + Iter : Component_Vertex_Iterator; + Vertex : Library_Graph_Vertex_Id; begin Trace_Vertex @@ -1305,45 +1545,61 @@ package body Bindo.Elaborators is -- Notify the successor that it has one less predecessor to wait on. -- This effectively eliminates the edge that links the two. - Decrement_Pending_Predecessors (G, Succ); + Decrement_Pending_Predecessors + (G => G, + Vertex => Succ, + Edge => Edge); -- The predecessor and successor reside in different components. -- Notify the successor component it has one fewer components to -- wait on. if In_Different_Components then - Decrement_Pending_Predecessors (G, Succ_Comp); + Decrement_Pending_Predecessors + (G => G, + Comp => Succ_Comp, + Edge => Edge); end if; -- At this point the successor may become elaborable when its final - -- predecessor or final predecessor component is elaborated. - - -- The predecessor and successor reside in different components. - -- The successor must not be added to the candidates of Pred's - -- component because this will mix units from the two components. - -- Instead, the successor is added to the set of all candidates - -- that must be elaborated. + -- predecessor or final predecessor component has been elaborated. + + if Is_Elaborable_Vertex (G, Succ) then + + -- The predecessor and successor reside in different components. + -- The successor must not be added to the candidates of Pred's + -- component because this will mix units from the two components. + -- Instead, the successor is added to the set of all elaborable + -- vertices. + + if In_Different_Components then + Insert_Elaborable_Successor + (G => G, + Vertex => Succ, + Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Msg => "add elaborable successor", + Step => Step, + Indent => Vertex_Indent); + + -- Otherwise the predecessor and successor reside within the same + -- component. Pred's component gains another elaborable vertex. - if In_Different_Components then - Msg := Add_To_All_Candidates_Msg'Access; - Set := All_Candidates; - - -- Otherwise the predecessor and successor reside within the same - -- component. Pred's component gains another elaborable node. - - else - Msg := Add_To_Comp_Candidates_Msg'Access; - Set := Comp_Candidates; + else + Insert_Elaborable_Successor + (G => G, + Vertex => Succ, + Elaborable_Vertices => Comp_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Msg => + "add elaborable component successor", + Step => Step, + Indent => Vertex_Indent); + end if; end if; - Add_Vertex_If_Elaborable - (G => G, - Vertex => Succ, - Set => Set, - Msg => Msg.all, - Step => Step, - Indent => Vertex_Indent); - -- At this point the successor component may become elaborable when -- its final predecessor component is elaborated. This in turn may -- allow vertices of the successor component to be elaborated. @@ -1353,15 +1609,19 @@ package body Bindo.Elaborators is then Iter := Iterate_Component_Vertices (G, Succ_Comp); while Has_Next (Iter) loop - Next (Iter, Candidate); - - Add_Vertex_If_Elaborable - (G => G, - Vertex => Candidate, - Set => All_Candidates, - Msg => Add_To_All_Candidates_Msg, - Step => Step, - Indent => Vertex_Indent); + Next (Iter, Vertex); + + if Is_Elaborable_Vertex (G, Vertex) then + Insert_Elaborable_Successor + (G => G, + Vertex => Vertex, + Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Msg => "add elaborable vertex", + Step => Step, + Indent => Vertex_Indent); + end if; end loop; end if; end Update_Successor; @@ -1371,36 +1631,41 @@ package body Bindo.Elaborators is ----------------------- procedure Update_Successors - (G : Library_Graph; - Pred : Library_Graph_Vertex_Id; - All_Candidates : LGV_Sets.Membership_Set; - Comp_Candidates : LGV_Sets.Membership_Set; - Step : Elaboration_Order_Step; - Indent : Indentation_Level) + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + All_Elaborable_Vertices : LGV_Sets.Membership_Set; + All_Waiting_Vertices : LGV_Sets.Membership_Set; + Comp_Elaborable_Vertices : LGV_Sets.Membership_Set; + Comp_Waiting_Vertices : LGV_Sets.Membership_Set; + Step : Elaboration_Order_Step; + Indent : Indentation_Level) is Edge : Library_Graph_Edge_Id; Iter : Edges_To_Successors_Iterator; begin pragma Assert (Present (G)); - pragma Assert (Present (Pred)); - pragma Assert (Needs_Elaboration (G, Pred)); - pragma Assert (LGV_Sets.Present (All_Candidates)); - pragma Assert (LGV_Sets.Present (Comp_Candidates)); + pragma Assert (Present (Vertex)); + pragma Assert (Needs_Elaboration (G, Vertex)); + pragma Assert (LGV_Sets.Present (All_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (All_Waiting_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Elaborable_Vertices)); + pragma Assert (LGV_Sets.Present (Comp_Waiting_Vertices)); - Iter := Iterate_Edges_To_Successors (G, Pred); + Iter := Iterate_Edges_To_Successors (G, Vertex); while Has_Next (Iter) loop Next (Iter, Edge); - pragma Assert (Predecessor (G, Edge) = Pred); + pragma Assert (Predecessor (G, Edge) = Vertex); Update_Successor - (G => G, - Pred => Pred, - Succ => Successor (G, Edge), - All_Candidates => All_Candidates, - Comp_Candidates => Comp_Candidates, - Step => Step, - Indent => Indent); + (G => G, + Edge => Edge, + All_Elaborable_Vertices => All_Elaborable_Vertices, + All_Waiting_Vertices => All_Waiting_Vertices, + Comp_Elaborable_Vertices => Comp_Elaborable_Vertices, + Comp_Waiting_Vertices => Comp_Waiting_Vertices, + Step => Step, + Indent => Indent); end loop; end Update_Successors; end Invocation_And_Library_Graph_Elaborators; diff --git a/gcc/ada/bindo-graphs.adb b/gcc/ada/bindo-graphs.adb index c68e367d567..387d969f74e 100644 --- a/gcc/ada/bindo-graphs.adb +++ b/gcc/ada/bindo-graphs.adb @@ -205,7 +205,7 @@ package body Bindo.Graphs is (G : Invocation_Graph; Rel : Source_Target_Relation) return Boolean; pragma Inline (Is_Existing_Source_Target_Relation); - -- Determine whether a source vertex and a target vertex desctibed by + -- Determine whether a source vertex and a target vertex described by -- relation Rel are already related in invocation graph G. procedure Save_Elaboration_Root @@ -226,7 +226,7 @@ package body Bindo.Graphs is Rel : Source_Target_Relation; Val : Boolean := True); pragma Inline (Set_Is_Existing_Source_Target_Relation); - -- Mark a source vertex and a target vertex desctibed by relation Rel as + -- Mark a source vertex and a target vertex described by relation Rel as -- already related in invocation graph G depending on value Val. procedure Set_IGE_Attributes @@ -1026,18 +1026,6 @@ package body Bindo.Graphs is package body Library_Graphs is - ----------- - -- Types -- - ----------- - - -- The following type represents the various kinds of precedence between - -- two items. - - type Precedence_Kind is - (Lower_Precedence, - Equal_Precedence, - Higher_Precedence); - ----------------------- -- Local subprograms -- ----------------------- @@ -1064,7 +1052,7 @@ package body Bindo.Graphs is Attrs : Library_Graph_Cycle_Attributes; Indent : Indentation_Level); pragma Inline (Add_Cycle); - -- Store a cycle described by attribytes Attrs in library graph G, + -- Store a cycle described by attributes Attrs in library graph G, -- unless a prior rotation of it already exists. The edges of the cycle -- must be in normalized form. Indent is the desired indentation level -- for tracing. @@ -1090,15 +1078,6 @@ package body Bindo.Graphs is -- part of an Elaborate_Body pair, or flag Do_Complement is set, add -- the complementary vertex to the set. - function Complementary_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Do_Complement : Boolean) return Library_Graph_Vertex_Id; - pragma Inline (Complementary_Vertex); - -- If vertex Vertex of library graph G is part of an Elaborate_Body - -- pair, or flag Do_Complement is set, return the spec when Vertex is - -- a body, the body when Vertex is a spec, or No_Library_Graph_Vertex. - function Copy_Cycle_Path (Cycle_Path : LGE_Lists.Doubly_Linked_List) return LGE_Lists.Doubly_Linked_List; @@ -1228,17 +1207,21 @@ package body Bindo.Graphs is procedure Increment_Pending_Predecessors (G : Library_Graph; - Comp : Component_Id); + Comp : Component_Id; + Edge : Library_Graph_Edge_Id); pragma Inline (Increment_Pending_Predecessors); - -- Increment the number of pending precedessors component Comp of - -- library graph G must wait on before it can be elaborated by one. + -- Increment the number of pending predecessors component Comp which was + -- reached via edge Edge of library graph G must wait on before it can + -- be elaborated by one. procedure Increment_Pending_Predecessors (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id); + Vertex : Library_Graph_Vertex_Id; + Edge : Library_Graph_Edge_Id); pragma Inline (Increment_Pending_Predecessors); - -- Increment the number of pending precedessors vertex Vertex of library - -- graph G must wait on before it can be elaborated by one. + -- Increment the number of pending predecessors vertex Vertex which was + -- reached via edge Edge of library graph G must wait on before it can + -- be elaborated by one. procedure Initialize_Components (G : Library_Graph); pragma Inline (Initialize_Components); @@ -1306,22 +1289,14 @@ package body Bindo.Graphs is Edge : Library_Graph_Edge_Id) return Boolean; pragma Inline (Is_Cyclic_With_Edge); -- Determine whether edge Edge of library graph G participates in a - -- cycle and is the result of awith dependency between its successor + -- cycle and is the result of a with dependency between its successor -- and predecessor. - function Is_Elaborable_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Predecessors : Natural) return Boolean; - pragma Inline (Is_Elaborable_Vertex); - -- Determine whether vertex Vertex of library graph G can be elaborated - -- given that it meets number of predecessors Predecessors. - function Is_Recorded_Cycle (G : Library_Graph; Attrs : Library_Graph_Cycle_Attributes) return Boolean; pragma Inline (Is_Recorded_Cycle); - -- Determine whether a cycle desctibed by its attributes Attrs has + -- Determine whether a cycle described by its attributes Attrs has -- has already been recorded in library graph G. function Is_Recorded_Edge @@ -1329,7 +1304,7 @@ package body Bindo.Graphs is Rel : Predecessor_Successor_Relation) return Boolean; pragma Inline (Is_Recorded_Edge); -- Determine whether a predecessor vertex and a successor vertex - -- desctibed by relation Rel are already linked in library graph G. + -- described by relation Rel are already linked in library graph G. function Links_Vertices_In_Same_Component (G : Library_Graph; @@ -1441,7 +1416,7 @@ package body Bindo.Graphs is Rel : Predecessor_Successor_Relation; Val : Boolean := True); pragma Inline (Set_Is_Recorded_Edge); - -- Mark a predecessor vertex and a successor vertex desctibed by + -- Mark a predecessor vertex and a successor vertex described by -- relation Rel as already linked depending on value Val. procedure Set_LGC_Attributes @@ -1493,6 +1468,16 @@ package body Bindo.Graphs is -- Write the contents of vertex Vertex of library graph G to standard -- output. Indent is the desired indentation level for tracing. + procedure Update_Pending_Predecessors + (Strong_Predecessors : in out Natural; + Weak_Predecessors : in out Natural; + Update_Weak : Boolean; + Value : Integer); + pragma Inline (Update_Pending_Predecessors); + -- Update the number of pending strong or weak predecessors denoted by + -- Strong_Predecessors and Weak_Predecessors respectively depending on + -- flag Update_Weak by adding value Value. + procedure Update_Pending_Predecessors_Of_Components (G : Library_Graph); pragma Inline (Update_Pending_Predecessors_Of_Components); -- Update the number of pending predecessors all components of library @@ -1523,7 +1508,7 @@ package body Bindo.Graphs is pragma Assert (LGE_Lists.Present (Edges)); -- A vertex requires a special Body_Before_Spec edge to its - -- Corresponging_Item when it either denotes a + -- Corresponding_Item when it either denotes a -- -- * Body that completes a previous spec -- @@ -1717,7 +1702,10 @@ package body Bindo.Graphs is -- Update the number of pending predecessors the successor must wait -- on before it is elaborated. - Increment_Pending_Predecessors (G, Succ); + Increment_Pending_Predecessors + (G => G, + Vertex => Succ, + Edge => Edge); -- Update the edge statistics @@ -1757,10 +1745,12 @@ package body Bindo.Graphs is Set_LGV_Attributes (G => G, Vertex => Vertex, - Val => (Corresponding_Item => No_Library_Graph_Vertex, - In_Elaboration_Order => False, - Pending_Predecessors => 0, - Unit => U_Id)); + Val => + (Corresponding_Item => No_Library_Graph_Vertex, + In_Elaboration_Order => False, + Pending_Strong_Predecessors => 0, + Pending_Weak_Predecessors => 0, + Unit => U_Id)); -- Associate the unit with its corresponding vertex @@ -1783,9 +1773,9 @@ package body Bindo.Graphs is Complement : constant Library_Graph_Vertex_Id := Complementary_Vertex - (G => G, - Vertex => Vertex, - Do_Complement => Do_Complement); + (G => G, + Vertex => Vertex, + Force_Complement => Do_Complement); begin LGV_Sets.Insert (Set, Vertex); @@ -1800,9 +1790,9 @@ package body Bindo.Graphs is -------------------------- function Complementary_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Do_Complement : Boolean) return Library_Graph_Vertex_Id + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Force_Complement : Boolean) return Library_Graph_Vertex_Id is Complement : Library_Graph_Vertex_Id; @@ -1816,7 +1806,7 @@ package body Bindo.Graphs is -- The caller requests the complement explicitly - if Do_Complement then + if Force_Complement then Complement := Corresponding_Item (G, Vertex); -- The vertex is a completing body of a spec subject to pragma @@ -1850,6 +1840,46 @@ package body Bindo.Graphs is return DG.Component (G.Graph, Vertex); end Component; + ------------------------------------ + -- Contains_Weak_Static_Successor -- + ------------------------------------ + + function Contains_Weak_Static_Successor + (G : Library_Graph; + Cycle : Library_Graph_Cycle_Id) return Boolean + is + Edge : Library_Graph_Edge_Id; + Iter : Edges_Of_Cycle_Iterator; + Seen : Boolean; + + begin + pragma Assert (Present (G)); + pragma Assert (Present (Cycle)); + + -- Assume that no weak static successor has been seen + + Seen := False; + + -- IMPORTANT: + -- + -- * The iteration must run to completion in order to unlock the + -- edges of the cycle. + + Iter := Iterate_Edges_Of_Cycle (G, Cycle); + while Has_Next (Iter) loop + Next (Iter, Edge); + + if not Seen + and then Is_Invocation_Edge (G, Edge) + and then not Is_Dynamically_Elaborated (G, Successor (G, Edge)) + then + Seen := True; + end if; + end loop; + + return Seen; + end Contains_Weak_Static_Successor; + --------------------- -- Copy_Cycle_Path -- --------------------- @@ -1911,15 +1941,12 @@ package body Bindo.Graphs is ------------ function Create - (Initial_Vertices : Positive; - Initial_Edges : Positive; - Dynamically_Elaborated : Boolean) return Library_Graph + (Initial_Vertices : Positive; + Initial_Edges : Positive) return Library_Graph is G : constant Library_Graph := new Library_Graph_Attributes; begin - G.Dynamically_Elaborated := Dynamically_Elaborated; - G.Component_Attributes := Component_Tables.Create (Initial_Vertices); G.Cycle_Attributes := LGC_Tables.Create (Initial_Vertices); G.Cycles := LGC_Lists.Create; @@ -1990,7 +2017,8 @@ package body Bindo.Graphs is procedure Decrement_Pending_Predecessors (G : Library_Graph; - Comp : Component_Id) + Comp : Component_Id; + Edge : Library_Graph_Edge_Id) is Attrs : Component_Attributes; @@ -1999,7 +2027,13 @@ package body Bindo.Graphs is pragma Assert (Present (Comp)); Attrs := Get_Component_Attributes (G, Comp); - Attrs.Pending_Predecessors := Attrs.Pending_Predecessors - 1; + + Update_Pending_Predecessors + (Strong_Predecessors => Attrs.Pending_Strong_Predecessors, + Weak_Predecessors => Attrs.Pending_Weak_Predecessors, + Update_Weak => Is_Invocation_Edge (G, Edge), + Value => -1); + Set_Component_Attributes (G, Comp, Attrs); end Decrement_Pending_Predecessors; @@ -2009,7 +2043,8 @@ package body Bindo.Graphs is procedure Decrement_Pending_Predecessors (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id) + Vertex : Library_Graph_Vertex_Id; + Edge : Library_Graph_Edge_Id) is Attrs : Library_Graph_Vertex_Attributes; @@ -2018,7 +2053,13 @@ package body Bindo.Graphs is pragma Assert (Present (Vertex)); Attrs := Get_LGV_Attributes (G, Vertex); - Attrs.Pending_Predecessors := Attrs.Pending_Predecessors - 1; + + Update_Pending_Predecessors + (Strong_Predecessors => Attrs.Pending_Strong_Predecessors, + Weak_Predecessors => Attrs.Pending_Weak_Predecessors, + Update_Weak => Is_Invocation_Edge (G, Edge), + Value => -1); + Set_LGV_Attributes (G, Vertex, Attrs); end Decrement_Pending_Predecessors; @@ -2071,7 +2112,10 @@ package body Bindo.Graphs is -- Update the number of pending predecessors the successor must wait -- on before it is elaborated. - Decrement_Pending_Predecessors (G, Succ); + Decrement_Pending_Predecessors + (G => G, + Vertex => Succ, + Edge => Edge); -- Delete the link between the predecessor and successor. This allows -- for further attempts to link the same predecessor and successor. @@ -2298,9 +2342,9 @@ package body Bindo.Graphs is (G => G, Vertex => Complementary_Vertex - (G => G, - Vertex => Vertex, - Do_Complement => Spec_And_Body_Together), + (G => G, + Vertex => Vertex, + Force_Complement => Spec_And_Body_Together), End_Vertices => End_Vertices, Most_Significant_Edge => Most_Significant_Edge, Invocation_Edge_Count => Invocation_Edge_Count, @@ -2343,7 +2387,7 @@ package body Bindo.Graphs is Trace_Edge (G, Initial_Edge, Indent); -- Use a set to represent the end vertices of the cycle. The set is - -- needed to accomodate the Elaborate_All and Elaborate_Body cases + -- needed to accommodate the Elaborate_All and Elaborate_Body cases -- where a cycle may terminate on either a spec or a body vertex. End_Vertices := LGV_Sets.Create (2); @@ -2650,7 +2694,10 @@ package body Bindo.Graphs is U_Rec : Unit_Record renames ALI.Units.Table (U_Id); begin - return U_Rec.Elaborate_Body; + -- Treat the spec and body as decoupled when switch -d_b (ignore the + -- effects of pragma Elaborate_Body) is in effect. + + return U_Rec.Elaborate_Body and not Debug_Flag_Underscore_B; end Has_Elaborate_Body; -------------- @@ -2884,7 +2931,8 @@ package body Bindo.Graphs is procedure Increment_Pending_Predecessors (G : Library_Graph; - Comp : Component_Id) + Comp : Component_Id; + Edge : Library_Graph_Edge_Id) is Attrs : Component_Attributes; @@ -2893,7 +2941,13 @@ package body Bindo.Graphs is pragma Assert (Present (Comp)); Attrs := Get_Component_Attributes (G, Comp); - Attrs.Pending_Predecessors := Attrs.Pending_Predecessors + 1; + + Update_Pending_Predecessors + (Strong_Predecessors => Attrs.Pending_Strong_Predecessors, + Weak_Predecessors => Attrs.Pending_Weak_Predecessors, + Update_Weak => Is_Invocation_Edge (G, Edge), + Value => 1); + Set_Component_Attributes (G, Comp, Attrs); end Increment_Pending_Predecessors; @@ -2903,7 +2957,8 @@ package body Bindo.Graphs is procedure Increment_Pending_Predecessors (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id) + Vertex : Library_Graph_Vertex_Id; + Edge : Library_Graph_Edge_Id) is Attrs : Library_Graph_Vertex_Attributes; @@ -2912,7 +2967,13 @@ package body Bindo.Graphs is pragma Assert (Present (Vertex)); Attrs := Get_LGV_Attributes (G, Vertex); - Attrs.Pending_Predecessors := Attrs.Pending_Predecessors + 1; + + Update_Pending_Predecessors + (Strong_Predecessors => Attrs.Pending_Strong_Predecessors, + Weak_Predecessors => Attrs.Pending_Weak_Predecessors, + Update_Weak => Is_Invocation_Edge (G, Edge), + Value => 1); + Set_LGV_Attributes (G, Vertex, Attrs); end Increment_Pending_Predecessors; @@ -2925,7 +2986,7 @@ package body Bindo.Graphs is pragma Assert (Present (G)); -- The graph already contains a set of components. Reinitialize - -- them in order to accomodate the new set of components about to + -- them in order to accommodate the new set of components about to -- be computed. if Number_Of_Components (G) > 0 then @@ -3216,11 +3277,15 @@ package body Bindo.Graphs is -- Is_Dynamically_Elaborated -- ------------------------------- - function Is_Dynamically_Elaborated (G : Library_Graph) return Boolean is + function Is_Dynamically_Elaborated + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean + is begin pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); - return G.Dynamically_Elaborated; + return Is_Dynamically_Elaborated (Unit (G, Vertex)); end Is_Dynamically_Elaborated; ----------------------------- @@ -3235,12 +3300,14 @@ package body Bindo.Graphs is pragma Assert (Present (G)); pragma Assert (Present (Comp)); - -- A component can be elaborated when + -- A component is elaborable when: -- - -- * The component is no longer wanting on any of its predecessors - -- to be elaborated. + -- * It is not waiting on strong predecessors, and + -- * It is not waiting on weak predecessors - return Pending_Predecessors (G, Comp) = 0; + return + Pending_Strong_Predecessors (G, Comp) = 0 + and then Pending_Weak_Predecessors (G, Comp) = 0; end Is_Elaborable_Component; -------------------------- @@ -3251,80 +3318,47 @@ package body Bindo.Graphs is (G : Library_Graph; Vertex : Library_Graph_Vertex_Id) return Boolean is - Check_Vertex : Library_Graph_Vertex_Id; - - begin pragma Assert (Present (G)); pragma Assert (Present (Vertex)); - Check_Vertex := Vertex; - - -- A spec-body pair where the spec carries pragma Elaborate_Body must - -- be treated as one vertex for elaboration purposes. Use the spec as - -- the point of reference for the composite vertex. - - if Is_Body_Of_Spec_With_Elaborate_Body (G, Check_Vertex) then - Check_Vertex := Proper_Spec (G, Check_Vertex); - end if; - - return - Is_Elaborable_Vertex - (G => G, - Vertex => Check_Vertex, - Predecessors => 0); - end Is_Elaborable_Vertex; - - -------------------------- - -- Is_Elaborable_Vertex -- - -------------------------- + Complement : constant Library_Graph_Vertex_Id := + Complementary_Vertex + (G => G, + Vertex => Vertex, + Force_Complement => False); - function Is_Elaborable_Vertex - (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id; - Predecessors : Natural) return Boolean - is - Body_Vertex : Library_Graph_Vertex_Id; + Strong_Preds : Natural; + Weak_Preds : Natural; begin - pragma Assert (Present (G)); - pragma Assert (Present (Vertex)); - - -- The vertex must not be re-elaborated once it has been elaborated + -- A vertex is elaborable when: + -- + -- * It has not been elaborated yet, and + -- * The complement vertex of an Elaborate_Body pair has not been + -- elaborated yet, and + -- * It resides within an elaborable component, and + -- * It is not waiting on strong predecessors, and + -- * It is not waiting on weak predecessors if In_Elaboration_Order (G, Vertex) then return False; - -- The vertex must not be waiting on more precedessors than requested - -- to be elaborated. - - elsif Pending_Predecessors (G, Vertex) /= Predecessors then + elsif Present (Complement) + and then In_Elaboration_Order (G, Complement) + then return False; - -- The component where the vertex resides must not be waiting on any - -- of its precedessors to be elaborated. - elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then return False; - - -- The vertex denotes a spec with a completing body, and is subject - -- to pragma Elaborate_Body. The body must be elaborable for the - -- vertex to be elaborated. Account for the sole predecessor of the - -- body which is the vertex itself. - - elsif Is_Spec_With_Elaborate_Body (G, Vertex) then - Body_Vertex := Proper_Body (G, Vertex); - pragma Assert (Present (Body_Vertex)); - - return - Is_Elaborable_Vertex - (G => G, - Vertex => Body_Vertex, - Predecessors => 1); end if; - -- At this point it is known that the vertex can be elaborated + Pending_Predecessors_For_Elaboration + (G => G, + Vertex => Vertex, + Strong_Preds => Strong_Preds, + Weak_Preds => Weak_Preds); - return True; + return Strong_Preds = 0 and then Weak_Preds = 0; end Is_Elaborable_Vertex; --------------------------- @@ -3378,6 +3412,26 @@ package body Bindo.Graphs is return Kind (G, Edge) = Elaborate_Edge; end Is_Elaborate_Edge; + ---------------------------- + -- Is_Elaborate_Body_Pair -- + ---------------------------- + + function Is_Elaborate_Body_Pair + (G : Library_Graph; + Spec_Vertex : Library_Graph_Vertex_Id; + Body_Vertex : Library_Graph_Vertex_Id) return Boolean + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Spec_Vertex)); + pragma Assert (Present (Body_Vertex)); + + return + Is_Spec_With_Elaborate_Body (G, Spec_Vertex) + and then Is_Body_Of_Spec_With_Elaborate_Body (G, Body_Vertex) + and then Proper_Body (G, Spec_Vertex) = Body_Vertex; + end Is_Elaborate_Body_Pair; + -------------------- -- Is_Forced_Edge -- -------------------- @@ -3539,6 +3593,57 @@ package body Bindo.Graphs is and then Has_Elaborate_Body (G, Vertex); end Is_Spec_With_Elaborate_Body; + --------------------------------- + -- Is_Weakly_Elaborable_Vertex -- + ---------------------------------- + + function Is_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean + is + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + + Complement : constant Library_Graph_Vertex_Id := + Complementary_Vertex + (G => G, + Vertex => Vertex, + Force_Complement => False); + + Strong_Preds : Natural; + Weak_Preds : Natural; + + begin + -- A vertex is weakly elaborable when: + -- + -- * It has not been elaborated yet, and + -- * The complement vertex of an Elaborate_Body pair has not been + -- elaborated yet, and + -- * It resides within an elaborable component, and + -- * It is not waiting on strong predecessors, and + -- * It is waiting on at least one weak predecessor + + if In_Elaboration_Order (G, Vertex) then + return False; + + elsif Present (Complement) + and then In_Elaboration_Order (G, Complement) + then + return False; + + elsif not Is_Elaborable_Component (G, Component (G, Vertex)) then + return False; + end if; + + Pending_Predecessors_For_Elaboration + (G => G, + Vertex => Vertex, + Strong_Preds => Strong_Preds, + Weak_Preds => Weak_Preds); + + return Strong_Preds = 0 and then Weak_Preds >= 1; + end Is_Weakly_Elaborable_Vertex; + ------------------ -- Is_With_Edge -- ------------------ @@ -4044,11 +4149,72 @@ package body Bindo.Graphs is return Get_LGC_Attributes (G, Cycle).Path; end Path; - -------------------------- - -- Pending_Predecessors -- - -------------------------- + ------------------------------------------ + -- Pending_Predecessors_For_Elaboration -- + ------------------------------------------ - function Pending_Predecessors + procedure Pending_Predecessors_For_Elaboration + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Strong_Preds : out Natural; + Weak_Preds : out Natural) + is + Complement : Library_Graph_Vertex_Id; + Spec_Vertex : Library_Graph_Vertex_Id; + Total_Strong_Preds : Natural; + Total_Weak_Preds : Natural; + + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + + Total_Strong_Preds := Pending_Strong_Predecessors (G, Vertex); + Total_Weak_Preds := Pending_Weak_Predecessors (G, Vertex); + + -- Assume that there is no complementary vertex that needs to be + -- examined. + + Complement := No_Library_Graph_Vertex; + Spec_Vertex := No_Library_Graph_Vertex; + + if Is_Body_Of_Spec_With_Elaborate_Body (G, Vertex) then + Complement := Proper_Spec (G, Vertex); + Spec_Vertex := Complement; + + elsif Is_Spec_With_Elaborate_Body (G, Vertex) then + Complement := Proper_Body (G, Vertex); + Spec_Vertex := Vertex; + end if; + + -- The vertex is part of an Elaborate_Body pair. Take into account + -- the strong and weak predecessors of the complementary vertex. + + if Present (Complement) then + Total_Strong_Preds := + Pending_Strong_Predecessors (G, Complement) + Total_Strong_Preds; + Total_Weak_Preds := + Pending_Weak_Predecessors (G, Complement) + Total_Weak_Preds; + + -- The body of an Elaborate_Body pair is the successor of a strong + -- edge where the predecessor is the spec. This edge must not be + -- considered for elaboration purposes because the pair is treated + -- as one vertex. Account for the edge only when the spec has not + -- been elaborated yet. + + if not In_Elaboration_Order (G, Spec_Vertex) then + Total_Strong_Preds := Total_Strong_Preds - 1; + end if; + end if; + + Strong_Preds := Total_Strong_Preds; + Weak_Preds := Total_Weak_Preds; + end Pending_Predecessors_For_Elaboration; + + --------------------------------- + -- Pending_Strong_Predecessors -- + --------------------------------- + + function Pending_Strong_Predecessors (G : Library_Graph; Comp : Component_Id) return Natural is @@ -4056,14 +4222,14 @@ package body Bindo.Graphs is pragma Assert (Present (G)); pragma Assert (Present (Comp)); - return Get_Component_Attributes (G, Comp).Pending_Predecessors; - end Pending_Predecessors; + return Get_Component_Attributes (G, Comp).Pending_Strong_Predecessors; + end Pending_Strong_Predecessors; - -------------------------- - -- Pending_Predecessors -- - -------------------------- + --------------------------------- + -- Pending_Strong_Predecessors -- + --------------------------------- - function Pending_Predecessors + function Pending_Strong_Predecessors (G : Library_Graph; Vertex : Library_Graph_Vertex_Id) return Natural is @@ -4071,8 +4237,38 @@ package body Bindo.Graphs is pragma Assert (Present (G)); pragma Assert (Present (Vertex)); - return Get_LGV_Attributes (G, Vertex).Pending_Predecessors; - end Pending_Predecessors; + return Get_LGV_Attributes (G, Vertex).Pending_Strong_Predecessors; + end Pending_Strong_Predecessors; + + ------------------------------- + -- Pending_Weak_Predecessors -- + ------------------------------- + + function Pending_Weak_Predecessors + (G : Library_Graph; + Comp : Component_Id) return Natural + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Comp)); + + return Get_Component_Attributes (G, Comp).Pending_Weak_Predecessors; + end Pending_Weak_Predecessors; + + ------------------------------- + -- Pending_Weak_Predecessors -- + ------------------------------- + + function Pending_Weak_Predecessors + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Natural + is + begin + pragma Assert (Present (G)); + pragma Assert (Present (Vertex)); + + return Get_LGV_Attributes (G, Vertex).Pending_Weak_Predecessors; + end Pending_Weak_Predecessors; ---------------- -- Precedence -- @@ -4306,9 +4502,9 @@ package body Bindo.Graphs is Complement : constant Library_Graph_Vertex_Id := Complementary_Vertex - (G => G, - Vertex => Vertex, - Do_Complement => Do_Complement); + (G => G, + Vertex => Vertex, + Force_Complement => Do_Complement); begin LGV_Sets.Delete (Set, Vertex); @@ -4702,6 +4898,24 @@ package body Bindo.Graphs is return Get_LGV_Attributes (G, Vertex).Unit; end Unit; + --------------------------------- + -- Update_Pending_Predecessors -- + --------------------------------- + + procedure Update_Pending_Predecessors + (Strong_Predecessors : in out Natural; + Weak_Predecessors : in out Natural; + Update_Weak : Boolean; + Value : Integer) + is + begin + if Update_Weak then + Weak_Predecessors := Weak_Predecessors + Value; + else + Strong_Predecessors := Strong_Predecessors + Value; + end if; + end Update_Pending_Predecessors; + ----------------------------------------------- -- Update_Pending_Predecessors_Of_Components -- ----------------------------------------------- @@ -4748,7 +4962,10 @@ package body Bindo.Graphs is -- must wait on another predecessor until it can be elaborated. if Pred_Comp /= Succ_Comp then - Increment_Pending_Predecessors (G, Succ_Comp); + Increment_Pending_Predecessors + (G => G, + Comp => Succ_Comp, + Edge => Edge); end if; end Update_Pending_Predecessors_Of_Components; end Library_Graphs; @@ -4835,7 +5052,7 @@ package body Bindo.Graphs is -------------------------- LGC_Sequencer : Library_Graph_Cycle_Id := First_Library_Graph_Cycle; - -- The couhnter for library graph cycles. Do not directly manipulate its + -- The counter for library graph cycles. Do not directly manipulate its -- value. function Sequence_Next_Cycle return Library_Graph_Cycle_Id is diff --git a/gcc/ada/bindo-graphs.ads b/gcc/ada/bindo-graphs.ads index 02f8e52fd64..3c2fef01825 100644 --- a/gcc/ada/bindo-graphs.ads +++ b/gcc/ada/bindo-graphs.ads @@ -668,7 +668,7 @@ package Bindo.Graphs is -- The following type represents the various kinds of library graph -- cycles. The ordering of kinds is significant, where a literal with - -- lower ordinal has a higner precedence than one with higher ordinal. + -- lower ordinal has a higher precedence than one with higher ordinal. type Library_Graph_Cycle_Kind is (Elaborate_Body_Cycle, @@ -753,13 +753,11 @@ package Bindo.Graphs is -- describes. function Create - (Initial_Vertices : Positive; - Initial_Edges : Positive; - Dynamically_Elaborated : Boolean) return Library_Graph; + (Initial_Vertices : Positive; + Initial_Edges : Positive) return Library_Graph; pragma Inline (Create); -- Create a new empty graph with vertex capacity Initial_Vertices and - -- edge capacity Initial_Edges. Flag Dynamically_Elaborated must be set - -- when the main library unit was compiled using the dynamic model. + -- edge capacity Initial_Edges. procedure Destroy (G : in out Library_Graph); pragma Inline (Destroy); @@ -809,10 +807,12 @@ package Bindo.Graphs is procedure Decrement_Pending_Predecessors (G : Library_Graph; - Vertex : Library_Graph_Vertex_Id); + Vertex : Library_Graph_Vertex_Id; + Edge : Library_Graph_Edge_Id); pragma Inline (Decrement_Pending_Predecessors); - -- Decrease the number of pending predecessors vertex Vertex of library - -- graph G must wait on until it can be elaborated. + -- Decrease the number of pending predecessors vertex Vertex which was + -- reached via edge Edge of library graph G must wait until it can be + -- elaborated. function File_Name (G : Library_Graph; @@ -844,12 +844,30 @@ package Bindo.Graphs is -- Obtain the name of the unit which vertex Vertex of library graph G -- represents. - function Pending_Predecessors + procedure Pending_Predecessors_For_Elaboration + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Strong_Preds : out Natural; + Weak_Preds : out Natural); + pragma Inline (Pending_Predecessors_For_Elaboration); + -- Obtain the number of pending strong and weak predecessors of vertex + -- Vertex of library graph G, taking into account Elaborate_Body pairs. + -- Strong predecessors are returned in Strong_Preds. Weak predecessors + -- are returned in Weak_Preds. + + function Pending_Strong_Predecessors + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Natural; + pragma Inline (Pending_Strong_Predecessors); + -- Obtain the number of pending strong predecessors vertex Vertex of + -- library graph G must wait on until it can be elaborated. + + function Pending_Weak_Predecessors (G : Library_Graph; Vertex : Library_Graph_Vertex_Id) return Natural; - pragma Inline (Pending_Predecessors); - -- Obtain the number of pending predecessors vertex Vertex of library - -- graph G must wait on until it can be elaborated. + pragma Inline (Pending_Weak_Predecessors); + -- Obtain the number of pending weak predecessors vertex Vertex of + -- library graph G must wait on until it can be elaborated. procedure Set_Corresponding_Item (G : Library_Graph; @@ -901,17 +919,26 @@ package Bindo.Graphs is procedure Decrement_Pending_Predecessors (G : Library_Graph; - Comp : Component_Id); + Comp : Component_Id; + Edge : Library_Graph_Edge_Id); pragma Inline (Decrement_Pending_Predecessors); - -- Decrease the number of pending predecessors component Comp of library - -- graph G must wait on until it can be elaborated. + -- Decrease the number of pending predecessors component Comp which was + -- reached via edge Edge of library graph G must wait on until it can be + -- elaborated. - function Pending_Predecessors + function Pending_Strong_Predecessors (G : Library_Graph; Comp : Component_Id) return Natural; - pragma Inline (Pending_Predecessors); - -- Obtain the number of pending predecessors component Comp of library - -- graph G must wait on until it can be elaborated. + pragma Inline (Pending_Strong_Predecessors); + -- Obtain the number of pending strong predecessors component Comp of + -- library graph G must wait on until it can be elaborated. + + function Pending_Weak_Predecessors + (G : Library_Graph; + Comp : Component_Id) return Natural; + pragma Inline (Pending_Weak_Predecessors); + -- Obtain the number of pending weak predecessors component Comp of + -- library graph G must wait on until it can be elaborated. ---------------------- -- Cycle attributes -- @@ -940,6 +967,26 @@ package Bindo.Graphs is -- Semantics -- --------------- + function Complementary_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id; + Force_Complement : Boolean) return Library_Graph_Vertex_Id; + pragma Inline (Complementary_Vertex); + -- Obtain the complementary vertex of vertex Vertex of library graph G + -- as follows: + -- + -- * If Vertex is the spec of an Elaborate_Body pair, return the body + -- * If Vertex is the body of an Elaborate_Body pair, return the spec + -- + -- This behavior can be forced by setting flag Force_Complement to True. + + function Contains_Weak_Static_Successor + (G : Library_Graph; + Cycle : Library_Graph_Cycle_Id) return Boolean; + pragma Inline (Contains_Weak_Static_Successor); + -- Determine whether cycle Cycle of library graph G contains a weak edge + -- where the successor was compiled using the static model. + function Has_Elaborate_All_Cycle (G : Library_Graph) return Boolean; pragma Inline (Has_Elaborate_All_Cycle); -- Determine whether library graph G contains a cycle involving pragma @@ -973,22 +1020,26 @@ package Bindo.Graphs is -- Determine whether vertex Vertex of library graph G denotes a body -- with a corresponding spec. - function Is_Dynamically_Elaborated (G : Library_Graph) return Boolean; + function Is_Dynamically_Elaborated + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; pragma Inline (Is_Dynamically_Elaborated); - -- Determine whether library graph G was created from a set of units - -- where the main library unit was compiled using the dynamic model. + -- Determine whether vertex Vertex of library graph G was compiled + -- using the dynamic model. function Is_Elaborable_Component (G : Library_Graph; Comp : Component_Id) return Boolean; pragma Inline (Is_Elaborable_Component); - -- Determine whether component Comp of library graph G can be elaborated + -- Determine whether component Comp of library graph G is not waiting on + -- any predecessors, and can thus be elaborated. function Is_Elaborable_Vertex (G : Library_Graph; Vertex : Library_Graph_Vertex_Id) return Boolean; pragma Inline (Is_Elaborable_Vertex); - -- Determine whether vertex Vertex of library graph G can be elaborated + -- Determine whether vertex Vertex of library graph G is not waiting on + -- any predecessors, and can thus be elaborated. function Is_Elaborate_All_Edge (G : Library_Graph; @@ -1012,6 +1063,15 @@ package Bindo.Graphs is -- Determine whether edge Edge of library graph G is an edge whose -- predecessor is subject to pragma Elaborate. + function Is_Elaborate_Body_Pair + (G : Library_Graph; + Spec_Vertex : Library_Graph_Vertex_Id; + Body_Vertex : Library_Graph_Vertex_Id) return Boolean; + pragma Inline (Is_Elaborate_Body_Pair); + -- Determine whether vertices Spec_Vertex and Body_Vertex of library + -- graph G denote a spec subject to Elaborate_Body and its completing + -- body. + function Is_Forced_Edge (G : Library_Graph; Edge : Library_Graph_Edge_Id) return Boolean; @@ -1045,7 +1105,7 @@ package Bindo.Graphs is Vertex : Library_Graph_Vertex_Id) return Boolean; pragma Inline (Is_Preelaborated_Unit); -- Determine whether vertex Vertex of library graph G denotes a unit - -- subjec to pragma Pure or Preelaborable. + -- subject to pragma Pure or Preelaborable. function Is_Spec (G : Library_Graph; @@ -1067,6 +1127,14 @@ package Bindo.Graphs is -- Determine whether vertex Vertex of library graph G denotes a spec -- with a corresponding body, and is subject to pragma Elaborate_Body. + function Is_Weakly_Elaborable_Vertex + (G : Library_Graph; + Vertex : Library_Graph_Vertex_Id) return Boolean; + pragma Inline (Is_Weakly_Elaborable_Vertex); + -- Determine whether vertex Vertex of library graph G is waiting on + -- weak predecessors only, in which case it can be elaborated assuming + -- that the weak edges will not be exercised at elaboration time. + function Is_With_Edge (G : Library_Graph; Edge : Library_Graph_Edge_Id) return Boolean; @@ -1320,9 +1388,13 @@ package Bindo.Graphs is In_Elaboration_Order : Boolean := False; -- Set when this vertex is elaborated - Pending_Predecessors : Natural := 0; - -- The number of pending predecessor vertices this vertex must wait - -- on before it can be elaborated. + Pending_Strong_Predecessors : Natural := 0; + -- The number of pending strong predecessor vertices this vertex must + -- wait on before it can be elaborated. + + Pending_Weak_Predecessors : Natural := 0; + -- The number of weak predecessor vertices this vertex must wait on + -- before it can be elaborated. Unit : Unit_Id := No_Unit_Id; -- The reference to unit this vertex represents @@ -1330,10 +1402,11 @@ package Bindo.Graphs is No_Library_Graph_Vertex_Attributes : constant Library_Graph_Vertex_Attributes := - (Corresponding_Item => No_Library_Graph_Vertex, - In_Elaboration_Order => False, - Pending_Predecessors => 0, - Unit => No_Unit_Id); + (Corresponding_Item => No_Library_Graph_Vertex, + In_Elaboration_Order => False, + Pending_Strong_Predecessors => 0, + Pending_Weak_Predecessors => 0, + Unit => No_Unit_Id); procedure Destroy_Library_Graph_Vertex_Attributes (Attrs : in out Library_Graph_Vertex_Attributes); @@ -1391,13 +1464,18 @@ package Bindo.Graphs is -- The following type represents the attributes of a component type Component_Attributes is record - Pending_Predecessors : Natural := 0; - -- The number of pending predecessor components this component must - -- wait on before it can be elaborated. + Pending_Strong_Predecessors : Natural := 0; + -- The number of pending strong predecessor components this component + -- must wait on before it can be elaborated. + + Pending_Weak_Predecessors : Natural := 0; + -- The number of pending weak predecessor components this component + -- must wait on before it can be elaborated. end record; No_Component_Attributes : constant Component_Attributes := - (Pending_Predecessors => 0); + (Pending_Strong_Predecessors => 0, + Pending_Weak_Predecessors => 0); procedure Destroy_Component_Attributes (Attrs : in out Component_Attributes); @@ -1560,10 +1638,6 @@ package Bindo.Graphs is Cycles : LGC_Lists.Doubly_Linked_List := LGC_Lists.Nil; -- The list of all cycles in the graph, sorted based on precedence - Dynamically_Elaborated : Boolean := False; - -- Set when the main library unit was compiled using the dynamic - -- model. - Edge_Attributes : LGE_Tables.Dynamic_Hash_Table := LGE_Tables.Nil; -- The map of edge -> edge attributes for all edges in the graph diff --git a/gcc/ada/bindo-validators.adb b/gcc/ada/bindo-validators.adb index aed49600369..88be2e8f9ed 100644 --- a/gcc/ada/bindo-validators.adb +++ b/gcc/ada/bindo-validators.adb @@ -140,7 +140,7 @@ package body Bindo.Validators is Edges := LGE_Sets.Create (Length (G, Cycle)); - -- Inspect the edges of the cucle, trying to catch duplicates + -- Inspect the edges of the cycle, trying to catch duplicates Iter := Iterate_Edges_Of_Cycle (G, Cycle); while Has_Next (Iter) loop @@ -155,7 +155,7 @@ package body Bindo.Validators is Write_Str (" library graph edge (LGE_Id_"); Write_Int (Int (Edge)); - Write_Str (") is repeaded in cycle (LGC_Id_"); + Write_Str (") is repeated in cycle (LGC_Id_"); Write_Int (Int (Cycle)); Write_Str (")"); Write_Eol; @@ -421,7 +421,7 @@ package body Bindo.Validators is (G : Invocation_Graph; Vertex : Invocation_Graph_Vertex_Id); pragma Inline (Validate_Invocation_Graph_Vertex); - -- Verify that the attributes of vertex Vertex of inbocation graph G are + -- Verify that the attributes of vertex Vertex of invocation graph G are -- properly set. procedure Validate_Invocation_Graph_Vertices (G : Invocation_Graph); @@ -468,7 +468,7 @@ package body Bindo.Validators is if not Present (Edge) then Write_Error (Msg, Has_Invalid_Data); - Write_Str (" emply invocation graph edge"); + Write_Str (" empty invocation graph edge"); Write_Eol; Write_Eol; return; @@ -530,7 +530,7 @@ package body Bindo.Validators is if not Present (Vertex) then Write_Error (Msg, Has_Invalid_Data); - Write_Str (" emply invocation graph vertex"); + Write_Str (" empty invocation graph vertex"); Write_Eol; Write_Eol; return; @@ -662,7 +662,7 @@ package body Bindo.Validators is if not Present (Edge) then Write_Error (Msg, Has_Invalid_Data); - Write_Str (" emply library graph edge"); + Write_Str (" empty library graph edge"); Write_Eol; Write_Eol; return; diff --git a/gcc/ada/bindo-writers.adb b/gcc/ada/bindo-writers.adb index a3b45fce766..99f93f5e403 100644 --- a/gcc/ada/bindo-writers.adb +++ b/gcc/ada/bindo-writers.adb @@ -1025,6 +1025,10 @@ package body Bindo.Writers is -- Write all vertices of component Comp of library graph G to standard -- output. + procedure Write_Components (G : Library_Graph); + pragma Inline (Write_Component); + -- Write all components of library graph G to standard output + procedure Write_Edges_To_Successors (G : Library_Graph; Vertex : Library_Graph_Vertex_Id); @@ -1089,8 +1093,12 @@ package body Bindo.Writers is Write_Str (")"); Write_Eol; - Write_Str (" Pending_Predecessors = "); - Write_Int (Int (Pending_Predecessors (G, Comp))); + Write_Str (" Pending_Strong_Predecessors = "); + Write_Int (Int (Pending_Strong_Predecessors (G, Comp))); + Write_Eol; + + Write_Str (" Pending_Weak_Predecessors = "); + Write_Int (Int (Pending_Weak_Predecessors (G, Comp))); Write_Eol; Write_Component_Vertices (G, Comp); @@ -1225,6 +1233,7 @@ package body Bindo.Writers is Write_Statistics (G); Write_Library_Graph_Vertices (G); + Write_Components (G); Write_Str ("Library Graph end"); Write_Eol; @@ -1312,8 +1321,12 @@ package body Bindo.Writers is end if; Write_Eol; - Write_Str (" Pending_Predecessors = "); - Write_Int (Int (Pending_Predecessors (G, Vertex))); + Write_Str (" Pending_Strong_Predecessors = "); + Write_Int (Int (Pending_Strong_Predecessors (G, Vertex))); + Write_Eol; + + Write_Str (" Pending_Weak_Predecessors = "); + Write_Int (Int (Pending_Weak_Predecessors (G, Vertex))); Write_Eol; Write_Str (" Component (Comp_Id_"); @@ -1612,7 +1625,7 @@ package body Bindo.Writers is is function Digits_Indentation return Indentation_Level; pragma Inline (Digits_Indentation); - -- Determine the level of indentation the number requies in order to + -- Determine the level of indentation the number requires in order to -- be right-justified by Val_Indent. ------------------------ diff --git a/gcc/ada/bindo-writers.ads b/gcc/ada/bindo-writers.ads index ff6b9b3b660..01e48e40fce 100644 --- a/gcc/ada/bindo-writers.ads +++ b/gcc/ada/bindo-writers.ads @@ -127,9 +127,6 @@ package Bindo.Writers is --------------------------- package Library_Graph_Writers is - procedure Write_Components (G : Library_Graph); - -- Write all components of library graph G to standard output - procedure Write_Library_Graph (G : Library_Graph); -- Write library graph G to standard output diff --git a/gcc/ada/bindo.adb b/gcc/ada/bindo.adb index b3106adfb25..897e7467f7d 100644 --- a/gcc/ada/bindo.adb +++ b/gcc/ada/bindo.adb @@ -74,7 +74,7 @@ package body Bindo is -- -- * Diagnose elaboration circularities between units -- - -- An elaboration circularity arrises when either + -- An elaboration circularity arises when either -- -- - At least one unit cannot be ordered, or -- @@ -95,6 +95,12 @@ package body Bindo is -- * Component - A strongly connected component of a graph. -- + -- * Elaborable component - A component that is not waiting on other + -- components to be elaborated. + -- + -- * Elaborable vertex - A vertex that is not waiting on strong and weak + -- predecessors, and whose component is elaborable. + -- -- * Elaboration circularity - A cycle involving units from the bind. -- -- * Elaboration root - A special invocation construct which denotes the @@ -136,8 +142,23 @@ package body Bindo is -- * Pending predecessor - A vertex that must be elaborated before another -- vertex can be elaborated. -- + -- * Strong edge - A non-invocation library graph edge. Strong edges + -- represent the language-defined relations between units. + -- + -- * Strong predecessor - A library graph vertex reachable via a strong + -- edge. + -- -- * Target - The destination construct of an invocation relation (the -- generic, subprogram, or task type). + -- + -- * Weak edge - An invocation library graph edge. Weak edges represent + -- the speculative flow of execution at elaboration time, which may or + -- may not take place. + -- + -- * Weak predecessor - A library graph vertex reachable via a weak edge. + -- + -- * Weakly elaborable vertex - A vertex that is waiting solely on weak + -- predecessors to be elaborated, and whose component is elaborable. ------------------ -- Architecture -- @@ -233,7 +254,7 @@ package body Bindo is -- bodies as single vertices. -- -- * Try to order as many vertices of the library graph as possible by - -- peforming a topological sort based on the pending predecessors of + -- performing a topological sort based on the pending predecessors of -- vertices across all components and within a single component. -- -- * Validate the consistency of the order, only when switch -d_V is in @@ -251,7 +272,7 @@ package body Bindo is -- The Diagnostics phase has the following objectives: -- -- * Discover, save, and sort all cycles in the library graph. The cycles - -- are sorted based on the following heiristics: + -- are sorted based on the following heuristics: -- -- - A cycle with higher precedence is preferred. -- @@ -268,7 +289,7 @@ package body Bindo is -- * Diagnose the most important cycle, or all cycles when switch -d_C is -- in effect. The diagnostic consists of: -- - -- - The reason for the existance of the cycle, along with the unit + -- - The reason for the existence of the cycle, along with the unit -- whose elaboration cannot be guaranteed. -- -- - A detailed traceback of the cycle, showcasing the transition @@ -276,7 +297,7 @@ package body Bindo is -- information. -- -- - A set of suggestions on how to break the cycle considering the - -- the edges coprising the circuit, the elaboration model used to + -- the edges comprising the circuit, the elaboration model used to -- compile the units, the availability of invocation information, -- and the state of various relevant switches. @@ -284,6 +305,23 @@ package body Bindo is -- Switches -- -------------- + -- -d_a Ignore the effects of pragma Elaborate_All + -- + -- GNATbind creates a regular with edge instead of an Elaborate_All + -- edge in the library graph, thus eliminating the effects of the + -- pragma. + -- + -- -d_b Ignore the effects of pragma Elaborate_Body + -- + -- GNATbind treats a spec and body pair as decoupled. + -- + -- -d_e Ignore the effects of pragma Elaborate + -- + -- GNATbind creates a regular with edge instead of an Elaborate edge + -- in the library graph, thus eliminating the effects of the pragma. + -- In addition, GNATbind does not create an edge to the body of the + -- pragma argument. + -- -- -d_A Output ALI invocation tables -- -- GNATbind outputs the contents of ALI table Invocation_Constructs diff --git a/gcc/ada/bindo.ads b/gcc/ada/bindo.ads index 39cf7a49373..940b752e484 100644 --- a/gcc/ada/bindo.ads +++ b/gcc/ada/bindo.ads @@ -41,4 +41,14 @@ package Bindo is -- exists, it is returned in Order, otherwise Unrecoverable_Error is -- raised. +private + + -- The following type represents the various kinds of precedence between + -- two items. + + type Precedence_Kind is + (Lower_Precedence, + Equal_Precedence, + Higher_Precedence); + end Bindo; diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb index da4bea1fec4..680c38fa4ce 100644 --- a/gcc/ada/debug.adb +++ b/gcc/ada/debug.adb @@ -349,11 +349,11 @@ package body Debug is -- d.8 -- d.9 - -- d_a - -- d_b + -- d_a Ignore the effects of pragma Elaborate_All + -- d_b Ignore the effects of pragma Elaborate_Body -- d_c -- d_d - -- d_e + -- d_e Ignore the effects of pragma Elaborate -- d_f -- d_g -- d_h @@ -1141,6 +1141,17 @@ package body Debug is -- dx Force the binder to read (and then ignore) the xref information -- in ali files (used to check that read circuit is working OK). + -- d_a GNATBIND ignores the effects of pragma Elaborate_All in the case of + -- elaboration order and treats the associated dependency as a regular + -- with edge. + + -- d_b GNATBIND ignores the effects of pragma Elaborate_Body in the case + -- of elaboration order and treats the spec and body as decoupled. + + -- d_e GNATBIND ignores the effects of pragma Elaborate in the case of + -- elaboration order and no longer creates an implicit dependency on + -- the body of the argument. + -- d_A GNATBIND output the contents of all ALI invocation-related tables -- in textual format to standard output. -- 2.30.2