aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2023-06-26 20:33:53 +0200
committerMarc Poulhiès <poulhies@adacore.com>2023-07-04 10:08:29 +0200
commit65ea0024063eaa9623c8309edbe22e042325b7ea (patch)
tree425f7f0b07517e2d4f52f377c9066bee8feec7ce /gcc
parent2e80be632bfd09987425cb0bdd271659673e1e43 (diff)
downloadgcc-65ea0024063eaa9623c8309edbe22e042325b7ea.zip
gcc-65ea0024063eaa9623c8309edbe22e042325b7ea.tar.gz
gcc-65ea0024063eaa9623c8309edbe22e042325b7ea.tar.bz2
ada: Do not unnecessarily use component-wise loop for slice assignment
This relaxes the condition under which Expand_Assign_Array leaves the assignment to or from an array slice untouched. The main prerequisite for the code generator is that everything be aligned on byte boundaries and Is_Possibly_Unaligned_Slice is too strong a predicate for this, so it is replaced by the combination of Possible_Bit_Aligned_Component and Is_Bit_Packed_Array, modulo a change to Possible_Bit_Aligned_Component to take into account the specific case of slices. gcc/ada/ * exp_ch5.adb (Expand_Assign_Array): Adjust comment above the calls to Possible_Bit_Aligned_Component on the LHS and RHS. Do not call Is_Possibly_Unaligned_Slice in the slice case. * exp_util.ads (Component_May_Be_Bit_Aligned): Add For_Slice boolean parameter. (Possible_Bit_Aligned_Component): Likewise. * exp_util.adb (Component_May_Be_Bit_Aligned): Do not return False for the slice of a small record or bit-packed array component. (Possible_Bit_Aligned_Component): Pass For_Slice in recursive calls, except in the slice case where True is passed, as well as in call to Component_May_Be_Bit_Aligned.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ada/exp_ch5.adb8
-rw-r--r--gcc/ada/exp_util.adb33
-rw-r--r--gcc/ada/exp_util.ads17
3 files changed, 31 insertions, 27 deletions
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index 258459b..d55fdb3 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -524,7 +524,7 @@ package body Exp_Ch5 is
R_Type := Get_Actual_Subtype (Act_Rhs);
Loop_Required := True;
- -- We require a loop if the left side is possibly bit unaligned
+ -- We require a loop if either side is possibly bit aligned
elsif Possible_Bit_Aligned_Component (Lhs)
or else
@@ -682,14 +682,10 @@ package body Exp_Ch5 is
return;
-- If either operand is bit packed, then we need a loop, since we can't
- -- be sure that the slice is byte aligned. Similarly, if either operand
- -- is a possibly unaligned slice, then we need a loop (since the back
- -- end cannot handle unaligned slices).
+ -- be sure that the slice is byte aligned.
elsif Is_Bit_Packed_Array (L_Type)
or else Is_Bit_Packed_Array (R_Type)
- or else Is_Possibly_Unaligned_Slice (Lhs)
- or else Is_Possibly_Unaligned_Slice (Rhs)
then
Loop_Required := True;
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 0d0ad8a..c74921e 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -4959,7 +4959,10 @@ package body Exp_Util is
-- Component_May_Be_Bit_Aligned --
----------------------------------
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean is
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
UT : Entity_Id;
begin
@@ -4980,11 +4983,12 @@ package body Exp_Util is
-- If we know that we have a small (at most the maximum integer size)
-- record or bit-packed array, then everything is fine, since the back
- -- end can handle these cases correctly.
+ -- end can handle these cases correctly, except if a slice is involved.
elsif Known_Esize (Comp)
and then Esize (Comp) <= System_Max_Integer_Size
and then (Is_Record_Type (UT) or else Is_Bit_Packed_Array (UT))
+ and then not For_Slice
then
return False;
@@ -11318,7 +11322,10 @@ package body Exp_Util is
-- Possible_Bit_Aligned_Component --
------------------------------------
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean is
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean
+ is
begin
-- Do not process an unanalyzed node because it is not yet decorated and
-- most checks performed below will fail.
@@ -11356,7 +11363,7 @@ package body Exp_Util is
-- indexing from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
@@ -11371,14 +11378,14 @@ package body Exp_Util is
-- This is the crucial test: if the component itself causes
-- trouble, then we can stop and return True.
- if Component_May_Be_Bit_Aligned (Comp) then
+ if Component_May_Be_Bit_Aligned (Comp, For_Slice) then
return True;
-- Otherwise, we need to test the prefix, to see if we are
-- selecting from a possibly unaligned component.
else
- return Possible_Bit_Aligned_Component (P);
+ return Possible_Bit_Aligned_Component (P, For_Slice);
end if;
end;
@@ -11386,13 +11393,13 @@ package body Exp_Util is
-- then for sure the slice is.
when N_Slice =>
- return Possible_Bit_Aligned_Component (Prefix (N));
+ return Possible_Bit_Aligned_Component (Prefix (N), True);
-- For an unchecked conversion, check whether the expression may
-- be bit aligned.
when N_Unchecked_Type_Conversion =>
- return Possible_Bit_Aligned_Component (Expression (N));
+ return Possible_Bit_Aligned_Component (Expression (N), For_Slice);
-- If we have none of the above, it means that we have fallen off the
-- top testing prefixes recursively, and we now have a stand alone
@@ -11400,15 +11407,11 @@ package body Exp_Util is
-- in which case we need to look into the renamed object.
when others =>
- if Is_Entity_Name (N)
+ return Is_Entity_Name (N)
and then Is_Object (Entity (N))
and then Present (Renamed_Object (Entity (N)))
- then
- return
- Possible_Bit_Aligned_Component (Renamed_Object (Entity (N)));
- else
- return False;
- end if;
+ and then Possible_Bit_Aligned_Component
+ (Renamed_Object (Entity (N)), For_Slice);
end case;
end Possible_Bit_Aligned_Component;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 02324d23..65bb920 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -399,16 +399,19 @@ package Exp_Util is
-- since for floating-point, abs, unary "-", and unary "+" can never
-- case overflow.
- function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean;
+ function Component_May_Be_Bit_Aligned
+ (Comp : Entity_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is in charge of detecting record components that may cause
- -- trouble for the back end if an attempt is made to access the component
- -- as a whole. The back end can handle such accesses with no problem if the
- -- components involved are small (64 bits or less) records or scalar items
+ -- trouble for the back end if an attempt is made to access the component,
+ -- either as a whole if For_Slice is False, or through an array slice if
+ -- For_Slice is True. The back end can handle such accesses only if the
+ -- components involved are small (64/128 bits or less) records or scalars
-- (including bit-packed arrays represented with a modular type), or else
-- if they are aligned on byte boundaries (i.e. starting on a byte boundary
-- and occupying an integral number of bytes).
--
- -- However, problems arise for records larger than 64 bits, or for arrays
+ -- However problems arise for records larger than 64/128 bits or for arrays
-- (other than bit-packed arrays represented with a modular type) if the
-- component either does not start on a byte boundary or does not occupy an
-- integral number of bytes (i.e. there are some bits possibly shared with
@@ -998,7 +1001,9 @@ package Exp_Util is
-- address might be captured in a way we do not detect. A value of True is
-- returned only if the replacement is safe.
- function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean;
+ function Possible_Bit_Aligned_Component
+ (N : Node_Id;
+ For_Slice : Boolean := False) return Boolean;
-- This function is used during processing the assignment of a record or an
-- array, or the construction of an aggregate. The argument N is either the
-- left or the right hand side of an assignment and the function determines