diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2019-07-08 08:13:43 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-08 08:13:43 +0000 |
commit | 92c7734db7af1395be571c5ec023a38fb7b42adf (patch) | |
tree | 2a24490b459eb9348717049e1670a899ba5b2aab /gcc/ada/bindo.adb | |
parent | 79ee9e32b17be333e6c70a104c7049c8cab40834 (diff) | |
download | gcc-92c7734db7af1395be571c5ec023a38fb7b42adf.zip gcc-92c7734db7af1395be571c5ec023a38fb7b42adf.tar.gz gcc-92c7734db7af1395be571c5ec023a38fb7b42adf.tar.bz2 |
[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 <kirtchev@adacore.com>
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
Diffstat (limited to 'gcc/ada/bindo.adb')
-rw-r--r-- | gcc/ada/bindo.adb | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/gcc/ada/bindo.adb b/gcc/ada/bindo.adb index b3106ad..897e746 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 |