diff options
author | Hristian Kirtchev <kirtchev@adacore.com> | 2019-07-05 07:02:08 +0000 |
---|---|---|
committer | Pierre-Marie de Rodat <pmderodat@gcc.gnu.org> | 2019-07-05 07:02:08 +0000 |
commit | 9795b20366362d63be058f1e4f3009d6bad79310 (patch) | |
tree | aba3763d81a519c490994b1fce8918c7e31e31c2 /gcc/ada/bindo.adb | |
parent | db6261488e4e53e4ac09ec9db50ea2e4a1859377 (diff) | |
download | gcc-9795b20366362d63be058f1e4f3009d6bad79310.zip gcc-9795b20366362d63be058f1e4f3009d6bad79310.tar.gz gcc-9795b20366362d63be058f1e4f3009d6bad79310.tar.bz2 |
[Ada] Diagnostics in Elaboration order v4.0
This patch introduces several changes to the new elaboration order
mechanism:
* The library graph can now discover, store, and organize the various
cycles it contains.
* The elaboration order mechanism can now diagnose one or all cycles
within the library graph. Diagnostics consist of describing the
reason for the cycle, listing all units comprising the circuit, and
offering suggestions on how to break the cycle.
The patch also modifies unit ALI to hide all invocation-related data
structures and several implementation-specific types by relocating them
in the body of the unit.
The patch cleans up most children of Bindo by using better names of
routines and formal parameters.
------------
-- Source --
------------
-- a.ads
with B; pragma Elaborate_All (B);
with C; pragma Elaborate_All (C);
package A is
end A;
-- b.ads
package B is
procedure Force_Body;
end B;
-- b.adb
with D;
package body B is
procedure Force_Body is null;
Elab : constant Integer := D.Func;
end B;
-- c.ads
package C is
procedure Force_Body;
end C;
-- c.adb
with E;
package body C is
procedure Force_Body is null;
end C;
-- d.ads
package D is
function Func return Integer;
end D;
-- d.adb
with A;
package body D is
Local : Integer := 123;
function Func return Integer is
begin
return Local;
end Func;
end D;
-- e.ads
with A;
package E is
end E;
-- main.adb
with B;
-- Elaborate_All Elaborate_All with
-- C spec <--------------- A spec ---------------------> B spec <------ Main
-- ^ ^ ^ ^
-- | | | |
-- sbb | | | | sbb
-- | | | |
-- C body -----------> E spec | D spec <--------- B body
-- with | ^ with |
-- | | |
-- | sbb | |
-- | | |
-- +------ D body <------------+
-- with Invocation
--
-- The cycles are
--
-- A spec --> C spec --> E spec --> A spec
-- C body
--
-- A spec --> B spec --> D body --> A spec
-- B body
procedure Main is begin null; end Main;
----------------------------
-- Compilation and output --
----------------------------
$ gnatmake -q main.adb -bargs -d_C -d_N
error: Elaboration circularity detected
info:
info: Reason:
info:
info: unit "a (spec)" depends on its own elaboration
info:
info: Circularity:
info:
info: unit "a (spec)" has with clause and pragma Elaborate_All for unit
"b (spec)"
info: unit "b (body)" is in the closure of pragma Elaborate_All
info: unit "b (body)" has with clause for unit "d (spec)"
info: unit "d (body)" is in the closure of pragma Elaborate_All
info: unit "d (body)" has with clause for unit "a (spec)"
info:
info: Suggestions:
info:
info: change pragma Elaborate_All for unit "b (spec)" to Elaborate in unit
"a (spec)"
info: remove pragma Elaborate_All for unit "b (spec)" in unit "a (spec)"
info:
error: Elaboration circularity detected
info:
info: Reason:
info:
info: unit "a (spec)" depends on its own elaboration
info:
info: Circularity:
info:
info: unit "a (spec)" has with clause and pragma Elaborate_All for unit
"c (spec)"
info: unit "c (body)" is in the closure of pragma Elaborate_All
info: unit "c (body)" has with clause for unit "e (spec)"
info: unit "e (spec)" has with clause for unit "a (spec)"
info:
info: Suggestions:
info:
info: change pragma Elaborate_All for unit "c (spec)" to Elaborate in unit
"a (spec)"
info: remove pragma Elaborate_All for unit "c (spec)" in unit "a (spec)"
info:
gnatmake: *** bind failed.
2019-07-05 Hristian Kirtchev <kirtchev@adacore.com>
gcc/ada/
* ali.adb: Relocate types Invocation_Construct_Record,
Invocation_Relation_Record, and Invocation_Signature_Record to
the body of ALI. Relocate tables Invocation_Constructs,
Invocation_Relations, and Invocation_Signatures to the body of
ALI. Remove type Body_Placement_Codes. Add new types
Declaration_Placement_Codes, and
Invocation_Graph_Encoding_Codes. Update the literals of type
Invocation_Graph_Line_Codes.
(Add_Invocation_Construct): Update the parameter profile. Add an
invocation construct built from all attributes provided.
(Add_Invocation_Relation): Update the parameter profile. Add an
invocation relation built from all attributes provided.
(Body_Placement): New routine.
(Body_Placement_Kind_To_Code, Code_To_Body_Placement_Kind):
Removed.
(Code_To_Declaration_Placement_Kind,
Code_To_Invocation_Graph_Encoding_Kind, Column,
Declaration_Placement_Kind_To_Code, Extra,
For_Each_Invocation_Construct, For_Each_Invocation_Relation,
Invocation_Graph_Encoding,
Invocation_Graph_Encoding_Kind_To_Code, Invoker, Kind, Line,
Locations, Name): New routine.
(Scan_Invocation_Construct_Line): Reimplement the scanning
mechanism.
(Scan_Invocation_Graph_Attributes_Line): New routine.
(Scan_Invocation_Graph_Line): Use a case statement to dispatch.
(Scan_Invocation_Relation_Line): Reimplement the scanning
mechanism.
(Scope): New routine.
(Set_Invocation_Graph_Encoding, Signature, Spec_Placement,
Target): New routine.
* ali.ads: Add new type Invocation_Graph_Encoding_Kind. Add
component Invocation_Graph_Encoding to type Unit_Record.
Relocate various types and data structures to the body of ALI.
(Add_Invocation_Construct, Add_Invocation_Relation): Update the
parameter profile.
(Body_Placement): New routine.
(Body_Placement_Kind_To_Code, Code_To_Body_Placement_Kind):
Removed.
(Code_To_Declaration_Placement_Kind,
Code_To_Invocation_Graph_Encoding_Kind, Column,
Declaration_Placement_Kind_To_Code, Extra,
For_Each_Invocation_Construct, For_Each_Invocation_Relation,
Invocation_Graph_Encoding,
Invocation_Graph_Encoding_Kind_To_Code, Invoker, Kind, Line,
Locations, Name, Scope, Set_Invocation_Graph_Encoding,
Signature, Spec_Placement, Target): New routine.
* bindo.adb: Add with clause for Binde. Add with and use
clauses for Debug. Update the documentation. Add new switches.
(Find_Elaboration_Order): Dispatch to the proper elaboration
mechanism.
* bindo-augmentors.adb:
Remove with and use clauses for GNAT and GNAT.Sets. Remove
membership set VS. Update the parameter profiles of most
routines to use better parameter names. Update the
implementation of most routine to use the new parameter names.
Remove various redundant assertions.
* bindo-builders.adb: Use better names for instantiated data
structures. Update all references to these names. Update the
parameter profiles of most routines to use better parameter
names. Update the implementation of most routine to use the new
parameter names.
(Build_Library_Graph): Update the parameter profile. Update the
call to Create.
(Create_Vertex): Reimplemented.
(Declaration_Placement_Vertex): New routine.
* bindo-builders.ads (Build_Library_Graph): Update the parameter
profile and comment on usage.
* bindo-diagnostics.adb: Almost a new unit.
* bindo-diagnostics.ads: Add a use clause for
Bindo.Graphs.Invocation_Graphs. Remove package
Cycle_Diagnostics.
(Diagnose_Circularities): New routine.
* bindo-elaborators.adb: Remove the with and use clauses for
Binderr and GNAT.Sets. Remove the use clause for
Bindo.Diagnostics.Cycle_Diagnostics. Remove membership set VS.
Update the parameter profiles of most routines to use better
parameter names. Update the implementation of most routine to
use the new parameter names. (Elaborate_Units_Common): Update
the parameter profile. Pass an infication to the library graph
builder whether the dynamic model is in effect.
(Elaborate_Units_Dynamic, Elaborate_Units_Static): Use
Diagnose_Circularities to provide diagnostics.
(Update_Successor): Use routine In_Same_Component to determine
whether the predecessor and successor reside in different
components.
* bindo-graphs.adb: Add with and use clauses for Butil, Debug,
Output, and Bindo.Writers. Remove with and use clauses for
GNAT.Lists. Update the parameter profiles of most routines to
use better parameter names. Update the implementation of most
routine to use the new parameter names. Remove various
redundant assertions. Remove doubly linked list EL. Add new
type Precedence_Kind.
(Add_Cycle): New routine.
(Add_Vertex): Update the parameter profile. Update the creation
of vertex attributes.
(Add_Vertex_And_Complement, Body_Vertex, Column,
Complementary_Vertex, Copy_Cycle_Path, Cycle_Kind_Of): New
routines.
(Destroy_Invocation_Graph_Edge, Destroy_Library_Graph_Cycle,
Destroy_Library_Graph_Edge, Extra, File_Name,
Find_All_Cycles_Through_Vertex, Find_All_Cycles_With_Edge,
Find_Cycles, Find_First_Lower_Precedence_Cycle,
Get_LGC_Attributes, Has_Next, Hash_Library_Graph_Cycle,
Hash_Library_Graph_Cycle_Attributes, Highest_Precedence_Cycle,
Highest_Precedence_Edge, In_Same_Component, Insert_And_Sort,
Invocation_Edge_Count, Invocation_Graph_Encoding,
Is_Cycle_Initiating_Edge, Is_Cyclic_Edge,
Is_Cyclic_Elaborate_All_Edge, Is_Cyclic_Elaborate_Body_Edge,
Is_Cyclic_Elaborate_Edge, Is_Cyclic_Forced_Edge,
Is_Cyclic_Invocation_Edge, Is_Cyclic_With_Edge,
Is_Dynamically_Elaborated, Is_Elaborate_All_Edge,
Is_Elaborate_Body_Edge, Is_Elaborate_Edge: New routines.
(Is_Existing_Predecessor_Successor_Relation): Removed.
(Is_Forced_Edge, Is_Invocation_Edge, Is_Recorded_Cycle,
Is_Recorded_Edge, Is_With_Edge, Iterate_Edges_Of_Cycle, Kind,
Length): New routine.
(Lib_Vertex): Removed.
(Line, Links_Vertices_In_Same_Component,
Maximum_Invocation_Edge_Count, Next, Normalize_And_Add_Cycle,
Normalize_Cycle_Path, Number_Of_Cycles, Path, Precedence,
Remove_Vertex_And_Complement, Sequence_Next_Cycle): New routines.
(Sequence_Next_IGE_Id): Renamed to Sequence_Next_Edge.
(Sequence_Next_IGV_Id): Renamed to Sequence_Next_Vertex.
(Sequence_Next_LGE_Id): Renamed to Sequence_Next_Edge.
(Sequence_Next_LGV_Id): Renamed to Sequence_Next_Vertex.
(Set_Is_Existing_Predecessor_Successor_Relation): Removed.
(Set_Is_Recorded_Cycle, Set_Is_Recorded_Edge,
Set_LGC_Attributes, Spec_Vertex, Trace_Cycle, Trace_Edge,
Trace_Eol, Trace_Vertex): New routines.
* bindo-graphs.ads: Add with and use clauses for Types and
GNAT.Lists. Update the parameter profiles of most routines to
use better parameter names. Update the implementation of most
routine to use the new parameter names. Add the new
instantiated data structures IGE_Lists, IGV_Sets, LGC_Lists,
LGE_Lists, LGE_Sets, LGV_Sets, and RC_Sets. Add new type
Library_Graph_Cycle_Id along with an empty and initial value.
Remove component Lib_Vertex and add new components Body_Vertex
and Spec_Vertex to type Invocation_Graph_Vertex_Attributes. Add
new type Library_Graph_Cycle_Kind. Add new iterators
All_Cycle_Iterator and Edges_Of_Cycle_Iterator. Add new type
Library_Graph_Cycle_Attributes. Add new components
Cycle_Attributes, Cycles, and Dynamically_Elaborated to type
Library_Graph_Attributes.
(Body_Vertex, Column, Destroy_Invocation_Graph_Edge,
Destroy_Library_Graph_Cycle_Attributes,
Destroy_Library_Graph_Edge, Extra, File_Name, Find_Cycles,
Has_Elaborate_All_Cycle, Has_Next, Hash_Library_Graph_Cycle,
Hash_Library_Graph_Cycle_Attributes, Highest_Precedence_Cycle,
In_Same_Component, Invocation_Edge_Count,
Invocation_Graph_Encoding, Is_Dynamically_Elaborated,
Is_Elaborate_All_Edge, Is_Elaborate_Body_Edge,
Is_Elaborate_Edge, Is_Forced_Edge, Is_Invocation_Edge,
Is_With_Edge, Iterate_All_Cycles, Iterate_Edges_Of_Cycle, Kind):
New routines.
(Length, Lib_Vertex, (Line, Next, Number_Of_Cycles, Present,
Same_Library_Graph_Cycle_Attributes, Spec_Vertex): New routines.
* bindo-units.adb (File_Name, Invocation_Graph_Encoding): New
routines.
* bindo-units.ads: Add new instantiated data structure
Unit_Sets.
(File_Name, Invocation_Graph_Encoding): New routine.
* bindo-validators.adb: Remove with and use clauses for GNAT and
GNAT.Sets. Remove membership set US. Update the parameter
profiles of most routines to use better parameter names. Update
the implementation of most routine to use the new parameter
names.
(Validate_Cycle, Validate_Cycle_Path, Validate_Cycles,
Validate_Invocation_Graph_Vertex): Remove the validation of
component Lib_Vertex. Add the validation of components
Body_Vertex and Spec_Vertex.
(Write_Error): New routine.
* bindo-validators.ads (Validate_Cycles): New routine.
* bindo-writers.adb: Update the parameter profiles of most
routines to use better parameter names. Update the
implementation of most routine to use the new parameter names.
(Write_Cycle, Write_Cyclic_Edge, Write_Cycles): New routines.
(Write_Invocation_Graph_Vertex): Remove the output of component
Lib_Vertex. Add the output of components Body_Vertex and
Spec_Vertex.
* bindo-writers.ads (Write_Cycles): New routine.
* debug.adb: Use binder switches -d_C and -d_P, add
documentation on their usage.
* gnatbind.adb: Remove with and use clauses for Binde. Delegate
the choice of elaboration mechanism to Bindo.
* lib-writ.adb (Column, Extra, Invoker, Kind, Line, Locations,
Name, Placement, Scope, Signature, Target): Removed.
(Write_Invocation_Graph): Moved at the top level.
(Write_Invocation_Graph_Attributes): New routine.
(Write_Invocation_Relation, Write_Invocation_Signature): Moved
at the top level.
* lib-writ.ads: Add a documentation section on invocation graph
attributes.
* sem_elab.adb (Body_Placement_Of): New routine.
(Declare_Invocation_Construct): Update the call to
Add_Invocation_Construct.
(Declaration_Placement_Of_Node): New routine.
(Get_Invocation_Attributes): Correct the retrieval of the
enclosing subprogram where the postcondition procedure lives.
(Placement_Of, Placement_Of_Node): Removed.
(Record_Invocation_Graph): Record the encoding format used.
(Record_Invocation_Graph_Encoding): New routine.
(Record_Invocation_Relation): Update the call to
Add_Invocation_Relation.
(Spec_Placement_Of): Removed.
* libgnat/g-lists.ads, libgnat/g-lists.adb (Equal): New routine.
From-SVN: r273107
Diffstat (limited to 'gcc/ada/bindo.adb')
-rw-r--r-- | gcc/ada/bindo.adb | 125 |
1 files changed, 100 insertions, 25 deletions
diff --git a/gcc/ada/bindo.adb b/gcc/ada/bindo.adb index 7d26476..039fd0d 100644 --- a/gcc/ada/bindo.adb +++ b/gcc/ada/bindo.adb @@ -23,8 +23,11 @@ -- -- ------------------------------------------------------------------------------ +with Binde; +with Debug; use Debug; + with Bindo.Elaborators; -use Bindo.Elaborators.Invocation_And_Library_Graph_Elaborators; +use Bindo.Elaborators; package body Bindo is @@ -47,30 +50,44 @@ package body Bindo is -- - The flow of execution at elaboration time. -- -- - Additional dependencies between units supplied to the binder by - -- means of a file. + -- means of a forced-elaboration-order file. + -- + -- The high-level idea empoyed by the EO mechanism is to construct two + -- graphs and use the information they represent to find an ordering of + -- all units. -- - -- The high-level idea is to construct two graphs: + -- The invocation graph represents the flow of execution at elaboration + -- time. -- - -- - Invocation graph - Models the flow of execution at elaboration - -- time. + -- The library graph captures the dependencies between units expressed + -- by with clause and elaboration-related pragmas. The library graph is + -- further augmented with additional information from the invocation + -- graph by exploring the execution paths from a unit with elaboration + -- code to other external units. -- - -- - Library graph - Represents with clause and pragma dependencies - -- between units. + -- The strongly connected components of the library graph are computed. -- - -- The library graph is further augmented with additional information - -- from the invocation graph by exploring the execution paths from a - -- unit with elaboration code to other external units. All strongly - -- connected components of the library graph are discovered. Finally, - -- the order is obtained via a topological sort-like algorithm which - -- attempts to order available units while enabling other units to be + -- The order is obtained using a topological sort-like algorithm which + -- traverses the library graph and its strongly connected components in + -- an attempt to order available units while enabling other units to be -- ordered. -- -- * Diagnose elaboration circularities between units -- - -- The library graph may contain at least one cycle, in which case no - -- ordering is possible. + -- An elaboration circularity arrises when either + -- + -- - At least one unit cannot be ordered, or + -- + -- - All units can be ordered, but an edge with an Elaborate_All + -- pragma links two vertices within the same component of the + -- library graph. -- - -- ??? more on this later + -- The library graph is traversed to discover, collect, and sort all + -- cycles that hinder the elaboration order. + -- + -- The most important cycle is diagnosed by describing its effects on + -- the elaboration order and listing all units comprising the circuit. + -- Various suggestions on how to break the cycle are offered. ----------------- -- Terminology -- @@ -78,6 +95,8 @@ package body Bindo is -- * Component - A strongly connected component of a graph. -- + -- * Elaboration circularity - A cycle involving units from the bind. + -- -- * Elaboration root - A special invocation construct which denotes the -- elaboration procedure of a unit. -- @@ -162,7 +181,11 @@ package body Bindo is -- | -- +------ | -------------- Diagnostics phase -------------------------+ -- | | | - -- | +--> ??? more on this later | + -- | +--> Find_Cycles | + -- | +--> Validate_Cycles | + -- | +--> Write_Cycles | + -- | | | + -- | +--> Diagnose_Cycle / Diagnose_All_Cycles | -- | | -- +-------------------------------------------------------------------+ @@ -225,7 +248,37 @@ package body Bindo is -- Diagnostics phase -- ----------------------- - -- ??? more on this later + -- 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: + -- + -- - A cycle with higher precedence is preferred. + -- + -- - A cycle with fewer invocation edges is preferred. + -- + -- - A cycle with a shorter length is preferred. + -- + -- * Validate the consistency of cycles, only when switch -d_V is in + -- effect. + -- + -- * Write the contents of all cycles in human-readable form to standard + -- output when switch -d_O is in effect. + -- + -- * 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 + -- whose elaboration cannot be guaranteed. + -- + -- - A detailed traceback of the cycle, showcasing the transition + -- between units, along with any other elaboration order-related + -- information. + -- + -- - A set of suggestions on how to break the cycle considering the + -- the edges coprising the circuit, the elaboration model used to + -- compile the units, the availability of invocation information, + -- and the state of various relevant switches. -------------- -- Switches -- @@ -236,6 +289,11 @@ package body Bindo is -- GNATbind outputs the contents of ALI table Invocation_Constructs -- and Invocation_Edges in textual format to standard output. -- + -- -d_C Diagnose all cycles + -- + -- GNATbind outputs diagnostics for all unique cycles in the bind, + -- rather than just the most important one. + -- -- -d_I Output invocation graph -- -- GNATbind outputs the invocation graph in text format to standard @@ -255,16 +313,20 @@ package body Bindo is -- GNATbind outputs the elaboration order in text format to standard -- output. -- + -- -d_P Output cycle paths + -- + -- GNATbind output the cycle paths in text format to standard output + -- -- -d_T Output elaboration order trace information -- - -- GNATbind outputs trace information on elaboration order activities - -- to standard output. + -- GNATbind outputs trace information on elaboration order and cycle + -- detection activities to standard output. -- - -- -d_V Validate bindo graphs and order + -- -d_V Validate bindo cycles, graphs, and order -- - -- GNATbind validates the invocation graph, library graph, SCC graph - -- and elaboration order by detecting inconsistencies and producing - -- error reports. + -- GNATbind validates the invocation graph, library graph along with + -- its cycles, and elaboration order by detecting inconsistencies and + -- producing error reports. ---------------------------------------- -- Debugging elaboration order issues -- @@ -281,7 +343,20 @@ package body Bindo is Main_Lib_File : File_Name_Type) is begin - Elaborate_Units (Order, Main_Lib_File); + -- Use the invocation and library graph-based elaboration order when + -- switch -d_N (new bindo order) is in effect. + + if Debug_Flag_Underscore_NN then + Invocation_And_Library_Graph_Elaborators.Elaborate_Units + (Order => Order, + Main_Lib_File => Main_Lib_File); + + -- Otherwise use the library graph and heuristic-based elaboration + -- order. + + else + Binde.Find_Elab_Order (Order, Main_Lib_File); + end if; end Find_Elaboration_Order; end Bindo; |