aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/par_sco.adb
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/par_sco.adb')
-rw-r--r--gcc/ada/par_sco.adb246
1 files changed, 183 insertions, 63 deletions
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index e0b5db3..897b359 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -28,12 +28,14 @@ with Debug; use Debug;
with Lib; use Lib;
with Lib.Util; use Lib.Util;
with Nlists; use Nlists;
+with Opt; use Opt;
with Output; use Output;
with Sinfo; use Sinfo;
with Sinput; use Sinput;
with Table;
-with GNAT.HTable; use GNAT.HTable;
+with GNAT.HTable; use GNAT.HTable;
+with GNAT.Heap_Sort_G;
package body Par_SCO is
@@ -120,20 +122,20 @@ package body Par_SCO is
-- Unit Table --
----------------
- -- This table keeps track of the units and the corresponding starting index
- -- in the SCO table. The ending index is either one less than the starting
- -- index of the next table entry, or, for the last table entry, it is
- -- SCO_Table.Last.
+ -- This table keeps track of the units and the corresponding starting and
+ -- ending indexes (From, To) in the SCO table. Note that entry zero is
+ -- unused, it is for convenience in calling the sort routine.
type SCO_Unit_Table_Entry is record
- Unit : Unit_Number_Type;
- Index : Int;
+ Unit : Unit_Number_Type;
+ From : Nat;
+ To : Nat;
end record;
package SCO_Unit_Table is new Table.Table (
Table_Component_Type => SCO_Unit_Table_Entry,
Table_Index_Type => Int,
- Table_Low_Bound => 1,
+ Table_Low_Bound => 0,
Table_Initial => 20,
Table_Increment => 200,
Table_Name => "SCO_Unit_Table_Entry");
@@ -181,6 +183,9 @@ package body Par_SCO is
-- the node is always a decision a decision is always present (at the very
-- least a simple decision is present at the top level).
+ procedure Process_Decisions (L : List_Id; T : Character);
+ -- Calls above procedure for each element of the list L
+
procedure Set_Table_Entry
(C1 : Character;
C2 : Character;
@@ -189,11 +194,12 @@ package body Par_SCO is
Last : Boolean);
-- Append an entry to SCO_Table with fields set as per arguments
- procedure Traverse_Declarations_Or_Statements (L : List_Id);
- procedure Traverse_Handled_Statement_Sequence (N : Node_Id);
- procedure Traverse_Package_Body (N : Node_Id);
- procedure Traverse_Package_Declaration (N : Node_Id);
- procedure Traverse_Subprogram_Body (N : Node_Id);
+ procedure Traverse_Declarations_Or_Statements (L : List_Id);
+ procedure Traverse_Generic_Package_Declaration (N : Node_Id);
+ procedure Traverse_Handled_Statement_Sequence (N : Node_Id);
+ procedure Traverse_Package_Body (N : Node_Id);
+ procedure Traverse_Package_Declaration (N : Node_Id);
+ procedure Traverse_Subprogram_Body (N : Node_Id);
-- Traverse the corresponding construct, generating SCO table entries
procedure dsco;
@@ -213,8 +219,10 @@ package body Par_SCO is
Write_Int (Index);
Write_Str (". Unit = ");
Write_Int (Int (SCO_Unit_Table.Table (Index).Unit));
- Write_Str (" Index = ");
- Write_Int (Int (SCO_Unit_Table.Table (Index).Index));
+ Write_Str (" From = ");
+ Write_Int (Int (SCO_Unit_Table.Table (Index).From));
+ Write_Str (" To = ");
+ Write_Int (Int (SCO_Unit_Table.Table (Index).To));
Write_Eol;
end loop;
@@ -297,14 +305,16 @@ package body Par_SCO is
return Header_Num (Nat (F) mod 997);
end Hash;
- ----------
- -- Init --
- ----------
+ ----------------
+ -- Initialize --
+ ----------------
- procedure Init is
+ procedure Initialize is
begin
- null;
- end Init;
+ SCO_Unit_Table.Init;
+ SCO_Unit_Table.Increment_Last;
+ SCO_Table.Init;
+ end Initialize;
-------------------------
-- Is_Logical_Operator --
@@ -324,10 +334,24 @@ package body Par_SCO is
-- Process_Decisions --
-----------------------
- procedure Process_Decisions
- (N : Node_Id;
- T : Character)
- is
+ -- Version taking a list
+
+ procedure Process_Decisions (L : List_Id; T : Character) is
+ N : Node_Id;
+ begin
+ if L /= No_List then
+ N := First (L);
+ while Present (N) loop
+ Process_Decisions (N, T);
+ Next (N);
+ end loop;
+ end if;
+ end Process_Decisions;
+
+ -- Version taking a node
+
+ procedure Process_Decisions (N : Node_Id; T : Character) is
+
function Process_Node (N : Node_Id) return Traverse_Result;
-- Processes one node in the traversal, looking for logical operators,
-- and if one is found, outputs the appropriate table entries.
@@ -567,40 +591,75 @@ package body Par_SCO is
dsco;
end if;
+ -- Sort the unit table
+
+ Unit_Table_Sort : declare
+
+ function Lt (Op1, Op2 : Natural) return Boolean;
+ -- Comparison routine for sort call
+
+ procedure Move (From : Natural; To : Natural);
+ -- Move routine for sort call
+
+ --------
+ -- Lt --
+ --------
+
+ function Lt (Op1, Op2 : Natural) return Boolean is
+ begin
+ return Dependency_Num (SCO_Unit_Table.Table (Nat (Op1)).Unit) <
+ Dependency_Num (SCO_Unit_Table.Table (Nat (Op2)).Unit);
+ end Lt;
+
+ ----------
+ -- Move --
+ ----------
+
+ procedure Move (From : Natural; To : Natural) is
+ begin
+ SCO_Unit_Table.Table (Nat (To)) :=
+ SCO_Unit_Table.Table (Nat (From));
+ end Move;
+
+ package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
+
+ -- Start of processing for Unit_Table_Sort
+
+ begin
+ Sorting.Sort (Integer (SCO_Unit_Table.Last));
+ end Unit_Table_Sort;
+
-- Loop through entries in the unit table
- for J in SCO_Unit_Table.First .. SCO_Unit_Table.Last loop
+ for J in 1 .. SCO_Unit_Table.Last loop
U := SCO_Unit_Table.Table (J).Unit;
- if In_Extended_Main_Source_Unit (Cunit_Entity (U)) then
- Write_Info_Initiate ('C');
- Write_Info_Char (' ');
- Write_Info_Nat (Dependency_Num (U));
- Write_Info_Char (' ');
- Write_Info_Name (Reference_Name (Source_Index (U)));
- Write_Info_Terminate;
+ -- Output header line preceded by blank line
- Start := SCO_Unit_Table.Table (J).Index;
+ Write_Info_Terminate;
+ Write_Info_Initiate ('C');
+ Write_Info_Char (' ');
+ Write_Info_Nat (Dependency_Num (U));
+ Write_Info_Char (' ');
+ Write_Info_Name (Reference_Name (Source_Index (U)));
+ Write_Info_Terminate;
- if J = SCO_Unit_Table.Last then
- Stop := SCO_Table.Last;
- else
- Stop := SCO_Unit_Table.Table (J + 1).Index - 1;
- end if;
+ Start := SCO_Unit_Table.Table (J).From;
+ Stop := SCO_Unit_Table.Table (J).To;
- -- Loop through relevant entries in SCO table, outputting C lines
+ -- Loop through relevant entries in SCO table, outputting C lines
- while Start <= Stop loop
- declare
- T : SCO_Table_Entry renames SCO_Table.Table (Start);
+ while Start <= Stop loop
+ declare
+ T : SCO_Table_Entry renames SCO_Table.Table (Start);
- begin
- Write_Info_Initiate ('C');
- Write_Info_Char (T.C1);
+ begin
+ Write_Info_Initiate ('C');
+ Write_Info_Char (T.C1);
- case T.C1 is
+ case T.C1 is
- -- Statements, entry, exit
+ -- Statements, entry, exit
when 'S' | 'Y' | 'T' =>
Write_Info_Char (' ');
@@ -641,17 +700,16 @@ package body Par_SCO is
when others =>
raise Program_Error;
- end case;
+ end case;
- Write_Info_Terminate;
- end;
+ Write_Info_Terminate;
+ end;
- exit when Start = Stop;
- Start := Start + 1;
+ exit when Start = Stop;
+ Start := Start + 1;
- pragma Assert (Start <= Stop);
- end loop;
- end if;
+ pragma Assert (Start <= Stop);
+ end loop;
end loop;
end SCO_Output;
@@ -660,11 +718,35 @@ package body Par_SCO is
----------------
procedure SCO_Record (U : Unit_Number_Type) is
- Cu : constant Node_Id := Cunit (U);
- Lu : constant Node_Id := Unit (Cu);
+ Lu : Node_Id;
+ From : Nat;
begin
- SCO_Unit_Table.Append ((Unit => U, Index => SCO_Table.Last + 1));
+ -- Ignore call if not generating code and generating SCO's
+
+ if not (Generate_SCO and then Operating_Mode = Generate_Code) then
+ return;
+ end if;
+
+ -- Ignore call if this unit already recorded
+
+ for J in 1 .. SCO_Unit_Table.Last loop
+ if SCO_Unit_Table.Table (J).Unit = U then
+ return;
+ end if;
+ end loop;
+
+ -- Otherwise record starting entry
+
+ From := SCO_Table.Last + 1;
+
+ -- Get Unit (checking case of subunit)
+
+ Lu := Unit (Cunit (U));
+
+ if Nkind (Lu) = N_Subunit then
+ Lu := Proper_Body (Lu);
+ end if;
-- Traverse the unit
@@ -677,13 +759,20 @@ package body Par_SCO is
elsif Nkind (Lu) = N_Package_Body then
Traverse_Package_Body (Lu);
- -- Ignore subprogram specifications, since nothing to cover.
- -- Also ignore instantiations, since again, nothing to cover.
- -- Also for now, ignore generic declarations ???
+ elsif Nkind (Lu) = N_Generic_Package_Declaration then
+ Traverse_Generic_Package_Declaration (Lu);
+
+ -- For anything else, the only issue is default expressions for
+ -- parameters, where we have to worry about possible embedded decisions
+ -- but nothing else.
else
- null;
+ Process_Decisions (Lu, 'X');
end if;
+
+ -- Make entry for new unit in unit table
+
+ SCO_Unit_Table.Append ((Unit => U, From => From, To => SCO_Table.Last));
end SCO_Record;
-----------------------
@@ -774,12 +863,33 @@ package body Par_SCO is
Set_Statement_Entry;
Traverse_Package_Declaration (N);
+ -- Generic package declaration
+
+ when N_Generic_Package_Declaration =>
+ Set_Statement_Entry;
+ Traverse_Generic_Package_Declaration (N);
+
-- Package body
when N_Package_Body =>
Set_Statement_Entry;
Traverse_Package_Body (N);
+ -- Subprogram declaration
+
+ when N_Subprogram_Declaration =>
+ Set_Statement_Entry;
+ Process_Decisions
+ (Parameter_Specifications (Specification (N)), 'X');
+
+ -- Generic subprogram declaration
+
+ when N_Generic_Subprogram_Declaration =>
+ Set_Statement_Entry;
+ Process_Decisions (Generic_Formal_Declarations (N), 'X');
+ Process_Decisions
+ (Parameter_Specifications (Specification (N)), 'X');
+
-- Subprogram_Body
when N_Subprogram_Body =>
@@ -906,6 +1016,16 @@ package body Par_SCO is
end if;
end Traverse_Declarations_Or_Statements;
+ ------------------------------------------
+ -- Traverse_Generic_Package_Declaration --
+ ------------------------------------------
+
+ procedure Traverse_Generic_Package_Declaration (N : Node_Id) is
+ begin
+ Process_Decisions (Generic_Formal_Declarations (N), 'X');
+ Traverse_Package_Declaration (N);
+ end Traverse_Generic_Package_Declaration;
+
-----------------------------------------
-- Traverse_Handled_Statement_Sequence --
-----------------------------------------