From 38b06e7a19d4002697117965d0bfce7ee77e1d40 Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Tue, 17 Sep 2019 07:59:11 +0000 Subject: [PATCH] [Ada] Refine conditions for calling Copy_Bitfield 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 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 | 8 +++++++ gcc/ada/exp_ch5.adb | 29 +++++++++++++++++------ gcc/ada/libgnat/s-bituti.adb | 46 ++++++++++++++++++------------------ 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index e3e274a756f..ecc67e5a376 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2019-09-17 Bob Duff + + * 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 * make.adb (Scan_Make_Arg): Also accept `--sysroot=' for the diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb index ba0b793132f..6ef3fb2c4a5 100644 --- a/gcc/ada/exp_ch5.adb +++ b/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); diff --git a/gcc/ada/libgnat/s-bituti.adb b/gcc/ada/libgnat/s-bituti.adb index 78e391b9626..511dc571487 100644 --- a/gcc/ada/libgnat/s-bituti.adb +++ b/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 @@ -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; -- 2.30.2