diff mbox

[Ada] Add statistics dumping function to Atree package

Message ID 20160418094849.GA70667@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 18, 2016, 9:48 a.m. UTC
This adds a statistics dumping function to the Atree package, which is the
package responsible for the allocation of the nodes of the front-end tree.

No user-visible functional changes.

Tested on x86_64-pc-linux-gnu, committed on trunk

2016-04-18  Eric Botcazou  <ebotcazou@adacore.com>

	* atree.ads (Num_Extension_Nodes): Add couple of figures
	to comment.
	* atree.adb: Add GNAT.Heap_Sort_G dependency.
	(Print_Statistics): New exported procedure to print statistics.
diff mbox

Patch

Index: atree.adb
===================================================================
--- atree.adb	(revision 235100)
+++ atree.adb	(working copy)
@@ -44,6 +44,8 @@ 
 with Sinput;  use Sinput;
 with Tree_IO; use Tree_IO;
 
+with GNAT.Heap_Sort_G;
+
 package body Atree is
 
    Reporting_Proc : Report_Proc := null;
@@ -115,6 +117,10 @@ 
    procedure Node_Debug_Output (Op : String; N : Node_Id);
    --  Common code for nnd and rrd, writes Op followed by information about N
 
+   procedure Print_Statistics;
+   pragma Export (Ada, Print_Statistics);
+   --  Print various statistics on the tables maintained by the package
+
    -----------------------------
    -- Local Objects and Types --
    -----------------------------
@@ -1955,6 +1961,102 @@ 
         Nodes.Table (OldN).Comes_From_Source;
    end Preserve_Comes_From_Source;
 
+   ----------------------
+   -- Print_Statistics --
+   ----------------------
+
+   procedure Print_Statistics is
+      N_Count : constant Natural := Natural (Nodes.Last - First_Node_Id + 1);
+      E_Count : Natural := 0;
+
+   begin
+      Write_Str ("Maximum number of nodes per entity: ");
+      Write_Int (Int (Num_Extension_Nodes + 1));
+      Write_Eol;
+      Write_Str ("Number of allocated nodes: ");
+      Write_Int (Int (N_Count));
+      Write_Eol;
+
+      Write_Str ("Number of entities: ");
+      Write_Eol;
+
+      declare
+         function CP_Lt (Op1, Op2 : Natural) return Boolean;
+         --  Compare routine for Sort
+
+         procedure CP_Move (From : Natural; To : Natural);
+         --  Move routine for Sort
+
+         Kind_Count : array (Node_Kind) of Natural := (others => 0);
+         --  Array of occurrence count per node kind
+
+         Kind_Max : constant Natural := Node_Kind'Pos (N_Unused_At_End) - 1;
+         --  The index of the largest (interesting) node kind
+
+         Ranking : array (0 .. Kind_Max) of Node_Kind;
+         --  Ranking array for node kinds (index 0 is used for the temporary)
+
+         package Sorting is new GNAT.Heap_Sort_G (CP_Move, CP_Lt);
+
+         function CP_Lt (Op1, Op2 : Natural) return Boolean is
+         begin
+            return Kind_Count (Ranking (Op2)) < Kind_Count (Ranking (Op1));
+         end CP_Lt;
+
+         procedure CP_Move (From : Natural; To : Natural) is
+         begin
+            Ranking (To) := Ranking (From);
+         end CP_Move;
+
+      begin
+         --  Count the number of occurrences of each node kind
+
+         for I in First_Node_Id .. Nodes.Last loop
+            declare
+               Nkind : constant Node_Kind := Nodes.Table (I).Nkind;
+            begin
+               if not Nodes.Table (I).Is_Extension then
+                  Kind_Count (Nkind) := Kind_Count (Nkind) + 1;
+               end if;
+            end;
+         end loop;
+
+         --  Sort the node kinds by number of occurrences
+
+         for N in 1 .. Kind_Max loop
+            Ranking (N) := Node_Kind'Val (N);
+         end loop;
+
+         Sorting.Sort (Kind_Max);
+
+         --  Print the list in descending order
+
+         for N in 1 .. Kind_Max loop
+            declare
+               Count : constant Natural := Kind_Count (Ranking (N));
+            begin
+               if Count > 0 then
+                  Write_Str ("  ");
+                  Write_Str (Node_Kind'Image (Ranking (N)));
+                  Write_Str (": ");
+                  Write_Int (Int (Count));
+                  Write_Eol;
+
+                  E_Count := E_Count + Count;
+               end if;
+            end;
+         end loop;
+      end;
+
+      Write_Str ("Total number of entities: ");
+      Write_Int (Int (E_Count));
+      Write_Eol;
+      Write_Str ("Ratio allocated nodes/entities: ");
+      Write_Int (Int (N_Count * 100 / E_Count));
+      Write_Str ("/100");
+      Write_Eol;
+   end Print_Statistics;
+
    -------------------
    -- Relocate_Node --
    -------------------
Index: atree.ads
===================================================================
--- atree.ads	(revision 235100)
+++ atree.ads	(working copy)
@@ -76,6 +76,10 @@ 
    --  This value is increased by one if debug flag -gnatd.N is set. This is
    --  for testing performance impact of adding a new extension node. We make
    --  this of type Node_Id for easy reference in loops using this value.
+   --  Print_Statistics can be used to display statistics on entities & nodes.
+   --  Measurements conducted for the 5->6 bump showed an increase from 1.81 to
+   --  2.01 for the nodes/entities ratio and a 2% increase in compilation time
+   --  on average for the GCC-based compiler at -O0 on a 32-bit x86 host.
 
    ----------------------------------------
    -- Definitions of Fields in Tree Node --