public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [Ada] Refine conditions for calling Copy_Bitfield
@ 2019-09-17  8:06 Pierre-Marie de Rodat
  0 siblings, 0 replies; only message in thread
From: Pierre-Marie de Rodat @ 2019-09-17  8:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: Bob Duff

[-- Attachment #1: Type: text/plain, Size: 467 bytes --]

Avoid calling Copy_Bitfield if there are volatile or independent
components that might be read or written. The test is conservative.

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

2019-09-17  Bob Duff  <duff@adacore.com>

gcc/ada/

	* exp_ch5.adb (Expand_Assign_Array_Loop_Or_Bitfield): Add tests
	for potential volatile or independent components.
	* libgnat/s-bituti.adb (Copy_Small_Bitfield,
	Copy_Large_Bitfield): Move declarations to more appropriate
	place.

[-- Attachment #2: patch.diff --]
[-- Type: text/x-diff, Size: 4780 bytes --]

--- gcc/ada/exp_ch5.adb
+++ gcc/ada/exp_ch5.adb
@@ -1451,20 +1451,35 @@ package body Exp_Ch5 is
    begin
       --  Determine whether Copy_Bitfield is appropriate (will work, and will
       --  be more efficient than component-by-component copy). Copy_Bitfield
-      --  doesn't work for reversed storage orders. It is efficient only for
-      --  slices of bit-packed arrays.
-
-      --  Note that Expand_Assign_Array_Bitfield is disabled for now
-
-      if False -- ???
+      --  doesn't work for reversed storage orders. It is efficient for slices
+      --  of bit-packed arrays. Copy_Bitfield can read and write bits that are
+      --  not part of the objects being copied, so we don't want to use it if
+      --  there are volatile or independent components. If the Prefix of the
+      --  slice is a selected component (etc, see below), then it might be a
+      --  component of an object with some other volatile or independent
+      --  components, so we disable the optimization in that case as well.
+      --  We could complicate this code by actually looking for such volatile
+      --  and independent components.
+
+      --  Note that Expand_Assign_Array_Bitfield is disabled for now.
+
+      if False and then -- ???
+        RTE_Available (RE_Copy_Bitfield)
         and then Is_Bit_Packed_Array (L_Type)
         and then Is_Bit_Packed_Array (R_Type)
-        and then RTE_Available (RE_Copy_Bitfield)
         and then not Reverse_Storage_Order (L_Type)
         and then not Reverse_Storage_Order (R_Type)
         and then Ndim = 1
         and then not Rev
         and then Slices
+        and then not Has_Volatile_Component (L_Type)
+        and then not Has_Volatile_Component (R_Type)
+        and then not Has_Independent_Components (L_Type)
+        and then not Has_Independent_Components (R_Type)
+        and then not Nkind_In (Prefix (Name (N)),
+                               N_Selected_Component,
+                               N_Indexed_Component,
+                               N_Slice)
       then
          return Expand_Assign_Array_Bitfield
            (N, Larray, Rarray, L_Type, R_Type, Rev);

--- gcc/ada/libgnat/s-bituti.adb
+++ gcc/ada/libgnat/s-bituti.adb
@@ -71,6 +71,29 @@ package body System.Bitfield_Utils is
       --  set to Src_Value. Src_Value must have high order bits (Size and
       --  above) zero. The result is returned as the function result.
 
+      procedure Copy_Small_Bitfield
+        (Src_Address  : Address;
+         Src_Offset   : Bit_Offset;
+         Dest_Address : Address;
+         Dest_Offset  : Bit_Offset;
+         Size         : Small_Size);
+      --  Copy_Bitfield in the case where Size <= Val'Size.
+      --  The Address values must be aligned as for Val and Val_2.
+      --  This works for overlapping bit fields.
+
+      procedure Copy_Large_Bitfield
+        (Src_Address  : Address;
+         Src_Offset   : Bit_Offset;
+         Dest_Address : Address;
+         Dest_Offset  : Bit_Offset;
+         Size         : Bit_Size);
+      --  Copy_Bitfield in the case where Size > Val'Size.
+      --  The Address values must be aligned as for Val and Val_2.
+      --  This works for overlapping bit fields only if the source
+      --  bit address is greater than or equal to the destination
+      --  bit address, because it copies forward (from lower to higher
+      --  bit addresses).
+
       function Get_Bitfield
         (Src : Val_2; Src_Offset : Bit_Offset; Size : Small_Size)
          return Val
@@ -120,29 +143,6 @@ package body System.Bitfield_Utils is
          Src_Offset   : Bit_Offset;
          Dest_Address : Address;
          Dest_Offset  : Bit_Offset;
-         Size         : Small_Size);
-      --  Copy_Bitfield in the case where Size <= Val'Size.
-      --  The Address values must be aligned as for Val and Val_2.
-      --  This works for overlapping bit fields.
-
-      procedure Copy_Large_Bitfield
-        (Src_Address  : Address;
-         Src_Offset   : Bit_Offset;
-         Dest_Address : Address;
-         Dest_Offset  : Bit_Offset;
-         Size         : Bit_Size);
-      --  Copy_Bitfield in the case where Size > Val'Size.
-      --  The Address values must be aligned as for Val and Val_2.
-      --  This works for overlapping bit fields only if the source
-      --  bit address is greater than or equal to the destination
-      --  bit address, because it copies forward (from lower to higher
-      --  bit addresses).
-
-      procedure Copy_Small_Bitfield
-        (Src_Address  : Address;
-         Src_Offset   : Bit_Offset;
-         Dest_Address : Address;
-         Dest_Offset  : Bit_Offset;
          Size         : Small_Size)
       is
          Src : constant Val_2 with Import, Address => Src_Address;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-09-17  8:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-17  8:06 [Ada] Refine conditions for calling Copy_Bitfield Pierre-Marie de Rodat

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).