[Ada] Elaboration order v4.0 and infinite loops
authorHristian Kirtchev <kirtchev@adacore.com>
Thu, 11 Jul 2019 08:01:21 +0000 (08:01 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Thu, 11 Jul 2019 08:01:21 +0000 (08:01 +0000)
This patch introduces binder switch -d_S which prompts the various
phases of the elaboration order mechanism to output a short message
concerning their commencement and completion. The output is useful when
trying to determine whether a phase is stuck in an infinite loop.

------------
-- Source --
------------

--  main.adb

procedure Main is begin null; end Main;

----------------------------
-- Compilation and output --
----------------------------

$ gnatmake -q main.adb -bargs -d_S -d_V
elaborating units...
collecting units...
units collected.
constructing library graph...
validating library graph...
library graph validated.
library graph constructed.
constructing invocation graph...
validating invocation graph...
invocation graph validated.
invocation graph constructed.
augmenting library graph...
library graph augmented.
discovering components...
components discovered.
validating elaboration order...
elaboration order validated.
units elaborated.

2019-07-11  Hristian Kirtchev  <kirtchev@adacore.com>

gcc/ada/

* bindo.adb: Update the section of switches and debugging
elaboration issues.
* bindo.ads: Add type Elaboration_Phase.
* bindo-augmentors.adb: Add use clause for
Bindo.Writers.Phase_Writers.
(Augment_Library_Graph): Signal the start and end of the
aubmentation phase.
* bindo-builders.adb: Add with and use clause for Bindo.Writers.
Add use clause for Bindo.Writers.Phase_Writers.
(Build_Invocation_Graph): Signal the start and end of the
invocation graph construction phase.
(Build_Library_Graph): Signal the start and end of the library
graph construction phase.
* bindo-diagnostics.adb: Add use clause for
Bindo.Writers.Phase_Writers.
(Diagnose_Cycle): Signal the start and end of the cycle
diagnostic phase.
* bindo-elaborators.adb: Add use clause for
Bindo.Writers.Phase_Writers.
(Elaborate_Units): Signal the start and end of the unit
elaboration phase.
* bindo-graphs.adb: Add use clause for
Bindo.Writers.Phase_Writers.
(Find_Components): Signal the start and end of the component
discovery phase.
(Find_Cycles): Signal the start and end of the cycle discovery
phase.
* bindo-units.adb: Add with and use clause for Bindo.Writers.
Add use clause for Bindo.Writers.Phase_Writers.
(Collect_Elaborable_Units): Signal the start and end of the unit
collection phase.
* bindo-validators.adb: Add with and use clause for
Bindo.Writers.  Add use clause for Bindo.Writers.Phase_Writers.
(Validate_Cycles, Validate_Elaboration_Order,
Validate_Invocation_Graph, Validate_Library_Graph): Signal the
start and end of the libray graph validation phase.
* bindo-writers.ads, bindo-writers.adb: Add new nested package
Phase_Writers.
* debug.adb: Update the documentation of switch d_S.

From-SVN: r273379

13 files changed:
gcc/ada/ChangeLog
gcc/ada/bindo-augmentors.adb
gcc/ada/bindo-builders.adb
gcc/ada/bindo-diagnostics.adb
gcc/ada/bindo-elaborators.adb
gcc/ada/bindo-graphs.adb
gcc/ada/bindo-units.adb
gcc/ada/bindo-validators.adb
gcc/ada/bindo-writers.adb
gcc/ada/bindo-writers.ads
gcc/ada/bindo.adb
gcc/ada/bindo.ads
gcc/ada/debug.adb

index a2316eaf33eeff4fa39cd5bb3b7fc92c76744401..fa580d293f0f0bf3f1f274d41f680f7dca8d4324 100644 (file)
@@ -1,3 +1,45 @@
+2019-07-11  Hristian Kirtchev  <kirtchev@adacore.com>
+
+       * bindo.adb: Update the section of switches and debugging
+       elaboration issues.
+       * bindo.ads: Add type Elaboration_Phase.
+       * bindo-augmentors.adb: Add use clause for
+       Bindo.Writers.Phase_Writers.
+       (Augment_Library_Graph): Signal the start and end of the
+       aubmentation phase.
+       * bindo-builders.adb: Add with and use clause for Bindo.Writers.
+       Add use clause for Bindo.Writers.Phase_Writers.
+       (Build_Invocation_Graph): Signal the start and end of the
+       invocation graph construction phase.
+       (Build_Library_Graph): Signal the start and end of the library
+       graph construction phase.
+       * bindo-diagnostics.adb: Add use clause for
+       Bindo.Writers.Phase_Writers.
+       (Diagnose_Cycle): Signal the start and end of the cycle
+       diagnostic phase.
+       * bindo-elaborators.adb: Add use clause for
+       Bindo.Writers.Phase_Writers.
+       (Elaborate_Units): Signal the start and end of the unit
+       elaboration phase.
+       * bindo-graphs.adb: Add use clause for
+       Bindo.Writers.Phase_Writers.
+       (Find_Components): Signal the start and end of the component
+       discovery phase.
+       (Find_Cycles): Signal the start and end of the cycle discovery
+       phase.
+       * bindo-units.adb: Add with and use clause for Bindo.Writers.
+       Add use clause for Bindo.Writers.Phase_Writers.
+       (Collect_Elaborable_Units): Signal the start and end of the unit
+       collection phase.
+       * bindo-validators.adb: Add with and use clause for
+       Bindo.Writers.  Add use clause for Bindo.Writers.Phase_Writers.
+       (Validate_Cycles, Validate_Elaboration_Order,
+       Validate_Invocation_Graph, Validate_Library_Graph): Signal the
+       start and end of the libray graph validation phase.
+       * bindo-writers.ads, bindo-writers.adb: Add new nested package
+       Phase_Writers.
+       * debug.adb: Update the documentation of switch d_S.
+
 2019-07-11  Yannick Moy  <moy@adacore.com>
 
        * sem_res.adb (Check_Argument_Order): Special case calls to
index e0e23386672ae3277238d804987836ee9f740049..57fb5418b34f846f1ec60aa759360a5b2d9b98b2 100644 (file)
@@ -27,7 +27,9 @@ with Debug;  use Debug;
 with Output; use Output;
 with Types;  use Types;
 
-with Bindo.Writers; use Bindo.Writers;
+with Bindo.Writers;
+use  Bindo.Writers;
+use  Bindo.Writers.Phase_Writers;
 
 package body Bindo.Augmentors is
 
@@ -124,6 +126,8 @@ package body Bindo.Augmentors is
             return;
          end if;
 
+         Start_Phase (Library_Graph_Augmentation);
+
          --  Prepare the statistics data
 
          Longest_Path  := 0;
@@ -131,6 +135,8 @@ package body Bindo.Augmentors is
 
          Visit_Elaboration_Roots (Inv_Graph, Lib_Graph);
          Write_Statistics;
+
+         End_Phase (Library_Graph_Augmentation);
       end Augment_Library_Graph;
 
       ----------------------------
index 351b10d8fc81734a8ce217b5743eae912cbbd9d7..9919007d53cb8ac36a291bf9b0fd8d1fd2570733 100644 (file)
@@ -37,6 +37,10 @@ use  Bindo.Validators;
 use  Bindo.Validators.Invocation_Graph_Validators;
 use  Bindo.Validators.Library_Graph_Validators;
 
+with Bindo.Writers;
+use  Bindo.Writers;
+use  Bindo.Writers.Phase_Writers;
+
 with GNAT;                 use GNAT;
 with GNAT.Dynamic_HTables; use GNAT.Dynamic_HTables;
 
@@ -99,6 +103,8 @@ package body Bindo.Builders is
       begin
          pragma Assert (Present (Lib_G));
 
+         Start_Phase (Invocation_Graph_Construction);
+
          --  Prepare the global data
 
          Inv_Graph :=
@@ -111,6 +117,7 @@ package body Bindo.Builders is
          For_Each_Elaborable_Unit (Create_Edges'Access);
 
          Validate_Invocation_Graph (Inv_Graph);
+         End_Phase (Invocation_Graph_Construction);
 
          return Inv_Graph;
       end Build_Invocation_Graph;
@@ -375,6 +382,8 @@ package body Bindo.Builders is
 
       function Build_Library_Graph return Library_Graph is
       begin
+         Start_Phase (Library_Graph_Construction);
+
          --  Prepare the global data
 
          Lib_Graph :=
@@ -388,6 +397,7 @@ package body Bindo.Builders is
          Create_Forced_Edges;
 
          Validate_Library_Graph (Lib_Graph);
+         End_Phase (Library_Graph_Construction);
 
          return Lib_Graph;
       end Build_Library_Graph;
index 9dbdfc0c0672d1416798b3f8883bb2d212d5c964..6f19ac0961a244c24a331c2ebe9fa17918c0b53b 100644 (file)
@@ -36,6 +36,7 @@ use  Bindo.Validators.Cycle_Validators;
 with Bindo.Writers;
 use  Bindo.Writers;
 use  Bindo.Writers.Cycle_Writers;
+use  Bindo.Writers.Phase_Writers;
 
 package body Bindo.Diagnostics is
 
@@ -348,6 +349,8 @@ package body Bindo.Diagnostics is
       Next_Edge    : Library_Graph_Edge_Id;
 
    begin
+      Start_Phase (Cycle_Diagnostics);
+
       First_Edge := No_Library_Graph_Edge;
 
       --  Inspect the edges of the cycle in pairs, emitting diagnostics based
@@ -402,6 +405,8 @@ package body Bindo.Diagnostics is
         (G          => Lib_Graph,
          Cycle      => Cycle,
          First_Edge => First_Edge);
+
+      End_Phase (Cycle_Diagnostics);
    end Diagnose_Cycle;
 
    --------------------------------------
index 0d9f207be3cd6087fd103a310fcc471ac75d8a38..9e207e1e8305222d1c44a8702633502317ace28f 100644 (file)
@@ -54,6 +54,7 @@ use  Bindo.Writers.Dependency_Writers;
 use  Bindo.Writers.Elaboration_Order_Writers;
 use  Bindo.Writers.Invocation_Graph_Writers;
 use  Bindo.Writers.Library_Graph_Writers;
+use  Bindo.Writers.Phase_Writers;
 use  Bindo.Writers.Unit_Closure_Writers;
 
 with GNAT;        use GNAT;
@@ -711,6 +712,8 @@ package body Bindo.Elaborators is
          Status    : Elaboration_Order_Status;
 
       begin
+         Start_Phase (Unit_Elaboration);
+
          --  Initialize all unit-related data structures and gather all units
          --  that need elaboration.
 
@@ -786,6 +789,7 @@ package body Bindo.Elaborators is
          --  Destroy all unit-related data structures
 
          Finalize_Units;
+         End_Phase (Unit_Elaboration);
 
          --  Halt the bind when there is no satisfactory elaboration order
 
index d254b1c45f034193da14ae40b9eaab9e91601fb5..9621bb4b4883043b4971f9a30a209d10184ba490 100644 (file)
@@ -31,6 +31,7 @@ with Output; use Output;
 
 with Bindo.Writers;
 use  Bindo.Writers;
+use  Bindo.Writers.Phase_Writers;
 
 package body Bindo.Graphs is
 
@@ -2636,6 +2637,8 @@ package body Bindo.Graphs is
       begin
          pragma Assert (Present (G));
 
+         Start_Phase (Component_Discovery);
+
          --  Initialize or reinitialize the components of the graph
 
          Initialize_Components (G);
@@ -2660,6 +2663,7 @@ package body Bindo.Graphs is
          --  before they can be elaborated.
 
          Update_Pending_Predecessors_Of_Components (G);
+         End_Phase (Component_Discovery);
       end Find_Components;
 
       -----------------
@@ -2683,6 +2687,8 @@ package body Bindo.Graphs is
       begin
          pragma Assert (Present (G));
 
+         Start_Phase (Cycle_Discovery);
+
          --  The cycles of graph G are discovered using Tarjan's enumeration
          --  of the elementary circuits of a directed-graph algorithm. Do not
          --  modify this code unless you intimately understand the algorithm.
@@ -2721,6 +2727,8 @@ package body Bindo.Graphs is
                Cycle_Count => Cycle_Count,
                Cycle_Limit => All_Cycle_Limit);
          end loop;
+
+         End_Phase (Cycle_Discovery);
       end Find_Cycles;
 
       --------------------------------
index 8b8fc283a98f926c227e8bf0c920eeb4c9648eee..284aa625c128f90fd5e2fe98c3ce859f92ecbdf7 100644 (file)
 --                                                                          --
 ------------------------------------------------------------------------------
 
+with Bindo.Writers;
+use  Bindo.Writers;
+use  Bindo.Writers.Phase_Writers;
+
 package body Bindo.Units is
 
    -------------------
@@ -79,9 +83,13 @@ package body Bindo.Units is
 
    procedure Collect_Elaborable_Units is
    begin
+      Start_Phase (Unit_Collection);
+
       for U_Id in ALI.Units.First .. ALI.Units.Last loop
          Process_Unit (U_Id);
       end loop;
+
+      End_Phase (Unit_Collection);
    end Collect_Elaborable_Units;
 
    ------------------------
index b711a91a31804a1afe1fcdffebb16ef120183b7f..584d33fc4884d1a6d693587a9a40d4227793e76f 100644 (file)
@@ -27,7 +27,12 @@ with Debug;  use Debug;
 with Output; use Output;
 with Types;  use Types;
 
-with Bindo.Units; use Bindo.Units;
+with Bindo.Units;
+use  Bindo.Units;
+
+with Bindo.Writers;
+use  Bindo.Writers;
+use  Bindo.Writers.Phase_Writers;
 
 package body Bindo.Validators is
 
@@ -188,6 +193,8 @@ package body Bindo.Validators is
             return;
          end if;
 
+         Start_Phase (Cycle_Validation);
+
          Iter := Iterate_All_Cycles (G);
          while Has_Next (Iter) loop
             Next (Iter, Cycle);
@@ -195,6 +202,8 @@ package body Bindo.Validators is
             Validate_Cycle (G, Cycle);
          end loop;
 
+         End_Phase (Cycle_Validation);
+
          if Has_Invalid_Cycle then
             raise Invalid_Cycle;
          end if;
@@ -330,8 +339,12 @@ package body Bindo.Validators is
             return;
          end if;
 
+         Start_Phase (Elaboration_Order_Validation);
+
          Validate_Units (Order);
 
+         End_Phase (Elaboration_Order_Validation);
+
          if Has_Invalid_Data then
             raise Invalid_Elaboration_Order;
          end if;
@@ -444,8 +457,12 @@ package body Bindo.Validators is
             return;
          end if;
 
+         Start_Phase (Invocation_Graph_Validation);
+
          Validate_Invocation_Graph_Vertices (G);
-         Validate_Invocation_Graph_Edges (G);
+         Validate_Invocation_Graph_Edges    (G);
+
+         End_Phase (Invocation_Graph_Validation);
 
          if Has_Invalid_Data then
             raise Invalid_Invocation_Graph;
@@ -638,8 +655,12 @@ package body Bindo.Validators is
             return;
          end if;
 
+         Start_Phase (Library_Graph_Validation);
+
          Validate_Library_Graph_Vertices (G);
-         Validate_Library_Graph_Edges (G);
+         Validate_Library_Graph_Edges    (G);
+
+         End_Phase (Library_Graph_Validation);
 
          if Has_Invalid_Data then
             raise Invalid_Library_Graph;
index c4784d4a3b92ae18eb76efcf220675fcf6601726..021d50f31d3094e0a6dc3332721313b9e1559455 100644 (file)
@@ -1404,6 +1404,94 @@ package body Bindo.Writers is
       end Write_Statistics;
    end Library_Graph_Writers;
 
+   -------------------
+   -- Phase_Writers --
+   -------------------
+
+   package body Phase_Writers is
+
+      subtype Phase_Message is String (1 .. 32);
+
+      --  The following table contains the phase-specific messages for phase
+      --  completion.
+
+      End_Messages : constant array (Elaboration_Phase) of Phase_Message :=
+        (Component_Discovery           => "components discovered.          ",
+         Cycle_Diagnostics             => "cycle diagnosed.                ",
+         Cycle_Discovery               => "cycles discovered.              ",
+         Cycle_Validation              => "cycles validated.               ",
+         Elaboration_Order_Validation  => "elaboration order validated.    ",
+         Invocation_Graph_Construction => "invocation graph constructed.   ",
+         Invocation_Graph_Validation   => "invocation graph validated.     ",
+         Library_Graph_Augmentation    => "library graph augmented.        ",
+         Library_Graph_Construction    => "library graph constructed.      ",
+         Library_Graph_Elaboration     => "library graph elaborated.       ",
+         Library_Graph_Validation      => "library graph validated.        ",
+         Unit_Collection               => "units collected.                ",
+         Unit_Elaboration              => "units elaborated.               ");
+
+      --  The following table contains the phase-specific messages for phase
+      --  commencement.
+
+      Start_Messages : constant array (Elaboration_Phase) of Phase_Message :=
+        (Component_Discovery           => "discovering components...       ",
+         Cycle_Diagnostics             => "diagnosing cycle...             ",
+         Cycle_Discovery               => "discovering cycles...           ",
+         Cycle_Validation              => "validating cycles...            ",
+         Elaboration_Order_Validation  => "validating elaboration order... ",
+         Invocation_Graph_Construction => "constructing invocation graph...",
+         Invocation_Graph_Validation   => "validating invocation graph...  ",
+         Library_Graph_Augmentation    => "augmenting library graph...     ",
+         Library_Graph_Construction    => "constructing library graph...   ",
+         Library_Graph_Elaboration     => "elaborating library graph...    ",
+         Library_Graph_Validation      => "validating library graph...     ",
+         Unit_Collection               => "collecting units...             ",
+         Unit_Elaboration              => "elaborating units...            ");
+
+      -----------------------
+      -- Local subprograms --
+      -----------------------
+
+      procedure Write_Phase_Message (Msg : Phase_Message);
+      pragma Inline (Write_Phase_Message);
+      --  Write elaboration phase-related message Msg to standard output
+
+      ---------------
+      -- End_Phase --
+      ---------------
+
+      procedure End_Phase (Phase : Elaboration_Phase) is
+      begin
+         Write_Phase_Message (End_Messages (Phase));
+      end End_Phase;
+
+      -----------------
+      -- Start_Phase --
+      -----------------
+
+      procedure Start_Phase (Phase : Elaboration_Phase) is
+      begin
+         Write_Phase_Message (Start_Messages (Phase));
+      end Start_Phase;
+
+      -------------------------
+      -- Write_Phase_Message --
+      -------------------------
+
+      procedure Write_Phase_Message (Msg : Phase_Message) is
+      begin
+         --  Nothing to do when switch -d_S (output elaboration order status)
+         --  is not in effect.
+
+         if not Debug_Flag_Underscore_SS then
+            return;
+         end if;
+
+         Write_Str (Msg);
+         Write_Eol;
+      end Write_Phase_Message;
+   end Phase_Writers;
+
    --------------------------
    -- Unit_Closure_Writers --
    --------------------------
index 01e48e40fce65c35f352c98a5f23f65a267ad4cd..66483d07278f285dc52aee6785eec4f22eb325b9 100644 (file)
@@ -132,6 +132,23 @@ package Bindo.Writers is
 
    end Library_Graph_Writers;
 
+   -------------------
+   -- Phase_Writers --
+   -------------------
+
+   package Phase_Writers is
+      procedure End_Phase (Phase : Elaboration_Phase);
+      pragma Inline (End_Phase);
+      --  Write the end message associated with elaboration phase Phase to
+      --  standard output.
+
+      procedure Start_Phase (Phase : Elaboration_Phase);
+      pragma Inline (Start_Phase);
+      --  Write the start message associated with elaboration phase Phase to
+      --  standard output.
+
+   end Phase_Writers;
+
    --------------------------
    -- Unit_Closure_Writers --
    --------------------------
index 678f0098b981186118137dfe8bb6c798d53b6485..d5830cab098d263cb9ffc69c46ee5dbeba01a800 100644 (file)
@@ -355,6 +355,11 @@ package body Bindo is
    --
    --        GNATbind output the cycle paths in text format to standard output
    --
+   --  -d_S  Output elaboration-order status information
+   --
+   --        GNATbind outputs trace information concerning the status of its
+   --        various phases to standard output.
+   --
    --  -d_T  Output elaboration-order trace information
    --
    --        GNATbind outputs trace information on elaboration-order detection
@@ -416,6 +421,11 @@ package body Bindo is
    --    plgv   --  print library-graph vertex
    --    pu     --  print units
    --
+   --  * Apparent infinite loop
+   --
+   --    The elaboration order mechanism appears to be stuck in an infinite
+   --    loop. Use switch -d_S to output the status of each elaboration phase.
+   --
    --  * Invalid elaboration order
    --
    --    The elaboration order is invalid when:
index b0ebe628bd7f4dd765967d1386481b3a8f87a9d5..ae35c956f14568626fde10674d0c1db75f529ff5 100644 (file)
@@ -31,6 +31,24 @@ with Namet; use Namet;
 
 package Bindo is
 
+   --  The following type represents the various phases of the elaboration
+   --  order mechanism.
+
+   type Elaboration_Phase is
+     (Component_Discovery,
+      Cycle_Diagnostics,
+      Cycle_Discovery,
+      Cycle_Validation,
+      Elaboration_Order_Validation,
+      Invocation_Graph_Construction,
+      Invocation_Graph_Validation,
+      Library_Graph_Augmentation,
+      Library_Graph_Construction,
+      Library_Graph_Elaboration,
+      Library_Graph_Validation,
+      Unit_Collection,
+      Unit_Elaboration);
+
    --  The following type represents the various kinds of precedence between
    --  two items.
 
index a81de09b19cb7539b3bbe5b94a0fd0caf5568a00..44f0b9ec4cb9107e6d69151d3d08f030342d28f8 100644 (file)
@@ -394,8 +394,8 @@ package body Debug is
    --  d_P  Output cycle paths
    --  d_Q
    --  d_R
-   --  d_S
-   --  d_T  Output elaboration order trace information
+   --  d_S  Output elaboration-order status
+   --  d_T  Output elaboration-order trace information
    --  d_U
    --  d_V  Validate bindo cycles, graphs, and order
    --  d_W
@@ -1167,6 +1167,9 @@ package body Debug is
 
    --  d_P  GNATBIND outputs the cycle paths to standard output
 
+   --  d_S  GNATBIND outputs trace information concerning the status of its
+   --       various phases to standard output.
+
    --  d_T  GNATBIND outputs trace information of elaboration order detection
    --       activities to standard output.