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/gen_il-gen.adb | |
parent | 7165704bfaae012cb28e5411619218da6fb8320d (diff) | |
download | gcc-99e30ba8c01f80a81891223069d47d8a611082c4.zip gcc-99e30ba8c01f80a81891223069d47d8a611082c4.tar.gz gcc-99e30ba8c01f80a81891223069d47d8a611082c4.tar.bz2 |
[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/gen_il-gen.adb')
-rw-r--r-- | gcc/ada/gen_il-gen.adb | 548 |
1 files changed, 326 insertions, 222 deletions
diff --git a/gcc/ada/gen_il-gen.adb b/gcc/ada/gen_il-gen.adb index 3bb9807..95fb526 100644 --- a/gcc/ada/gen_il-gen.adb +++ b/gcc/ada/gen_il-gen.adb @@ -28,6 +28,20 @@ with Ada.Text_IO; package body Gen_IL.Gen is + Num_Header_Slots : constant := 3; + -- Number of header slots; the first Num_Header_Slots slots are stored in + -- the header; the rest are dynamically allocated in the Slots table. We + -- need to subtract this off when accessing dynamic slots. The constant + -- Seinfo.N_Head will contain this value. + -- + -- This number can be adjusted for efficiency. We choose 3 because the + -- minimum node size is 3 slots, and because that causes the size of type + -- Node_Header to be a power of 2. We can't make it zero, however, because + -- C doesn't allow zero-length arrays. + + N_Head : constant String := Image (Field_Offset'(Num_Header_Slots)); + -- String form of the above + Enable_Assertions : constant Boolean := True; -- True to enable predicates on the _Id types, and preconditions on getters -- and setters. @@ -37,6 +51,9 @@ package body Gen_IL.Gen is -- which results in enormous nodes. For experimenting and debugging. -- Should be True in normal operation, for efficiency. + SS : constant := 32; -- slot size in bits + SSS : constant String := Image (Bit_Offset'(SS)); + Inline : constant String := "Inline"; -- For experimenting with Inline_Always @@ -563,6 +580,8 @@ package body Gen_IL.Gen is procedure Put_Setter_Spec (S : in out Sink; F : Field_Enum); procedure Put_Getter_Decl (S : in out Sink; F : Field_Enum); procedure Put_Setter_Decl (S : in out Sink; F : Field_Enum); + procedure Put_Getter_Setter_Locals + (S : in out Sink; F : Field_Enum; Get : Boolean); procedure Put_Getter_Body (S : in out Sink; F : Field_Enum); procedure Put_Setter_Body (S : in out Sink; F : Field_Enum); -- Print out the specification, declaration, or body of a getter or @@ -573,9 +592,9 @@ package body Gen_IL.Gen is -- Print out the precondition, if any, for a getter or setter for the -- given field. - procedure Put_Low_Level_Accessor_Instantiations + procedure Put_Casts (S : in out Sink; T : Type_Enum); - -- Print out the low-level getter and setter for a given type + -- Print out the Cast functions for a given type procedure Put_Traversed_Fields (S : in out Sink); -- Called by Put_Nodes to print out the Traversed_Fields table in @@ -616,19 +635,14 @@ package body Gen_IL.Gen is -- corresponding to the Ada Node_Kind, Entity_Kind, and subtypes -- thereof. - procedure Put_Low_Level_C_Getter - (S : in out Sink; T : Type_Enum); - -- Used by Put_Sinfo_Dot_H and Put_Einfo_Dot_H to print out low-level - -- getters. - - procedure Put_High_Level_C_Getters + procedure Put_C_Getters (S : in out Sink; Root : Root_Type); -- Used by Put_Sinfo_Dot_H and Put_Einfo_Dot_H to print out high-level -- getters. - procedure Put_High_Level_C_Getter + procedure Put_C_Getter (S : in out Sink; F : Field_Enum); - -- Used by Put_High_Level_C_Getters to print out one high-level getter. + -- Used by Put_C_Getters to print out one high-level getter. procedure Put_Union_Membership (S : in out Sink; Root : Root_Type); @@ -884,13 +898,13 @@ package body Gen_IL.Gen is function To_Size_In_Slots (Size_In_Bits : Bit_Offset) return Field_Offset is - ((Field_Offset (Size_In_Bits) + 31) / 32); + ((Field_Offset (Size_In_Bits) + (SS - 1)) / SS); function Type_Size_In_Slots (T : Concrete_Type) return Field_Offset is (To_Size_In_Slots (Type_Bit_Size (T))); -- rounded up to slot boundary function Type_Bit_Size_Aligned (T : Concrete_Type) return Bit_Offset is - (Bit_Offset (Type_Size_In_Slots (T)) * 32); -- multiple of slot size + (Bit_Offset (Type_Size_In_Slots (T)) * SS); -- multiple of slot size --------------------------- -- Compute_Field_Offsets -- @@ -1289,7 +1303,10 @@ package body Gen_IL.Gen is end if; end loop; - Type_Bit_Size (T) := Max_Offset + 1; + -- No type can be smaller than the header slots + + Type_Bit_Size (T) := + Bit_Offset'Max (Max_Offset + 1, SS * Num_Header_Slots); end; end loop; @@ -1596,57 +1613,25 @@ package body Gen_IL.Gen is (if Setter_Needs_Parent (F) then "_With_Parent" else "")); ------------------------------------------- - -- Put_Low_Level_Accessor_Instantiations -- + -- Put_Casts -- ------------------------------------------- - procedure Put_Low_Level_Accessor_Instantiations + procedure Put_Casts (S : in out Sink; T : Type_Enum) is + Pre : constant String := + "function Cast is new Unchecked_Conversion ("; + Lo_Type : constant String := "Field_Size_" & Image (Field_Size (T)) & "_Bit"; + Hi_Type : constant String := Get_Set_Id_Image (T); begin - -- Special case for subtypes of Uint that have predicates. Use - -- Get_Valid_32_Bit_Field in that case. - - if T in Uint_Subtype then - pragma Assert (Field_Size (T) = 32); - Put (S, LF & "function " & Low_Level_Getter_Name (T) & - " is new Get_Valid_32_Bit_Field (" & - Get_Set_Id_Image (T) & - ") with " & Inline & ";" & LF); - - -- Special case for types that have special defaults; instantiate - -- Get_32_Bit_Field_With_Default and pass in the Default_Val. - - elsif Field_Has_Special_Default (T) then - pragma Assert (Field_Size (T) = 32); - Put (S, LF & "function " & Low_Level_Getter_Name (T) & - " is new Get_32_Bit_Field_With_Default (" & - Get_Set_Id_Image (T) & ", " & Special_Default (T) & - ") with " & Inline & ";" & LF); - - -- Otherwise, instantiate the normal getter for the right size in - -- bits. - - else - Put (S, LF & "function " & Low_Level_Getter_Name (T) & - " is new Get_" & Image (Field_Size (T)) & "_Bit_Field (" & - Get_Set_Id_Image (T) & ") with " & Inline & ";" & LF); - end if; - - if T in Node_Kind_Type | Entity_Kind_Type then - Put (S, "pragma Warnings (Off);" & LF); - -- Set_Node_Kind_Type and Set_Entity_Kind_Type might not be called - end if; - - -- No special cases for the setter - - Put (S, "procedure " & Low_Level_Setter_Name (T) & " is new Set_" & - Image (Field_Size (T)) & "_Bit_Field (" & Get_Set_Id_Image (T) & - ") with " & Inline & ";" & LF); + if T not in Uint_Subtype then + if T not in Node_Kind_Type | Entity_Kind_Type then + Put (S, Pre & Hi_Type & ", " & Lo_Type & ");" & LF); + end if; - if T in Node_Kind_Type | Entity_Kind_Type then - Put (S, "pragma Warnings (On);" & LF); + Put (S, Pre & Lo_Type & ", " & Hi_Type & ");" & LF); end if; - end Put_Low_Level_Accessor_Instantiations; + end Put_Casts; ---------------------- -- Put_Precondition -- @@ -1753,12 +1738,64 @@ package body Gen_IL.Gen is Put (S, ";" & LF); end Put_Getter_Decl; + ------------------------------ + -- Put_Getter_Setter_Locals -- + ------------------------------ + + procedure Put_Getter_Setter_Locals + (S : in out Sink; F : Field_Enum; Get : Boolean) + is + Rec : Field_Info renames Field_Table (F).all; + + Off : constant Field_Offset := Rec.Offset; + F_Size : constant Bit_Offset := Field_Size (Rec.Field_Type); + F_Per_Slot : constant Field_Offset := + SS / Field_Offset (Field_Size (Rec.Field_Type)); + Slot_Off : constant Field_Offset := Off / F_Per_Slot; + In_NH : constant Boolean := Slot_Off < Num_Header_Slots; + + N : constant String := + (if Get then Node_To_Fetch_From (F) else "N"); + + begin + Put (S, " is" & LF); + Increase_Indent (S, 3); + Put (S, "-- " & Image (F_Per_Slot) & " " & Image (F_Size) & + "-bit fields per " & SSS & "-bit slot." & LF); + Put (S, "-- Offset " & Image (Off) & " = " & + Image (Slot_Off) & " slots + " & Image (Off mod F_Per_Slot) & + " fields in slot." & LF & LF); + + Put (S, "Off : constant := " & Image (Off) & ";" & LF); + Put (S, "F_Size : constant := " & Image (F_Size) & ";" & LF); + + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "Mask : constant := 2**F_Size - 1;" & LF); + end if; + + Put (S, "F_Per_Slot : constant Field_Offset := Slot_Size / F_Size;" & LF); + Put (S, "Slot_Off : constant Field_Offset := Off / F_Per_Slot;" & LF); + + if In_NH then + Put (S, "S : Slot renames Node_Offsets.Table (" & N & ").Slots (Slot_Off);" & LF); + else + Put (S, "S : Slot renames Slots.Table (Node_Offsets.Table (" & N & ").Offset + Slot_Off);" & LF); + end if; + + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "V : constant Natural := Natural ((Off mod F_Per_Slot) * F_Size);" & LF); + Put (S, LF); + end if; + end Put_Getter_Setter_Locals; + --------------------- -- Put_Getter_Body -- --------------------- procedure Put_Getter_Body (S : in out Sink; F : Field_Enum) is Rec : Field_Info renames Field_Table (F).all; + F_Size : constant Bit_Offset := Field_Size (Rec.Field_Type); + T : constant String := Get_Set_Id_Image (Rec.Field_Type); begin -- Note that we store the result in a local constant below, so that -- the "Pre => ..." can refer to it. The constant is called Val so @@ -1767,16 +1804,43 @@ package body Gen_IL.Gen is -- and setter. Put_Getter_Spec (S, F); - Put (S, " is" & LF); - Increase_Indent (S, 3); - Put (S, "Val : constant " & Get_Set_Id_Image (Rec.Field_Type) & - " := " & Low_Level_Getter_Name (Rec.Field_Type) & - " (" & Node_To_Fetch_From (F) & ", " & - Image (Rec.Offset) & ");" & LF); + Put_Getter_Setter_Locals (S, F, Get => True); + + Put (S, "Raw : constant Field_Size_" & Image (F_Size) & "_Bit :=" & LF); + Increase_Indent (S, 2); + Put (S, "Field_Size_" & Image (F_Size) & "_Bit ("); + + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "Shift_Right (S, V) and Mask);" & LF); + else + Put (S, "S);" & LF); + end if; + + Decrease_Indent (S, 2); + + Put (S, "Val : constant " & T & " :="); + + if Field_Has_Special_Default (Rec.Field_Type) then + pragma Assert (Field_Size (Rec.Field_Type) = 32); + Put (S, LF); + Increase_Indent (S, 2); + Put (S, "(if Raw = 0 then " & Special_Default (Rec.Field_Type) & " else " & "Cast (Raw));"); + Decrease_Indent (S, 2); + + else + Put (S, " Cast (Raw);"); + end if; + + Put (S, LF); + Decrease_Indent (S, 3); Put (S, "begin" & LF); Increase_Indent (S, 3); + Put (S, "-- pragma Debug (Validate_Node_And_Offset (NN, Slot_Off));" & LF); + -- Comment out the validation, because it's too slow, and because the + -- relevant routines in Atree are not visible. + if Rec.Pre.all /= "" then Put (S, "pragma Assert (" & Rec.Pre.all & ");" & LF); end if; @@ -1824,6 +1888,7 @@ package body Gen_IL.Gen is procedure Put_Setter_Body (S : in out Sink; F : Field_Enum) is Rec : Field_Info renames Field_Table (F).all; + F_Size : constant Bit_Offset := Field_Size (Rec.Field_Type); -- If Type_Only was specified in the call to Create_Semantic_Field, -- then we assert that the node is a base type. We cannot assert that @@ -1836,10 +1901,18 @@ package body Gen_IL.Gen is "Is_Base_Type (N)"); begin Put_Setter_Spec (S, F); - Put (S, " is" & LF); + Put_Getter_Setter_Locals (S, F, Get => False); + + Put (S, "Raw : constant Field_Size_" & Image (F_Size) & "_Bit := Cast (Val);" & LF); + + Decrease_Indent (S, 3); Put (S, "begin" & LF); Increase_Indent (S, 3); + Put (S, "-- pragma Debug (Validate_Node_And_Offset_Write (N, Slot_Off));" & LF); + -- Comment out the validation, because it's too slow, and because the + -- relevant routines in Atree are not visible. + if Rec.Pre.all /= "" then Put (S, "pragma Assert (" & Rec.Pre.all & ");" & LF); end if; @@ -1852,8 +1925,28 @@ package body Gen_IL.Gen is Put (S, "pragma Assert (" & Type_Only_Assertion & ");" & LF); end if; - Put (S, Low_Level_Setter_Name (F) & " (N, " & Image (Rec.Offset) - & ", Val);" & LF); + if Setter_Needs_Parent (F) then + declare + Err : constant String := + (if Rec.Field_Type = List_Id then "Error_List" else "Error"); + begin + Put (S, "if Present (Val) and then Val /= " & Err & " then" & LF); + Increase_Indent (S, 3); + Put (S, "pragma Warnings (Off, ""actuals for this call may be in wrong order"");" & LF); + Put (S, "Set_Parent (Val, N);" & LF); + Put (S, "pragma Warnings (On, ""actuals for this call may be in wrong order"");" & LF); + Decrease_Indent (S, 3); + Put (S, "end if;" & LF & LF); + end; + end if; + + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "S := (S and not Shift_Left (Mask, V)) or Shift_Left (Slot (Raw), V);" & LF); + + else + Put (S, "S := Slot (Raw);" & LF); + end if; + Decrease_Indent (S, 3); Put (S, "end Set_" & Image (F) & ";" & LF & LF); end Put_Setter_Body; @@ -2076,7 +2169,7 @@ package body Gen_IL.Gen is when others => "Entity_Field"); -- Entity_Kind begin - Put (S, "-- Table of sizes in 32-bit slots for given " & + Put (S, "-- Table of sizes in " & SSS & "-bit slots for given " & Image (Root) & ", for use by Atree:" & LF); case Root is @@ -2107,34 +2200,48 @@ package body Gen_IL.Gen is Put (S, "); -- Size" & LF); Decrease_Indent (S, 2); - declare - type Dummy is array - (First_Field (Root) .. Last_Field (Root)) of Boolean; - Num_Fields : constant Root_Int := Dummy'Length; - First_Time : Boolean := True; - begin - Put (S, LF & "-- Enumeration of all " & Image (Num_Fields) - & " fields:" & LF & LF); + if Root = Node_Kind then + declare + type Node_Dummy is array (Node_Field) of Boolean; + type Entity_Dummy is array (Entity_Field) of Boolean; + Num_Fields : constant Root_Int := + Node_Dummy'Length + Entity_Dummy'Length; + First_Time : Boolean := True; + begin + Put (S, LF & "-- Enumeration of all " & Image (Num_Fields) + & " fields:" & LF & LF); - Put (S, "type " & Field_Enum_Type_Name & " is" & LF); - Increase_Indent (S, 2); - Put (S, "("); - Increase_Indent (S, 1); + Put (S, "type Node_Or_Entity_Field is" & LF); + Increase_Indent (S, 2); + Put (S, "("); + Increase_Indent (S, 1); - for F in First_Field (Root) .. Last_Field (Root) loop - if First_Time then - First_Time := False; - else + for F in Node_Field loop + if First_Time then + First_Time := False; + else + Put (S, "," & LF); + end if; + + Put (S, F_Image (F)); + end loop; + + for F in Entity_Field loop Put (S, "," & LF); - end if; + Put (S, F_Image (F)); + end loop; - Put (S, F_Image (F)); - end loop; + Decrease_Indent (S, 1); + Put (S, "); -- Node_Or_Entity_Field" & LF); + Decrease_Indent (S, 2); + end; + end if; - Decrease_Indent (S, 1); - Put (S, "); -- " & Field_Enum_Type_Name & LF); - Decrease_Indent (S, 2); - end; + Put (S, LF & "subtype " & Field_Enum_Type_Name & " is" & LF); + Increase_Indent (S, 2); + Put (S, "Node_Or_Entity_Field range " & F_Image (First_Field (Root)) & + " .. " & F_Image (Last_Field (Root)) & ";" & LF); + Decrease_Indent (S, 2); Put (S, LF & "type " & Field_Enum_Type_Name & "_Index is new Pos;" & LF); Put (S, "type " & Field_Enum_Type_Name & "_Array is array (" & @@ -2193,34 +2300,43 @@ package body Gen_IL.Gen is Decrease_Indent (S, 2); end; - declare - First_Time : Boolean := True; - begin - Put (S, LF & "-- Table mapping fields to kind and offset:" & LF & LF); + if Root = Node_Kind then + declare + First_Time : Boolean := True; + begin + Put (S, LF & "-- Table mapping fields to kind and offset:" & LF & LF); - Put (S, Field_Enum_Type_Name & "_Descriptors : constant array (" & - Field_Enum_Type_Name & ") of Field_Descriptor :=" & LF); + Put (S, "Field_Descriptors : constant array (" & + "Node_Or_Entity_Field) of Field_Descriptor :=" & LF); - Increase_Indent (S, 2); - Put (S, "("); - Increase_Indent (S, 1); + Increase_Indent (S, 2); + Put (S, "("); + Increase_Indent (S, 1); - for F in First_Field (Root) .. Last_Field (Root) loop - if First_Time then - First_Time := False; - else - Put (S, "," & LF); - end if; + for F in Node_Field loop + if First_Time then + First_Time := False; + else + Put (S, "," & LF); + end if; - Put (S, F_Image (F) & " => (" & - Image (Field_Table (F).Field_Type) & "_Field, " & - Image (Field_Table (F).Offset) & ")"); - end loop; + Put (S, F_Image (F) & " => (" & + Image (Field_Table (F).Field_Type) & "_Field, " & + Image (Field_Table (F).Offset) & ")"); + end loop; - Decrease_Indent (S, 1); - Put (S, "); -- Field_Descriptors" & LF); - Decrease_Indent (S, 2); - end; + for F in Entity_Field loop + Put (S, "," & LF); + Put (S, F_Image (F) & " => (" & + Image (Field_Table (F).Field_Type) & "_Field, " & + Image (Field_Table (F).Offset) & ")"); + end loop; + + Decrease_Indent (S, 1); + Put (S, "); -- Field_Descriptors" & LF); + Decrease_Indent (S, 2); + end; + end if; end Put_Tables; @@ -2293,6 +2409,21 @@ package body Gen_IL.Gen is Decrease_Indent (S, 3); Put (S, "end record;" & LF); + -- Print out the node header types. Note that the Offset field is of + -- the base type, because we are using zero-origin addressing in + -- Atree. + + Put (S, "N_Head : constant Field_Offset := " & N_Head & ";" & LF); + Put (S, "" & LF); + Put (S, "type Node_Header_Slots is" & LF); + Put (S, " array (Field_Offset range 0 .. N_Head - 1) of aliased Slot;" & LF); + Put (S, "type Node_Header is record" & LF); + Put (S, " Slots : Node_Header_Slots;" & LF); + Put (S, " Offset : Node_Offset'Base;" & LF); + Put (S, "end record;" & LF); + Put (S, "pragma Assert (Node_Header'Size = (" & N_Head & + " + 1) * " & SSS & ");" & LF); + Decrease_Indent (S, 3); Put (S, LF & "end Seinfo;" & LF); end Put_Seinfo; @@ -2305,39 +2436,6 @@ package body Gen_IL.Gen is S : Sink; B : Sink; - procedure Put_Setter_With_Parent (Kind : String); - -- Put the low-level ..._With_Parent setter. Kind is either "Node" or - -- "List". - - procedure Put_Setter_With_Parent (Kind : String) is - Error : constant String := (if Kind = "Node" then "" else "_" & Kind); - begin - Put (B, LF & "procedure Set_" & Kind & "_Id_With_Parent" & LF); - Increase_Indent (B, 2); - Put (B, "(N : Node_Id; Offset : Field_Offset; Val : " & Kind & "_Id);" & LF & LF); - Decrease_Indent (B, 2); - - Put (B, "procedure Set_" & Kind & "_Id_With_Parent" & LF); - Increase_Indent (B, 2); - Put (B, "(N : Node_Id; Offset : Field_Offset; Val : " & Kind & "_Id) is" & LF); - Decrease_Indent (B, 2); - Put (B, "begin" & LF); - Increase_Indent (B, 3); - Put (B, "if Present (Val) and then Val /= Error" & Error & " then" & LF); - Increase_Indent (B, 3); - Put (B, "pragma Warnings (Off, ""actuals for this call may be in wrong order"");" & LF); - Put (B, "Set_Parent (Val, N);" & LF); - Put (B, "pragma Warnings (On, ""actuals for this call may be in wrong order"");" & LF); - Decrease_Indent (B, 3); - Put (B, "end if;" & LF & LF); - - Put (B, "Set_" & Kind & "_Id (N, Offset, Val);" & LF); - Decrease_Indent (B, 3); - Put (B, "end Set_" & Kind & "_Id_With_Parent;" & LF); - end Put_Setter_With_Parent; - - -- Start of processing for Put_Nodes - begin Create_File (S, "sinfo-nodes.ads"); Create_File (B, "sinfo-nodes.adb"); @@ -2369,6 +2467,7 @@ package body Gen_IL.Gen is Decrease_Indent (S, 3); Put (S, LF & "end Sinfo.Nodes;" & LF); + Put (B, "with Unchecked_Conversion;" & LF); Put (B, "with Atree; use Atree; use Atree.Atree_Private_Part;" & LF); Put (B, "with Nlists; use Nlists;" & LF); Put (B, "pragma Warnings (Off);" & LF); @@ -2381,19 +2480,14 @@ package body Gen_IL.Gen is Put (B, "-- This package is automatically generated." & LF & LF); - Put (B, "-- Instantiations of low-level getters and setters that take offsets" & LF); - Put (B, "-- in units of the size of the field." & LF); - Put (B, "pragma Style_Checks (""M200"");" & LF); + for T in Special_Type loop if Node_Field_Types_Used (T) then - Put_Low_Level_Accessor_Instantiations (B, T); + Put_Casts (B, T); end if; end loop; - Put_Setter_With_Parent ("Node"); - Put_Setter_With_Parent ("List"); - Put_Subp_Bodies (B, Node_Kind); Decrease_Indent (B, 3); @@ -2411,7 +2505,6 @@ package body Gen_IL.Gen is begin Create_File (S, "einfo-entities.ads"); Create_File (B, "einfo-entities.adb"); - Put (S, "with Seinfo; use Seinfo;" & LF); Put (S, "with Sinfo.Nodes; use Sinfo.Nodes;" & LF); Put (S, LF & "package Einfo.Entities is" & LF & LF); @@ -2430,6 +2523,7 @@ package body Gen_IL.Gen is Decrease_Indent (S, 3); Put (S, LF & "end Einfo.Entities;" & LF); + Put (B, "with Unchecked_Conversion;" & LF); Put (B, "with Atree; use Atree; use Atree.Atree_Private_Part;" & LF); Put (B, "with Einfo.Utils; use Einfo.Utils;" & LF); -- This forms a cycle between packages (via bodies, which is OK) @@ -2439,13 +2533,11 @@ package body Gen_IL.Gen is Put (B, "-- This package is automatically generated." & LF & LF); - Put (B, "-- Instantiations of low-level getters and setters that take offsets" & LF); - Put (B, "-- in units of the size of the field." & LF); - Put (B, "pragma Style_Checks (""M200"");" & LF); + for T in Special_Type loop if Entity_Field_Types_Used (T) then - Put_Low_Level_Accessor_Instantiations (B, T); + Put_Casts (B, T); end if; end loop; @@ -2714,11 +2806,11 @@ package body Gen_IL.Gen is return Result : Bit_Offset do if F = No_Field then -- We don't have a field size for No_Field, so just look at - -- the bits up to the next word boundary. + -- the bits up to the next slot boundary. Result := First_Bit; - while (Result + 1) mod 32 /= 0 + while (Result + 1) mod SS /= 0 and then Type_Layout (T) (Result + 1) = No_Field loop Result := Result + 1; @@ -2731,19 +2823,19 @@ package body Gen_IL.Gen is end Get_Last_Bit; function First_Bit_Image (First_Bit : Bit_Offset) return String is - W : constant Bit_Offset := First_Bit / 32; - B : constant Bit_Offset := First_Bit mod 32; - pragma Assert (W * 32 + B = First_Bit); + W : constant Bit_Offset := First_Bit / SS; + B : constant Bit_Offset := First_Bit mod SS; + pragma Assert (W * SS + B = First_Bit); begin return - Image (W) & "*32" & (if B = 0 then "" else " + " & Image (B)); + Image (W) & "*" & SSS & (if B = 0 then "" else " + " & Image (B)); end First_Bit_Image; function Last_Bit_Image (Last_Bit : Bit_Offset) return String is - W : constant Bit_Offset := (Last_Bit + 1) / 32; + W : constant Bit_Offset := (Last_Bit + 1) / SS; begin - if W * 32 - 1 = Last_Bit then - return Image (W) & "*32 - 1"; + if W * SS - 1 = Last_Bit then + return Image (W) & "*" & SSS & " - 1"; else return First_Bit_Image (Last_Bit); end if; @@ -3027,76 +3119,84 @@ package body Gen_IL.Gen is Put_Union_Membership (S, Root); end Put_C_Type_And_Subtypes; - ---------------------------- - -- Put_Low_Level_C_Getter -- - ---------------------------- + ------------------ + -- Put_C_Getter -- + ------------------ - procedure Put_Low_Level_C_Getter - (S : in out Sink; T : Type_Enum) + procedure Put_C_Getter + (S : in out Sink; F : Field_Enum) is - T_Image : constant String := Get_Set_Id_Image (T); + Rec : Field_Info renames Field_Table (F).all; + + Off : constant Field_Offset := Rec.Offset; + F_Size : constant Bit_Offset := Field_Size (Rec.Field_Type); + F_Per_Slot : constant Field_Offset := + SS / Field_Offset (Field_Size (Rec.Field_Type)); + Slot_Off : constant Field_Offset := Off / F_Per_Slot; + In_NH : constant Boolean := Slot_Off < Num_Header_Slots; + N : constant String := Node_To_Fetch_From (F); begin - Put (S, "INLINE " & T_Image & "" & LF); - Put (S, "Get_" & Image (T) & " (Node_Id N, Field_Offset Offset)" & LF); + Put (S, "INLINE " & Get_Set_Id_Image (Rec.Field_Type) & + " " & Image (F) & " (Node_Id N)" & LF); + Put (S, "{" & LF); Increase_Indent (S, 3); + Put (S, "const Field_Offset Off = " & Image (Rec.Offset) & ";" & LF); + Put (S, "const Field_Offset F_Size = " & Image (F_Size) & ";" & LF); - -- Same special cases for getters as in - -- Put_Low_Level_Accessor_Instantiations. - - if T in Uint_Subtype then - pragma Assert (Field_Size (T) = 32); - Put (S, "{ return (" & T_Image & - ") Get_Valid_32_Bit_Field(N, Offset); }" & LF & LF); + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "const any_slot Mask = (1 << F_Size) - 1;" & LF); + end if; - elsif Field_Has_Special_Default (T) then - pragma Assert (Field_Size (T) = 32); - Put (S, "{ return (" & T_Image & - ") Get_32_Bit_Field_With_Default(N, Offset, " & - Special_Default (T) & "); }" & LF & LF); + Put (S, "const Field_Offset F_Per_Slot = Slot_Size / F_Size;" & LF); + Put (S, "const Field_Offset Slot_Off = Off / F_Per_Slot;" & LF); + Put (S, LF); + if In_NH then + Put (S, "any_slot slot = Node_Offsets_Ptr[" & N & "].Slots[Slot_Off];" & LF); + else + Put (S, "any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[" & N & + "].Offset + Slot_Off);" & LF); + end if; + if Field_Size (Rec.Field_Type) /= SS then + Put (S, "unsigned int Raw = (slot >> (Off % F_Per_Slot) * F_Size) & Mask;" & LF); else - Put (S, "{ return (" & T_Image & ") Get_" & - Image (Field_Size (T)) & "_Bit_Field(N, Offset); }" & LF & LF); + Put (S, "unsigned int Raw = slot;" & LF); end if; - Decrease_Indent (S, 3); - end Put_Low_Level_C_Getter; + Put (S, Get_Set_Id_Image (Rec.Field_Type) & " val = "); - ----------------------------- - -- Put_High_Level_C_Getter -- - ----------------------------- + if Field_Has_Special_Default (Rec.Field_Type) then + Increase_Indent (S, 2); + Put (S, "(Raw? Raw : " & Special_Default (Rec.Field_Type) & ")"); + Decrease_Indent (S, 2); - procedure Put_High_Level_C_Getter - (S : in out Sink; F : Field_Enum) - is - begin - Put (S, "INLINE " & Get_Set_Id_Image (Field_Table (F).Field_Type) & - " " & Image (F) & " (Node_Id N)" & LF); + else + Put (S, "Raw"); + end if; - Increase_Indent (S, 3); - Put (S, "{ return " & - Low_Level_Getter_Name (Field_Table (F).Field_Type) & - "(" & Node_To_Fetch_From (F) & ", " & - Image (Field_Table (F).Offset) & "); }" & LF & LF); + Put (S, ";" & LF); + + Put (S, "return val;" & LF); Decrease_Indent (S, 3); - end Put_High_Level_C_Getter; + Put (S, "}" & LF & LF); + end Put_C_Getter; - ------------------------------ - -- Put_High_Level_C_Getters -- - ------------------------------ + ------------------- + -- Put_C_Getters -- + ------------------- - procedure Put_High_Level_C_Getters + procedure Put_C_Getters (S : in out Sink; Root : Root_Type) is begin Put (S, "// Getters for fields" & LF & LF); for F in First_Field (Root) .. Last_Field (Root) loop - Put_High_Level_C_Getter (S, F); + Put_C_Getter (S, F); end loop; - end Put_High_Level_C_Getters; + end Put_C_Getters; -------------------------- -- Put_Union_Membership -- @@ -3174,16 +3274,24 @@ package body Gen_IL.Gen is Put (S, "typedef Boolean Flag;" & LF & LF); + Put (S, "#define N_Head " & N_Head & LF); + Put (S, "" & LF); + Put (S, "typedef struct Node_Header {" & LF); + Increase_Indent (S, 2); + Put (S, "any_slot Slots[N_Head];" & LF); + Put (S, "Field_Offset Offset;" & LF); + Decrease_Indent (S, 2); + Put (S, "} Node_Header;" & LF & LF); + + Put (S, "extern Node_Header *Node_Offsets_Ptr;" & LF); + Put (S, "extern any_slot *Slots_Ptr;" & LF & LF); + Put_C_Type_And_Subtypes (S, Node_Kind); Put (S, "// Getters corresponding to instantiations of Atree.Get_n_Bit_Field" & LF & LF); - for T in Special_Type loop - Put_Low_Level_C_Getter (S, T); - end loop; - - Put_High_Level_C_Getters (S, Node_Kind); + Put_C_Getters (S, Node_Kind); Put (S, "#ifdef __cplusplus" & LF); Put (S, "}" & LF); @@ -3238,11 +3346,7 @@ package body Gen_IL.Gen is Put_C_Type_And_Subtypes (S, Entity_Kind); - -- Note that we do not call Put_Low_Level_C_Getter here. Those are in - -- sinfo.h, so every file that #includes einfo.h must #include - -- sinfo.h first. - - Put_High_Level_C_Getters (S, Entity_Kind); + Put_C_Getters (S, Entity_Kind); Put (S, "// Abstract type queries" & LF & LF); |