[Ada] Refine conditions for calling Copy_Bitfield
authorBob Duff <duff@adacore.com>
Tue, 17 Sep 2019 07:59:11 +0000 (07:59 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Tue, 17 Sep 2019 07:59:11 +0000 (07:59 +0000)
Avoid calling Copy_Bitfield if there are volatile or independent
components that might be read or written. The test is conservative.

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.

From-SVN: r275768

gcc/ada/ChangeLog
gcc/ada/exp_ch5.adb
gcc/ada/libgnat/s-bituti.adb

index e3e274a756fb04b3360d94f3650e567e8a094fb5..ecc67e5a376420ac89ee236c5b8d052b84c66999 100644 (file)
@@ -1,3 +1,11 @@
+2019-09-17  Bob Duff  <duff@adacore.com>
+
+       * 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.
+
 2019-09-13  Maciej W. Rozycki  <macro@wdc.com>
 
        * make.adb (Scan_Make_Arg): Also accept `--sysroot=' for the 
index ba0b793132f907a7c8fa7236b238e3a0c63695b1..6ef3fb2c4a53250887502be96e22e6ea28cc60ea 100644 (file)
@@ -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);
index 78e391b9626a226d164d72a115ca9f2fa1a59adc..511dc5714879b82b6d2464803036cc7dda646aac 100644 (file)
@@ -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
@@ -115,29 +138,6 @@ package body System.Bitfield_Utils is
          return Result;
       end Set_Bitfield;
 
-      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).
-
       procedure Copy_Small_Bitfield
         (Src_Address  : Address;
          Src_Offset   : Bit_Offset;