From patchwork Fri May 7 09:38:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 1475436 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Fc55b4N2Jz9t0G for ; Fri, 7 May 2021 19:40:03 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4BF7B3B8A42A; Fri, 7 May 2021 09:38:39 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTP id 2C5B93938C12 for ; Fri, 7 May 2021 09:38:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2C5B93938C12 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=derodat@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 37D3956360; Fri, 7 May 2021 05:38:26 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id FlLWAQeS3TQt; Fri, 7 May 2021 05:38:26 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id B7B1256367; Fri, 7 May 2021 05:38:23 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id B3D38FA; Fri, 7 May 2021 05:38:23 -0400 (EDT) Date: Fri, 7 May 2021 05:38:23 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Subject: [Ada] Replace packed records with integers in low-level implementation Message-ID: <20210507093823.GA140787@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Eric Botcazou Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Accessing components in packed record types turns out to be too slow for practical use so this replaces them with integer types. Tested on x86_64-pc-linux-gnu, committed on trunk gcc/ada/ * atree.ads (Slot): Change to modular type. (Slot_1_Bit): Delete. (Slot_2_Bit): Likewise. (Slot_4_Bit): Likewise. (Slot_8_Bit): Likewise. (Slot_32_Bit): Likewise. * atree.adb (Get_1_Bit_Val): Adjust to above change. (Get_2_Bit_Val): Likewise. (Get_4_Bit_Val): Likewise. (Get_8_Bit_Val): Likewise. (Get_32_Bit_Val): Likewise. (Set_1_Bit_Val): Likewise. (Set_2_Bit_Val): Likewise. (Set_4_Bit_Val): Likewise. (Set_8_Bit_Val): Likewise. (Set_32_Bit_Val): Likewise. (Print_Atree_Info): Likewise. (Zero): Likewise. * atree.h (Get_1_Bit_Field): Likewise. (Get_2_Bit_Field): Likewise. (Get_4_Bit_Field): Likewise. (Get_8_Bit_Field): Likewise. (Get_32_Bit_Field): Likewise. (Get_32_Bit_Field_With_Default): Likewise. * types.h (slot_1_bit): Delete. (slot_2_bit): Likewise. (slot_4_bit): Likewise. (slot_8_bit): Likewise. (slot_32_bit): Likewise. (any_slot): Change to unsigned int. (Slot_Size): New macro. diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb --- a/gcc/ada/atree.adb +++ b/gcc/ada/atree.adb @@ -599,119 +599,55 @@ package body Atree is (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_1_Bit is -- We wish we were using packed arrays, but instead we're simulating - -- packed arrays using packed records. L here (and elsewhere) is the - -- 'Length of that array. - L : constant Field_Offset := 32; + -- 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)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => return S.Slot_1.F0; - when 1 => return S.Slot_1.F1; - when 2 => return S.Slot_1.F2; - when 3 => return S.Slot_1.F3; - when 4 => return S.Slot_1.F4; - when 5 => return S.Slot_1.F5; - when 6 => return S.Slot_1.F6; - when 7 => return S.Slot_1.F7; - when 8 => return S.Slot_1.F8; - when 9 => return S.Slot_1.F9; - when 10 => return S.Slot_1.F10; - when 11 => return S.Slot_1.F11; - when 12 => return S.Slot_1.F12; - when 13 => return S.Slot_1.F13; - when 14 => return S.Slot_1.F14; - when 15 => return S.Slot_1.F15; - when 16 => return S.Slot_1.F16; - when 17 => return S.Slot_1.F17; - when 18 => return S.Slot_1.F18; - when 19 => return S.Slot_1.F19; - when 20 => return S.Slot_1.F20; - when 21 => return S.Slot_1.F21; - when 22 => return S.Slot_1.F22; - when 23 => return S.Slot_1.F23; - when 24 => return S.Slot_1.F24; - when 25 => return S.Slot_1.F25; - when 26 => return S.Slot_1.F26; - when 27 => return S.Slot_1.F27; - when 28 => return S.Slot_1.F28; - when 29 => return S.Slot_1.F29; - when 30 => return S.Slot_1.F30; - when 31 => return S.Slot_1.F31; - end case; + return Field_1_Bit (Shift_Right (S, V) and 1); end Get_1_Bit_Val; function Get_2_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_2_Bit is - L : constant Field_Offset := 16; + L : constant Field_Offset := Slot_Size / 2; pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => return S.Slot_2.F0; - when 1 => return S.Slot_2.F1; - when 2 => return S.Slot_2.F2; - when 3 => return S.Slot_2.F3; - when 4 => return S.Slot_2.F4; - when 5 => return S.Slot_2.F5; - when 6 => return S.Slot_2.F6; - when 7 => return S.Slot_2.F7; - when 8 => return S.Slot_2.F8; - when 9 => return S.Slot_2.F9; - when 10 => return S.Slot_2.F10; - when 11 => return S.Slot_2.F11; - when 12 => return S.Slot_2.F12; - when 13 => return S.Slot_2.F13; - when 14 => return S.Slot_2.F14; - when 15 => return S.Slot_2.F15; - end case; + return Field_2_Bit (Shift_Right (S, V) and 3); end Get_2_Bit_Val; function Get_4_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_4_Bit is - L : constant Field_Offset := 8; + L : constant Field_Offset := Slot_Size / 4; pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => return S.Slot_4.F0; - when 1 => return S.Slot_4.F1; - when 2 => return S.Slot_4.F2; - when 3 => return S.Slot_4.F3; - when 4 => return S.Slot_4.F4; - when 5 => return S.Slot_4.F5; - when 6 => return S.Slot_4.F6; - when 7 => return S.Slot_4.F7; - end case; + return Field_4_Bit (Shift_Right (S, V) and 15); end Get_4_Bit_Val; function Get_8_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset) return Field_8_Bit is - L : constant Field_Offset := 4; + L : constant Field_Offset := Slot_Size / 8; pragma Debug (Validate_Node_And_Offset (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => return S.Slot_8.F0; - when 1 => return S.Slot_8.F1; - when 2 => return S.Slot_8.F2; - when 3 => return S.Slot_8.F3; - end case; + return Field_8_Bit (Shift_Right (S, V) and 255); end Get_8_Bit_Val; function Get_32_Bit_Val @@ -721,123 +657,59 @@ package body Atree is S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset); begin - return S.Slot_32; + return Field_32_Bit (S); end Get_32_Bit_Val; procedure Set_1_Bit_Val (N : Node_Or_Entity_Id; Offset : Field_Offset; Val : Field_1_Bit) is - L : constant Field_Offset := 32; + L : constant Field_Offset := Slot_Size / 1; pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => S.Slot_1.F0 := Val; - when 1 => S.Slot_1.F1 := Val; - when 2 => S.Slot_1.F2 := Val; - when 3 => S.Slot_1.F3 := Val; - when 4 => S.Slot_1.F4 := Val; - when 5 => S.Slot_1.F5 := Val; - when 6 => S.Slot_1.F6 := Val; - when 7 => S.Slot_1.F7 := Val; - when 8 => S.Slot_1.F8 := Val; - when 9 => S.Slot_1.F9 := Val; - when 10 => S.Slot_1.F10 := Val; - when 11 => S.Slot_1.F11 := Val; - when 12 => S.Slot_1.F12 := Val; - when 13 => S.Slot_1.F13 := Val; - when 14 => S.Slot_1.F14 := Val; - when 15 => S.Slot_1.F15 := Val; - when 16 => S.Slot_1.F16 := Val; - when 17 => S.Slot_1.F17 := Val; - when 18 => S.Slot_1.F18 := Val; - when 19 => S.Slot_1.F19 := Val; - when 20 => S.Slot_1.F20 := Val; - when 21 => S.Slot_1.F21 := Val; - when 22 => S.Slot_1.F22 := Val; - when 23 => S.Slot_1.F23 := Val; - when 24 => S.Slot_1.F24 := Val; - when 25 => S.Slot_1.F25 := Val; - when 26 => S.Slot_1.F26 := Val; - when 27 => S.Slot_1.F27 := Val; - when 28 => S.Slot_1.F28 := Val; - when 29 => S.Slot_1.F29 := Val; - when 30 => S.Slot_1.F30 := Val; - when 31 => S.Slot_1.F31 := Val; - end case; + S := (S and not Shift_Left (1, 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_2_Bit) is - L : constant Field_Offset := 16; + L : constant Field_Offset := Slot_Size / 2; pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => S.Slot_2.F0 := Val; - when 1 => S.Slot_2.F1 := Val; - when 2 => S.Slot_2.F2 := Val; - when 3 => S.Slot_2.F3 := Val; - when 4 => S.Slot_2.F4 := Val; - when 5 => S.Slot_2.F5 := Val; - when 6 => S.Slot_2.F6 := Val; - when 7 => S.Slot_2.F7 := Val; - when 8 => S.Slot_2.F8 := Val; - when 9 => S.Slot_2.F9 := Val; - when 10 => S.Slot_2.F10 := Val; - when 11 => S.Slot_2.F11 := Val; - when 12 => S.Slot_2.F12 := Val; - when 13 => S.Slot_2.F13 := Val; - when 14 => S.Slot_2.F14 := Val; - when 15 => S.Slot_2.F15 := Val; - end case; + S := (S and not Shift_Left (3, 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_4_Bit) is - L : constant Field_Offset := 8; + L : constant Field_Offset := Slot_Size / 4; pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => S.Slot_4.F0 := Val; - when 1 => S.Slot_4.F1 := Val; - when 2 => S.Slot_4.F2 := Val; - when 3 => S.Slot_4.F3 := Val; - when 4 => S.Slot_4.F4 := Val; - when 5 => S.Slot_4.F5 := Val; - when 6 => S.Slot_4.F6 := Val; - when 7 => S.Slot_4.F7 := Val; - end case; + S := (S and not Shift_Left (15, 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_8_Bit) is - L : constant Field_Offset := 4; + L : constant Field_Offset := Slot_Size / 8; pragma Debug (Validate_Node_And_Offset_Write (N, Offset / L)); - subtype Offset_In_Slot is Field_Offset range 0 .. L - 1; S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset / L); + V : constant Integer := Integer ((Offset mod L) * (Slot_Size / L)); begin - case Offset_In_Slot'(Offset mod L) is - when 0 => S.Slot_8.F0 := Val; - when 1 => S.Slot_8.F1 := Val; - when 2 => S.Slot_8.F2 := Val; - when 3 => S.Slot_8.F3 := Val; - end case; + S := (S and not Shift_Left (255, V)) or Shift_Left (Slot (Val), V); end Set_8_Bit_Val; procedure Set_32_Bit_Val @@ -847,7 +719,7 @@ package body Atree is S : Slot renames Slots.Table (Node_Offsets.Table (N) + Offset); begin - S.Slot_32 := Val; + S := Slot (Val); end Set_32_Bit_Val; end Atree_Private_Part; @@ -2006,7 +1878,7 @@ package body Atree is ---------------------- procedure Print_Atree_Info (N : Node_Or_Entity_Id) is - function Cast is new Unchecked_Conversion (Slot_32_Bit, Int); + function Cast is new Unchecked_Conversion (Slot, Int); begin Write_Int (Int (Size_In_Slots (N))); Write_Str (" slots ("); @@ -2017,7 +1889,7 @@ package body Atree is for Off in Off_0 (N) .. Off_L (N) loop Write_Str (" "); - Write_Int (Cast (Slots.Table (Off).Slot_32)); + Write_Int (Cast (Slots.Table (Off))); end loop; Write_Eol; @@ -2507,7 +2379,7 @@ package body Atree is Locked := False; end Unlock_Nodes; - Zero : constant Slot := (Field_Size => 32, Slot_32 => 0); + Zero : constant Slot := 0; procedure Zero_Slots (F, L : Node_Offset) is begin diff --git a/gcc/ada/atree.ads b/gcc/ada/atree.ads --- a/gcc/ada/atree.ads +++ b/gcc/ada/atree.ads @@ -722,57 +722,21 @@ package Atree is Table_Increment => Alloc.Node_Offsets_Increment, Table_Name => "Node_Offsets"); - -- We define type Slot as a packed Unchecked_Union of slots with - -- appropriate numbers of components of appropriate size. The reason - -- for this (as opposed to using packed arrays) is that we are using - -- bit fields on the C++ side, and C++ doesn't have packed arrays. - - type Field_1_Bit is mod 2**1; - type Slot_1_Bit is record -- 32 1-bit fields - F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, - F10, F11, F12, F13, F14, F15, F16, F17, F18, F19, - F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, - F30, F31 : - Field_1_Bit; - end record with Pack, Convention => C; - pragma Assert (Slot_1_Bit'Size = 32); - - type Field_2_Bit is mod 2**2; - type Slot_2_Bit is record -- 16 2-bit fields - F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15 : - Field_2_Bit; - end record with Pack, Convention => C; - pragma Assert (Slot_2_Bit'Size = 32); - - type Field_4_Bit is mod 2**4; - type Slot_4_Bit is record -- 8 4-bit fields - F0, F1, F2, F3, F4, F5, F6, F7 : - Field_4_Bit; - end record with Pack, Convention => C; - pragma Assert (Slot_4_Bit'Size = 32); - - type Field_8_Bit is mod 2**8; - type Slot_8_Bit is record -- 4 8-bit fields - F0, F1, F2, F3 : - Field_8_Bit; - end record with Pack, Convention => C; - pragma Assert (Slot_8_Bit'Size = 32); - + -- We define the type Slot as a 32-bit modular integer. It is logically + -- split into the appropriate numbers of components of appropriate size, + -- but this splitting is not explicit because packed arrays cannot be + -- properly interfaced in C/C++ and packed records are way too slow. + + Slot_Size : constant := 32; + type Slot is mod 2**Slot_Size; + for Slot'Size use Slot_Size; + pragma Provide_Shift_Operators (Slot); + + type Field_1_Bit is mod 2**1; + type Field_2_Bit is mod 2**2; + type Field_4_Bit is mod 2**4; + type Field_8_Bit is mod 2**8; type Field_32_Bit is mod 2**32; - subtype Slot_32_Bit is Field_32_Bit; -- 1 32-bit field - pragma Assert (Slot_32_Bit'Size = 32); - - type Slot (Field_Size : Field_Size_In_Bits := 9999) is record - case Field_Size is - when 1 => Slot_1 : Slot_1_Bit; - when 2 => Slot_2 : Slot_2_Bit; - when 4 => Slot_4 : Slot_4_Bit; - when 8 => Slot_8 : Slot_8_Bit; - when 32 => Slot_32 : Slot_32_Bit; - when others => null; - end case; - end record with Unchecked_Union; - pragma Assert (Slot'Size = 32); Slots_Low_Bound : constant Field_Offset := Field_Offset'First + 1; diff --git a/gcc/ada/atree.h b/gcc/ada/atree.h --- a/gcc/ada/atree.h +++ b/gcc/ada/atree.h @@ -72,144 +72,60 @@ extern Node_Id Current_Error_Node; extern Field_Offset *Node_Offsets_Ptr; extern any_slot *Slots_Ptr; -INLINE Union_Id Get_1_Bit_Field (Node_Id N, Field_Offset Offset); -INLINE Union_Id Get_2_Bit_Field (Node_Id N, Field_Offset Offset); -INLINE Union_Id Get_4_Bit_Field (Node_Id N, Field_Offset Offset); -INLINE Union_Id Get_8_Bit_Field (Node_Id N, Field_Offset Offset); -INLINE Union_Id Get_32_Bit_Field (Node_Id N, Field_Offset Offset); -INLINE Union_Id Get_32_Bit_Field_With_Default (Node_Id N, Field_Offset Offset, - Union_Id Default_Value); - -INLINE Union_Id +INLINE unsigned int Get_1_Bit_Field (Node_Id, Field_Offset); +INLINE unsigned int Get_2_Bit_Field (Node_Id, Field_Offset); +INLINE unsigned int Get_4_Bit_Field (Node_Id, Field_Offset); +INLINE unsigned int Get_8_Bit_Field (Node_Id, Field_Offset); +INLINE unsigned int Get_32_Bit_Field (Node_Id, Field_Offset); +INLINE unsigned int Get_32_Bit_Field_With_Default (Node_Id, Field_Offset, + unsigned int); + +INLINE unsigned int Get_1_Bit_Field (Node_Id N, Field_Offset Offset) { - const Field_Offset L = 32; - - slot_1_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_1; - - switch (Offset % L) - { - case 0: return slot.f0; - case 1: return slot.f1; - case 2: return slot.f2; - case 3: return slot.f3; - case 4: return slot.f4; - case 5: return slot.f5; - case 6: return slot.f6; - case 7: return slot.f7; - case 8: return slot.f8; - case 9: return slot.f9; - case 10: return slot.f10; - case 11: return slot.f11; - case 12: return slot.f12; - case 13: return slot.f13; - case 14: return slot.f14; - case 15: return slot.f15; - case 16: return slot.f16; - case 17: return slot.f17; - case 18: return slot.f18; - case 19: return slot.f19; - case 20: return slot.f20; - case 21: return slot.f21; - case 22: return slot.f22; - case 23: return slot.f23; - case 24: return slot.f24; - case 25: return slot.f25; - case 26: return slot.f26; - case 27: return slot.f27; - case 28: return slot.f28; - case 29: return slot.f29; - case 30: return slot.f30; - case 31: return slot.f31; - default: gcc_unreachable (); - } + const Field_Offset L = Slot_Size / 1; + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); + return (slot >> (Offset % L) * (Slot_Size / L)) & 1; } -INLINE Union_Id +INLINE unsigned int Get_2_Bit_Field (Node_Id N, Field_Offset Offset) { - const Field_Offset L = 16; - - slot_2_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_2; - - switch (Offset % L) - { - case 0: return slot.f0; - case 1: return slot.f1; - case 2: return slot.f2; - case 3: return slot.f3; - case 4: return slot.f4; - case 5: return slot.f5; - case 6: return slot.f6; - case 7: return slot.f7; - case 8: return slot.f8; - case 9: return slot.f9; - case 10: return slot.f10; - case 11: return slot.f11; - case 12: return slot.f12; - case 13: return slot.f13; - case 14: return slot.f14; - case 15: return slot.f15; - default: gcc_unreachable (); - } + const Field_Offset L = Slot_Size / 2; + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); + return (slot >> (Offset % L) * (Slot_Size / L)) & 3; } -INLINE Union_Id +INLINE unsigned int Get_4_Bit_Field (Node_Id N, Field_Offset Offset) { - const Field_Offset L = 8; - - slot_4_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_4; - - switch (Offset % L) - { - case 0: return slot.f0; - case 1: return slot.f1; - case 2: return slot.f2; - case 3: return slot.f3; - case 4: return slot.f4; - case 5: return slot.f5; - case 6: return slot.f6; - case 7: return slot.f7; - default: gcc_unreachable (); - } + const Field_Offset L = Slot_Size / 4; + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); + return (slot >> (Offset % L) * (Slot_Size / L)) & 15; } -INLINE Union_Id +INLINE unsigned int Get_8_Bit_Field (Node_Id N, Field_Offset Offset) { - const Field_Offset L = 4; - - slot_8_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_8; - - switch (Offset % L) - { - case 0: return slot.f0; - case 1: return slot.f1; - case 2: return slot.f2; - case 3: return slot.f3; - default: gcc_unreachable (); - } + const Field_Offset L = Slot_Size / 8; + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); + return (slot >> (Offset % L) * (Slot_Size / L)) & 255; } -INLINE Union_Id +INLINE unsigned int Get_32_Bit_Field (Node_Id N, Field_Offset Offset) { const Field_Offset L = 1; - - slot_32_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_32; - + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); return slot; } -INLINE Union_Id +INLINE unsigned int Get_32_Bit_Field_With_Default (Node_Id N, Field_Offset Offset, - Union_Id Default_Value) + unsigned int Default_Value) { const Field_Offset L = 1; - - slot_32_bit slot = (Slots_Ptr + (Node_Offsets_Ptr[N] + Offset / L))->slot_32; - + any_slot slot = *(Slots_Ptr + Node_Offsets_Ptr[N] + Offset / L); return slot == Empty ? Default_Value : slot; } diff --git a/gcc/ada/types.h b/gcc/ada/types.h --- a/gcc/ada/types.h +++ b/gcc/ada/types.h @@ -374,103 +374,15 @@ typedef Nat Small_Paren_Count_Type; typedef Nat Field_Offset; -typedef struct -{ - unsigned f0 : 1; - unsigned f1 : 1; - unsigned f2 : 1; - unsigned f3 : 1; - unsigned f4 : 1; - unsigned f5 : 1; - unsigned f6 : 1; - unsigned f7 : 1; - unsigned f8 : 1; - unsigned f9 : 1; - unsigned f10 : 1; - unsigned f11 : 1; - unsigned f12 : 1; - unsigned f13 : 1; - unsigned f14 : 1; - unsigned f15 : 1; - unsigned f16 : 1; - unsigned f17 : 1; - unsigned f18 : 1; - unsigned f19 : 1; - unsigned f20 : 1; - unsigned f21 : 1; - unsigned f22 : 1; - unsigned f23 : 1; - unsigned f24 : 1; - unsigned f25 : 1; - unsigned f26 : 1; - unsigned f27 : 1; - unsigned f28 : 1; - unsigned f29 : 1; - unsigned f30 : 1; - unsigned f31 : 1; -} slot_1_bit; - -typedef struct -{ - unsigned f0 : 2; - unsigned f1 : 2; - unsigned f2 : 2; - unsigned f3 : 2; - unsigned f4 : 2; - unsigned f5 : 2; - unsigned f6 : 2; - unsigned f7 : 2; - unsigned f8 : 2; - unsigned f9 : 2; - unsigned f10 : 2; - unsigned f11 : 2; - unsigned f12 : 2; - unsigned f13 : 2; - unsigned f14 : 2; - unsigned f15 : 2; -} slot_2_bit; - -typedef struct -{ - unsigned f0 : 4; - unsigned f1 : 4; - unsigned f2 : 4; - unsigned f3 : 4; - unsigned f4 : 4; - unsigned f5 : 4; - unsigned f6 : 4; - unsigned f7 : 4; -} slot_4_bit; - -typedef struct -{ - unsigned f0 : 8; - unsigned f1 : 8; - unsigned f2 : 8; - unsigned f3 : 8; -} slot_8_bit; - -typedef Union_Id slot_32_bit; +typedef unsigned int any_slot; -typedef union -{ - slot_1_bit slot_1; - slot_2_bit slot_2; - slot_4_bit slot_4; - slot_8_bit slot_8; - slot_32_bit slot_32; -} any_slot; +#define Slot_Size (sizeof (any_slot) * 8) /* Slots are 32 bits (for now, but we might want to make that 64). The first bootstrap stage uses -std=gnu++98, so we cannot use static_assert in that case. */ #if __cplusplus >= 201402L -static_assert (sizeof (slot_1_bit) == 4); -static_assert (sizeof (slot_2_bit) == 4); -static_assert (sizeof (slot_4_bit) == 4); -static_assert (sizeof (slot_8_bit) == 4); -static_assert (sizeof (slot_32_bit) == 4); -static_assert (sizeof (any_slot) == 4); +static_assert (Slot_Size == 32); #endif /* Definitions of Reason codes for Raise_xxx_Error nodes. */