diff options
author | Bob Duff <duff@adacore.com> | 2021-07-29 11:15:46 -0400 |
---|---|---|
committer | Pierre-Marie de Rodat <derodat@adacore.com> | 2021-09-23 13:06:14 +0000 |
commit | 99e30ba8c01f80a81891223069d47d8a611082c4 (patch) | |
tree | 2bfbbf0e257e54ccf041809b15680cfb8b58c83a /gcc/ada/atree.adb | |
parent | 7165704bfaae012cb28e5411619218da6fb8320d (diff) | |
download | gcc-99e30ba8c01f80a81891223069d47d8a611082c4.tar.gz |
[Ada] Cleanup and efficiency improvements
gcc/ada/
* gen_il-gen.adb: Generate getters and setters with much of the
code inlined. Generate code for storing a few fields in the node
header, to avoid the extra level of indirection for those
fields. We generate the header type, so we don't have to
duplicate hand-written Ada and C code to depend on the number of
header fields. Declare constants for slot size. Use short names
because these are used all over. Remove
Put_Low_Level_Accessor_Instantiations, Put_Low_Level_C_Getter,
which are no longer needed. Rename
Put_High_Level_C_Getter-->Put_C_Getter.
* atree.ads, atree.adb: Take into account the header slots.
Take into account the single Node_Or_Entity_Field type. Remove
"pragma Assertion_Policy (Ignore);", because the routines in
this package are no longer efficiency critical.
* atree.h: Remove low-level getters, which are no longer used by
sinfo.h and einfo.h.
* einfo-utils.adb: Avoid crash in Known_Alignment.
* live.adb, sem_eval.adb: Remove code that prevents Node_Id from
having a predicate. We don't actually add a predicate to
Node_Id, but we want to be able to for temporary debugging.
* sinfo-utils.adb: Remove code that prevents Node_Id from having
a predicate. Take into account the single Node_Or_Entity_Field
type.
* sinfo-utils.ads: Minor.
* table.ads (Table_Type): Make the components aliased, because
low-level setters in Atree need to take 'Access.
* treepr.adb: Take into account the single Node_Or_Entity_Field
type. Make some code more robust, so we can print out
half-baked nodes.
* types.ads: Move types here for visibility purposes.
* gcc-interface/gigi.h, gcc-interface/trans.c: Take into account
the Node_Header change in the GNAT front end.
* gcc-interface/cuintp.c, gcc-interface/targtyps.c: Add because
gigi.h now refers to type Node_Header, which is in sinfo.h.
Diffstat (limited to 'gcc/ada/atree.adb')
-rw-r--r-- | gcc/ada/atree.adb | 489 |
1 files changed, 284 insertions, 205 deletions
diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb index d69d4037ebc..00565d66d85 100644 --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -23,20 +23,12 @@ -- -- ------------------------------------------------------------------------------ --- Assertions in this package are too slow, and are mostly needed when working --- on this package itself, or on gen_il, so we disable them. --- To debug low-level bugs in this area, comment out the following pragma, --- and run with -gnatd_v. - -pragma Assertion_Policy (Ignore); - with Aspects; use Aspects; with Debug; use Debug; with Namet; use Namet; with Nlists; use Nlists; with Opt; use Opt; with Output; use Output; -with Seinfo; use Seinfo; with Sinfo.Utils; use Sinfo.Utils; with System.Storage_Elements; @@ -153,7 +145,11 @@ package body Atree is function Size_In_Slots (N : Node_Or_Entity_Id) return Slot_Count; -- Number of slots belonging to N. This can be less than - -- Size_In_Slots_To_Alloc for entities. + -- Size_In_Slots_To_Alloc for entities. Includes both header + -- and dynamic slots. + + function Size_In_Slots_Dynamic (N : Node_Or_Entity_Id) return Slot_Count; + -- Just counts the number of dynamic slots function Size_In_Slots_To_Alloc (N : Node_Or_Entity_Id) return Slot_Count; function Size_In_Slots_To_Alloc (Kind : Node_Kind) return Slot_Count; @@ -161,35 +157,47 @@ package body Atree is -- to allocate the max, because we don't know the Ekind when this is -- called. - function Off_0 (N : Node_Id) return Node_Offset; - -- Offset of the first slot of N (offset 0) in Slots.Table + function Off_F (N : Node_Id) return Node_Offset with Inline; + -- Offset of the first dynamic slot of N in Slots.Table. + -- The actual offset of this slot from the start of the node + -- is not 0; this is logically the first slot after the header + -- slots. + + function Off_0 (N : Node_Id) return Node_Offset'Base with Inline; + -- This is for zero-origin addressing of the dynamic slots. + -- It points to slot 0 of N in Slots.Table, which does not exist, + -- because the first few slots are stored in the header. - function Off_L (N : Node_Id) return Node_Offset; + function Off_L (N : Node_Id) return Node_Offset with Inline; -- Offset of the last slot of N in Slots.Table - procedure Zero_Slots (First, Last : Node_Offset) with Inline; - -- Set slots in the range F..L to zero + procedure Zero_Dynamic_Slots (First, Last : Node_Offset'Base) with Inline; + -- Set dynamic slots in the range First..Last to zero + + procedure Zero_Header_Slots (N : Node_Or_Entity_Id) with Inline; + -- Zero the header slots belonging to N procedure Zero_Slots (N : Node_Or_Entity_Id) with Inline; - -- Zero the slots belonging to N + -- Zero the slots belonging to N (both header and dynamic) - procedure Copy_Slots (From, To : Node_Offset; Num_Slots : Slot_Count) + procedure Copy_Dynamic_Slots + (From, To : Node_Offset; Num_Slots : Slot_Count) with Inline; -- Copy Num_Slots slots from From to To. Caller is responsible for ensuring -- that the Num_Slots at To are a reasonable place to copy to. procedure Copy_Slots (Source, Destination : Node_Id) with Inline; - -- Copies the slots of Source to Destination; uses the node kind to - -- determine the Num_Slots. + -- Copies the slots (both header and dynamic) of Source to Destination; + -- uses the node kind to determine the Num_Slots. function Get_Field_Value - (N : Node_Id; Field : Node_Field) return Field_Size_32_Bit; + (N : Node_Id; Field : Node_Or_Entity_Field) return Field_Size_32_Bit; -- Get any field value as a Field_Size_32_Bit. If the field is smaller than -- 32 bits, convert it to Field_Size_32_Bit. The Field must be present in -- the Nkind of N. procedure Set_Field_Value - (N : Node_Id; Field : Node_Field; Val : Field_Size_32_Bit); + (N : Node_Id; Field : Node_Or_Entity_Field; Val : Field_Size_32_Bit); -- Set any field value as a Field_Size_32_Bit. If the field is smaller than -- 32 bits, convert it from Field_Size_32_Bit, and Val had better be small -- enough. The Field must be present in the Nkind of N. @@ -199,10 +207,6 @@ package body Atree is -- Called whenever Nkind is modified. Raises an exception if not all -- vanishing fields are in their initial zero state. - function Get_Field_Value - (N : Entity_Id; Field : Entity_Field) return Field_Size_32_Bit; - procedure Set_Field_Value - (N : Entity_Id; Field : Entity_Field; Val : Field_Size_32_Bit); procedure Check_Vanishing_Fields (Old_N : Entity_Id; New_Kind : Entity_Kind); -- Above are the same as the ones for nodes, but for entities @@ -405,7 +409,8 @@ package body Atree is pragma Assert (N'Valid); pragma Assert (N <= Node_Offsets.Last); - pragma Assert (Off_0 (N) <= Off_L (N)); + pragma Assert (Off_L (N) >= Off_0 (N)); + pragma Assert (Off_L (N) >= Off_F (N) - 1); pragma Assert (Off_L (N) <= Slots.Last); pragma Assert (Nkind (N)'Valid); pragma Assert (Nkind (N) /= N_Unused_At_End); @@ -469,8 +474,9 @@ package body Atree is function Cast is new Unchecked_Conversion (Field_Size_1_Bit, Field_Type); + Val : constant Field_Size_1_Bit := Get_1_Bit_Val (N, Offset); begin - return Cast (Get_1_Bit_Val (N, Offset)); + return Cast (Val); end Get_1_Bit_Field; function Get_2_Bit_Field @@ -480,8 +486,9 @@ package body Atree is function Cast is new Unchecked_Conversion (Field_Size_2_Bit, Field_Type); + Val : constant Field_Size_2_Bit := Get_2_Bit_Val (N, Offset); begin - return Cast (Get_2_Bit_Val (N, Offset)); + return Cast (Val); end Get_2_Bit_Field; function Get_4_Bit_Field @@ -491,8 +498,9 @@ package body Atree is function Cast is new Unchecked_Conversion (Field_Size_4_Bit, Field_Type); + Val : constant Field_Size_4_Bit := Get_4_Bit_Val (N, Offset); begin - return Cast (Get_4_Bit_Val (N, Offset)); + return Cast (Val); end Get_4_Bit_Field; function Get_8_Bit_Field @@ -502,8 +510,9 @@ package body Atree is function Cast is new Unchecked_Conversion (Field_Size_8_Bit, Field_Type); + Val : constant Field_Size_8_Bit := Get_8_Bit_Val (N, Offset); begin - return Cast (Get_8_Bit_Val (N, Offset)); + return Cast (Val); end Get_8_Bit_Field; function Get_32_Bit_Field @@ -514,7 +523,8 @@ package body Atree is function Cast is new Unchecked_Conversion (Field_Size_32_Bit, Field_Type); - Result : constant Field_Type := Cast (Get_32_Bit_Val (N, Offset)); + Val : constant Field_Size_32_Bit := Get_32_Bit_Val (N, Offset); + Result : constant Field_Type := Cast (Val); -- Note: declaring Result here instead of directly returning -- Cast (...) helps CodePeer understand that there are no issues -- around uninitialized variables. @@ -612,133 +622,214 @@ package body Atree is Set_32_Bit_Val (N, Offset, Cast (Val)); end Set_32_Bit_Field; + pragma Style_Checks ("M90"); + + ----------------------------------- + -- Low-level getters and setters -- + ----------------------------------- + + -- In the getters and setters below, we use shifting and masking to + -- simulate packed arrays. F_Size is the field size in bits. Mask is + -- that number of 1 bits in the low-order bits. F_Per_Slot is the number + -- of fields per slot. Slot_Off is the offset of the slot of interest. + -- S is the slot at that offset. V is the amount to shift by. + + function In_NH (Slot_Off : Field_Offset) return Boolean is + (Slot_Off < Seinfo.N_Head); + -- In_NH stands for "in Node_Header", not "in New Hampshire" + + function Get_Slot + (N : Node_Or_Entity_Id; Slot_Off : Field_Offset) + return Slot is + (if In_NH (Slot_Off) then + Node_Offsets.Table (N).Slots (Slot_Off) + else Slots.Table (Node_Offsets.Table (N).Offset + Slot_Off)); + -- Get the slot, either directly from the node header, or indirectly + -- from the Slots table. + function Get_1_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_Size_1_Bit is - -- We wish we were using packed arrays, but instead we're simulating - -- them with modular integers. L here (and elsewhere) is the 'Length - -- of that simulated array. - L : constant Field_Offset := Slot_Size / 1; - - pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 1; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + S : constant Slot := Get_Slot (N, Slot_Off); + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset (N, Slot_Off)); + Raw : constant Field_Size_1_Bit := + Field_Size_1_Bit (Shift_Right (S, V) and Mask); begin - return Field_Size_1_Bit (Shift_Right (S, V) and 1); + return Raw; end Get_1_Bit_Val; function Get_2_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_Size_2_Bit is - L : constant Field_Offset := Slot_Size / 2; - - pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 2; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + S : constant Slot := Get_Slot (N, Slot_Off); + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset (N, Slot_Off)); + Raw : constant Field_Size_2_Bit := + Field_Size_2_Bit (Shift_Right (S, V) and Mask); begin - return Field_Size_2_Bit (Shift_Right (S, V) and 3); + return Raw; end Get_2_Bit_Val; function Get_4_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_Size_4_Bit is - L : constant Field_Offset := Slot_Size / 4; - - pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 4; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + S : constant Slot := Get_Slot (N, Slot_Off); + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset (N, Slot_Off)); + Raw : constant Field_Size_4_Bit := + Field_Size_4_Bit (Shift_Right (S, V) and Mask); begin - return Field_Size_4_Bit (Shift_Right (S, V) and 15); + return Raw; end Get_4_Bit_Val; function Get_8_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_Size_8_Bit is - L : constant Field_Offset := Slot_Size / 8; - - pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 8; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + S : constant Slot := Get_Slot (N, Slot_Off); + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset (N, Slot_Off)); + Raw : constant Field_Size_8_Bit := + Field_Size_8_Bit (Shift_Right (S, V) and Mask); begin - return Field_Size_8_Bit (Shift_Right (S, V) and 255); + return Raw; end Get_8_Bit_Val; function Get_32_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_Size_32_Bit is - pragma Debug (Validate_Node_And_Offset (N, Offset)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset); + F_Size : constant := 32; + -- No Mask needed + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + S : constant Slot := Get_Slot (N, Slot_Off); + pragma Debug (Validate_Node_And_Offset (N, Slot_Off)); + Raw : constant Field_Size_32_Bit := + Field_Size_32_Bit (S); begin - return Field_Size_32_Bit (S); + return Raw; end Get_32_Bit_Val; + type Slot_Ptr is access all Slot; + function Get_Slot_Ptr + (N : Node_Or_Entity_Id; Slot_Off : Field_Offset) + return Slot_Ptr is + (if In_NH (Slot_Off) then + Node_Offsets.Table (N).Slots (Slot_Off)'Access + else Slots.Table (Node_Offsets.Table (N).Offset + Slot_Off)'Access); + procedure Set_1_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_Size_1_Bit) is - L : constant Field_Offset := Slot_Size / 1; - - pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 1; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + Ptr : constant Slot_Ptr := Get_Slot_Ptr (N, Slot_Off); + S : Slot renames Ptr.all; + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off)); begin - S := (S and not Shift_Left (1, V)) or Shift_Left (Slot (Val), V); + S := (S and not Shift_Left (Mask, V)) or Shift_Left (Slot (Val), V); end Set_1_Bit_Val; procedure Set_2_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_Size_2_Bit) is - L : constant Field_Offset := Slot_Size / 2; - - pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 2; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + Ptr : constant Slot_Ptr := Get_Slot_Ptr (N, Slot_Off); + S : Slot renames Ptr.all; + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off)); begin - S := (S and not Shift_Left (3, V)) or Shift_Left (Slot (Val), V); + S := (S and not Shift_Left (Mask, V)) or Shift_Left (Slot (Val), V); end Set_2_Bit_Val; procedure Set_4_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_Size_4_Bit) is - L : constant Field_Offset := Slot_Size / 4; - - pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 4; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + Ptr : constant Slot_Ptr := Get_Slot_Ptr (N, Slot_Off); + S : Slot renames Ptr.all; + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off)); begin - S := (S and not Shift_Left (15, V)) or Shift_Left (Slot (Val), V); + S := (S and not Shift_Left (Mask, V)) or Shift_Left (Slot (Val), V); end Set_4_Bit_Val; procedure Set_8_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_Size_8_Bit) is - L : constant Field_Offset := Slot_Size / 8; - - pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); - V : constant Natural := Natural ((Offset mod L) * (Slot_Size / L)); + F_Size : constant := 8; + Mask : constant := 2**F_Size - 1; + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + Ptr : constant Slot_Ptr := Get_Slot_Ptr (N, Slot_Off); + S : Slot renames Ptr.all; + V : constant Natural := Natural ((Offset mod F_Per_Slot) * F_Size); + pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off)); begin - S := (S and not Shift_Left (255, V)) or Shift_Left (Slot (Val), V); + S := (S and not Shift_Left (Mask, V)) or Shift_Left (Slot (Val), V); end Set_8_Bit_Val; procedure Set_32_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_Size_32_Bit) is - pragma Debug (Validate_Node_And_Offset_Write (N, Offset)); - - S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset); + F_Size : constant := 32; + -- No Mask needed + F_Per_Slot : constant Field_Offset := Slot_Size / F_Size; + Slot_Off : constant Field_Offset := Offset / F_Per_Slot; + Ptr : constant Slot_Ptr := Get_Slot_Ptr (N, Slot_Off); + S : Slot renames Ptr.all; + pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off)); begin S := Slot (Val); end Set_32_Bit_Val; + ---------------------- + -- Print_Atree_Info -- + ---------------------- + + procedure Print_Atree_Info (N : Node_Or_Entity_Id) is + function Cast is new Unchecked_Conversion (Slot, Int); + begin + Write_Int (Int (Size_In_Slots (N))); + Write_Str (" slots ("); + Write_Int (Int (Off_0 (N))); + Write_Str (" .. "); + Write_Int (Int (Off_L (N))); + Write_Str ("):"); + + for Off in Off_0 (N) .. Off_L (N) loop + Write_Str (" "); + Write_Int (Cast (Get_Slot (N, Off))); + end loop; + + Write_Eol; + end Print_Atree_Info; + end Atree_Private_Part; --------------- @@ -751,13 +842,12 @@ package body Atree is -- etc. function Get_Field_Value - (N : Node_Id; Field : Node_Field) return Field_Size_32_Bit + (N : Node_Id; Field : Node_Or_Entity_Field) return Field_Size_32_Bit is - pragma Assert (Field_Checking.Field_Present (Nkind (N), Field)); - Desc : Field_Descriptor renames Node_Field_Descriptors (Field); + Desc : Seinfo.Field_Descriptor renames Field_Descriptors (Field); begin - case Field_Size (Desc.Kind) is + case Seinfo.Field_Size (Desc.Kind) is when 1 => return Field_Size_32_Bit (Get_1_Bit_Val (N, Desc.Offset)); when 2 => return Field_Size_32_Bit (Get_2_Bit_Val (N, Desc.Offset)); when 4 => return Field_Size_32_Bit (Get_4_Bit_Val (N, Desc.Offset)); @@ -767,13 +857,12 @@ package body Atree is end Get_Field_Value; procedure Set_Field_Value - (N : Node_Id; Field : Node_Field; Val : Field_Size_32_Bit) + (N : Node_Id; Field : Node_Or_Entity_Field; Val : Field_Size_32_Bit) is - pragma Assert (Field_Checking.Field_Present (Nkind (N), Field)); - Desc : Field_Descriptor renames Node_Field_Descriptors (Field); + Desc : Seinfo.Field_Descriptor renames Field_Descriptors (Field); begin - case Field_Size (Desc.Kind) is + case Seinfo.Field_Size (Desc.Kind) is when 1 => Set_1_Bit_Val (N, Desc.Offset, Field_Size_1_Bit (Val)); when 2 => Set_2_Bit_Val (N, Desc.Offset, Field_Size_2_Bit (Val)); when 4 => Set_4_Bit_Val (N, Desc.Offset, Field_Size_4_Bit (Val)); @@ -782,13 +871,15 @@ package body Atree is end case; end Set_Field_Value; - procedure Reinit_Field_To_Zero (N : Node_Id; Field : Node_Field) is + procedure Reinit_Field_To_Zero + (N : Node_Id; Field : Node_Or_Entity_Field) + is begin Set_Field_Value (N, Field, 0); end Reinit_Field_To_Zero; function Field_Is_Initial_Zero - (N : Node_Id; Field : Node_Field) return Boolean is + (N : Node_Id; Field : Node_Or_Entity_Field) return Boolean is begin return Get_Field_Value (N, Field) = 0; end Field_Is_Initial_Zero; @@ -839,47 +930,6 @@ package body Atree is end loop; end Check_Vanishing_Fields; - function Get_Field_Value - (N : Entity_Id; Field : Entity_Field) return Field_Size_32_Bit - is - pragma Assert (Field_Checking.Field_Present (Ekind (N), Field)); - Desc : Field_Descriptor renames Entity_Field_Descriptors (Field); - begin - case Field_Size (Desc.Kind) is - when 1 => return Field_Size_32_Bit (Get_1_Bit_Val (N, Desc.Offset)); - when 2 => return Field_Size_32_Bit (Get_2_Bit_Val (N, Desc.Offset)); - when 4 => return Field_Size_32_Bit (Get_4_Bit_Val (N, Desc.Offset)); - when 8 => return Field_Size_32_Bit (Get_8_Bit_Val (N, Desc.Offset)); - when others => return Get_32_Bit_Val (N, Desc.Offset); -- 32 - end case; - end Get_Field_Value; - - procedure Set_Field_Value - (N : Entity_Id; Field : Entity_Field; Val : Field_Size_32_Bit) - is - pragma Assert (Field_Checking.Field_Present (Ekind (N), Field)); - Desc : Field_Descriptor renames Entity_Field_Descriptors (Field); - begin - case Field_Size (Desc.Kind) is - when 1 => Set_1_Bit_Val (N, Desc.Offset, Field_Size_1_Bit (Val)); - when 2 => Set_2_Bit_Val (N, Desc.Offset, Field_Size_2_Bit (Val)); - when 4 => Set_4_Bit_Val (N, Desc.Offset, Field_Size_4_Bit (Val)); - when 8 => Set_8_Bit_Val (N, Desc.Offset, Field_Size_8_Bit (Val)); - when others => Set_32_Bit_Val (N, Desc.Offset, Val); -- 32 - end case; - end Set_Field_Value; - - procedure Reinit_Field_To_Zero (N : Node_Id; Field : Entity_Field) is - begin - Set_Field_Value (N, Field, 0); - end Reinit_Field_To_Zero; - - function Field_Is_Initial_Zero - (N : Entity_Id; Field : Entity_Field) return Boolean is - begin - return Get_Field_Value (N, Field) = 0; - end Field_Is_Initial_Zero; - procedure Check_Vanishing_Fields (Old_N : Entity_Id; New_Kind : Entity_Kind) is @@ -918,7 +968,7 @@ package body Atree is end Check_Vanishing_Fields; Nkind_Offset : constant Field_Offset := - Node_Field_Descriptors (F_Nkind).Offset; + Field_Descriptors (F_Nkind).Offset; procedure Set_Node_Kind_Type is new Set_8_Bit_Field (Node_Kind) with Inline; @@ -943,35 +993,43 @@ package body Atree is if Old_Size < New_Size then declare Old_Last_Slot : constant Node_Offset := Slots.Last; - Old_Off_0 : constant Node_Offset := Off_0 (N); + Old_Off_F : constant Node_Offset := Off_F (N); begin - if Old_Last_Slot = Old_Off_0 + Old_Size - 1 then + if Old_Last_Slot = Old_Off_F + Old_Size - 1 then -- In this case, the slots are at the end of Slots.Table, so we -- don't need to move them. Slots.Set_Last (Old_Last_Slot + New_Size - Old_Size); else -- Move the slots - All_Node_Offsets (N) := Alloc_Slots (New_Size); - Copy_Slots (Old_Off_0, Off_0 (N), Old_Size); - pragma Debug (Zero_Slots (Old_Off_0, Old_Off_0 + Old_Size - 1)); + + declare + New_Off_F : constant Node_Offset := Alloc_Slots (New_Size); + begin + All_Node_Offsets (N).Offset := New_Off_F - Seinfo.N_Head; + Copy_Dynamic_Slots (Old_Off_F, New_Off_F, Old_Size); + pragma Debug + (Zero_Dynamic_Slots (Old_Off_F, Old_Off_F + Old_Size - 1)); + end; end if; end; - Zero_Slots (Off_0 (N) + Old_Size, Slots.Last); + Zero_Dynamic_Slots (Off_F (N) + Old_Size, Slots.Last); end if; Set_Node_Kind_Type (N, Nkind_Offset, Val); pragma Debug (Validate_Node_Write (N)); + + New_Node_Debugging_Output (N); end Mutate_Nkind; procedure Mutate_Nkind (N : Node_Id; Val : Node_Kind) is begin - Mutate_Nkind (N, Val, Old_Size => Size_In_Slots (N)); + Mutate_Nkind (N, Val, Old_Size => Size_In_Slots_Dynamic (N)); end Mutate_Nkind; Ekind_Offset : constant Field_Offset := - Entity_Field_Descriptors (F_Ekind).Offset; + Field_Descriptors (F_Ekind).Offset; procedure Set_Entity_Kind_Type is new Set_8_Bit_Field (Entity_Kind) with Inline; @@ -993,6 +1051,8 @@ package body Atree is Set_Entity_Kind_Type (N, Ekind_Offset, Val); pragma Debug (Validate_Node_Write (N)); + + New_Node_Debugging_Output (N); end Mutate_Ekind; ----------------------- @@ -1006,8 +1066,9 @@ package body Atree is Sz : constant Slot_Count := Size_In_Slots_To_Alloc (Kind); Sl : constant Node_Offset := Alloc_Slots (Sz); begin - Node_Offsets.Table (Result) := Sl; - Zero_Slots (Sl, Sl + Sz - 1); + Node_Offsets.Table (Result).Offset := Sl - Seinfo.N_Head; + Zero_Dynamic_Slots (Sl, Sl + Sz - 1); + Zero_Header_Slots (Result); end; Init_Nkind (Result, Kind); @@ -1045,7 +1106,7 @@ package body Atree is pragma Assert (Nkind (N) not in N_Entity); pragma Assert (New_Kind not in N_Entity); - Old_Size : constant Slot_Count := Size_In_Slots (N); + Old_Size : constant Slot_Count := Size_In_Slots_Dynamic (N); New_Size : constant Slot_Count := Size_In_Slots_To_Alloc (New_Kind); Save_Sloc : constant Source_Ptr := Sloc (N); @@ -1068,15 +1129,16 @@ package body Atree is New_Offset : constant Field_Offset := Alloc_Slots (New_Size); begin pragma Debug (Zero_Slots (N)); - Node_Offsets.Table (N) := New_Offset; - Zero_Slots (New_Offset, New_Offset + New_Size - 1); + Node_Offsets.Table (N).Offset := New_Offset - Seinfo.N_Head; + Zero_Dynamic_Slots (New_Offset, New_Offset + New_Size - 1); + Zero_Header_Slots (N); end; else Zero_Slots (N); end if; - Mutate_Nkind (N, New_Kind, Old_Size); + Init_Nkind (N, New_Kind); -- Not Mutate, because of Zero_Slots above Set_Sloc (N, Save_Sloc); Set_In_List (N, Save_In_List); @@ -1095,8 +1157,10 @@ package body Atree is -- Copy_Slots -- ---------------- - procedure Copy_Slots (From, To : Node_Offset; Num_Slots : Slot_Count) is - pragma Assert (From /= To); + procedure Copy_Dynamic_Slots + (From, To : Node_Offset; Num_Slots : Slot_Count) + is + pragma Assert (if Num_Slots /= 0 then From /= To); All_Slots : Slots.Table_Type renames Slots.Table (Slots.First .. Slots.Last); @@ -1109,21 +1173,21 @@ package body Atree is begin Destination_Slots := Source_Slots; - end Copy_Slots; + end Copy_Dynamic_Slots; procedure Copy_Slots (Source, Destination : Node_Id) is pragma Debug (Validate_Node (Source)); - pragma Debug (Validate_Node_Write (Destination)); pragma Assert (Source /= Destination); - S_Size : constant Slot_Count := Size_In_Slots (Source); + S_Size : constant Slot_Count := Size_In_Slots_Dynamic (Source); All_Node_Offsets : Node_Offsets.Table_Type renames Node_Offsets.Table (Node_Offsets.First .. Node_Offsets.Last); begin - Copy_Slots - (All_Node_Offsets (Source), All_Node_Offsets (Destination), S_Size); + Copy_Dynamic_Slots + (Off_F (Source), Off_F (Destination), S_Size); + All_Node_Offsets (Destination).Slots := All_Node_Offsets (Source).Slots; end Copy_Slots; --------------- @@ -1152,14 +1216,14 @@ package body Atree is if D_Size < S_Size then pragma Debug (Zero_Slots (Destination)); -- destroy old slots - Node_Offsets.Table (Destination) := Alloc_Slots (S_Size); + Node_Offsets.Table (Destination).Offset := + Alloc_Slots (S_Size) - Seinfo.N_Head; end if; Copy_Slots (Source, Destination); Set_In_List (Destination, Save_In_List); Set_Link (Destination, Save_Link); - Set_Paren_Count_Of_Copy (Target => Destination, Source => Source); end Copy_Node; @@ -1371,7 +1435,7 @@ package body Atree is (Is_Entity (E1) and then Is_Entity (E2) and then not In_List (E1) and then not In_List (E2)); - Old_E1 : constant Node_Offset := Node_Offsets.Table (E1); + Old_E1 : constant Seinfo.Node_Header := Node_Offsets.Table (E1); begin Node_Offsets.Table (E1) := Node_Offsets.Table (E2); @@ -1404,6 +1468,7 @@ package body Atree is pragma Assert (not Is_Entity (Source)); Old_Kind : constant Node_Kind := Nkind (Source); + pragma Assert (Old_Kind in N_Direct_Name); New_Kind : constant Node_Kind := (case Old_Kind is when N_Character_Literal => N_Defining_Character_Literal, @@ -1469,8 +1534,9 @@ package body Atree is begin for J in Fields'Range loop declare + use Seinfo; Desc : Field_Descriptor renames - Node_Field_Descriptors (Fields (J)); + Field_Descriptors (Fields (J)); begin if Desc.Kind in Node_Id_Field | List_Id_Field then Fix_Parent (Get_Node_Field_Union (Fix_Node, Desc.Offset)); @@ -1620,7 +1686,8 @@ package body Atree is end if; return New_Id : constant Node_Id := Alloc_Node_Id do - Node_Offsets.Table (New_Id) := Alloc_Slots (S_Size); + Node_Offsets.Table (New_Id).Offset := + Alloc_Slots (S_Size) - Seinfo.N_Head; Orig_Nodes.Append (New_Id); Copy_Slots (Source, New_Id); @@ -1676,7 +1743,7 @@ package body Atree is -- source nodes, then reset Current_Error_Node. This is useful -- if we bomb during parsing to get a error location for the bomb. - if New_Sloc > No_Location and then Comes_From_Source_Default then + if New_Sloc > No_Location and then Comes_From_Source_Default then Current_Error_Node := New_Id; end if; @@ -1765,16 +1832,25 @@ package body Atree is -- Off_0 -- ----------- - function Off_0 (N : Node_Id) return Node_Offset is + function Off_0 (N : Node_Id) return Node_Offset'Base is pragma Debug (Validate_Node (N)); All_Node_Offsets : Node_Offsets.Table_Type renames Node_Offsets.Table (Node_Offsets.First .. Node_Offsets.Last); begin - return All_Node_Offsets (N); + return All_Node_Offsets (N).Offset; end Off_0; ----------- + -- Off_F -- + ----------- + + function Off_F (N : Node_Id) return Node_Offset is + begin + return Off_0 (N) + Seinfo.N_Head; + end Off_F; + + ----------- -- Off_L -- ----------- @@ -1784,7 +1860,7 @@ package body Atree is All_Node_Offsets : Node_Offsets.Table_Type renames Node_Offsets.Table (Node_Offsets.First .. Node_Offsets.Last); begin - return All_Node_Offsets (N) + Size_In_Slots (N) - 1; + return All_Node_Offsets (N).Offset + Size_In_Slots (N) - 1; end Off_L; ------------------- @@ -1855,28 +1931,6 @@ package body Atree is Set_Comes_From_Source (NewN, Comes_From_Source (OldN)); end Preserve_Comes_From_Source; - ---------------------- - -- Print_Atree_Info -- - ---------------------- - - procedure Print_Atree_Info (N : Node_Or_Entity_Id) is - function Cast is new Unchecked_Conversion (Slot, Int); - begin - Write_Int (Int (Size_In_Slots (N))); - Write_Str (" slots ("); - Write_Int (Int (Off_0 (N))); - Write_Str (" .. "); - Write_Int (Int (Off_L (N))); - Write_Str ("):"); - - for Off in Off_0 (N) .. Off_L (N) loop - Write_Str (" "); - Write_Int (Cast (Slots.Table (Off))); - end loop; - - Write_Eol; - end Print_Atree_Info; - ------------------- -- Relocate_Node -- ------------------- @@ -1926,7 +1980,7 @@ package body Atree is procedure Destroy_New_Node is begin Zero_Slots (New_Node); - Node_Offsets.Table (New_Node) := Field_Offset'Base'Last; + Node_Offsets.Table (New_Node).Offset := Field_Offset'Base'Last; end Destroy_New_Node; begin @@ -2182,11 +2236,15 @@ package body Atree is Rewriting_Proc := Proc; end Set_Rewriting_Proc; + ---------------------------- + -- Size_In_Slots_To_Alloc -- + ---------------------------- + function Size_In_Slots_To_Alloc (Kind : Node_Kind) return Slot_Count is begin return (if Kind in N_Entity then Einfo.Entities.Max_Entity_Size - else Sinfo.Nodes.Size (Kind)); + else Sinfo.Nodes.Size (Kind)) - Seinfo.N_Head; -- Unfortunately, we don't know the Entity_Kind, so we have to use the -- max. end Size_In_Slots_To_Alloc; @@ -2197,6 +2255,10 @@ package body Atree is return Size_In_Slots_To_Alloc (Nkind (N)); end Size_In_Slots_To_Alloc; + ------------------- + -- Size_In_Slots -- + ------------------- + function Size_In_Slots (N : Node_Or_Entity_Id) return Slot_Count is begin pragma Assert (Nkind (N) /= N_Unused_At_Start); @@ -2205,6 +2267,15 @@ package body Atree is else Sinfo.Nodes.Size (Nkind (N))); end Size_In_Slots; + --------------------------- + -- Size_In_Slots_Dynamic -- + --------------------------- + + function Size_In_Slots_Dynamic (N : Node_Or_Entity_Id) return Slot_Count is + begin + return Size_In_Slots (N) - Seinfo.N_Head; + end Size_In_Slots_Dynamic; + ------------------- -- Traverse_Func -- ------------------- @@ -2372,14 +2443,22 @@ package body Atree is -- Zero_Slots -- ---------------- - procedure Zero_Slots (First, Last : Node_Offset) is + procedure Zero_Dynamic_Slots (First, Last : Node_Offset'Base) is begin Slots.Table (First .. Last) := (others => 0); - end Zero_Slots; + end Zero_Dynamic_Slots; + + procedure Zero_Header_Slots (N : Node_Or_Entity_Id) is + All_Node_Offsets : Node_Offsets.Table_Type renames + Node_Offsets.Table (Node_Offsets.First .. Node_Offsets.Last); + begin + All_Node_Offsets (N).Slots := (others => 0); + end Zero_Header_Slots; procedure Zero_Slots (N : Node_Or_Entity_Id) is begin - Zero_Slots (Off_0 (N), Off_L (N)); + Zero_Dynamic_Slots (Off_F (N), Off_L (N)); + Zero_Header_Slots (N); end Zero_Slots; end Atree; |