[Ada] Streamline comparison for equality of 2-element arrays
In the general case, the comparison for equality of array objects is implemented by a local function that contains, among other things, a loop running over the elements, comparing them one by one and exiting as soon as an element is not the same in the two array objects. For the specific case of constrained 2-element arrays, this is rather heavy and unnecessarily obfuscates the control flow of the program, so this change implements a simple conjunction of comparisons for it. Running these commands: gcc -c p.ads -O -gnatD grep loop p.ads.dg On the following sources: package P is type Rec is record Re : Float; Im : Float; end record; type Arr is array (1 .. 2) of Rec; function Equal (A, B : Arr) return Boolean is (A = B); end P; Should execute silently. 2019-09-19 Eric Botcazou <ebotcazou@adacore.com> gcc/ada/ * exp_ch4.adb (Expand_Array_Equality): If optimization is enabled, generate a simple conjunction of comparisons for the specific case of constrained 1-dimensional 2-element arrays. Fix formatting. From-SVN: r275941
This commit is contained in:
parent
c4f372c54f
commit
1dd3915be1
|
@ -1,3 +1,10 @@
|
|||
2019-09-19 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* exp_ch4.adb (Expand_Array_Equality): If optimization is
|
||||
enabled, generate a simple conjunction of comparisons for the
|
||||
specific case of constrained 1-dimensional 2-element arrays.
|
||||
Fix formatting.
|
||||
|
||||
2019-09-19 Piotr Trojanek <trojanek@adacore.com>
|
||||
|
||||
* exp_dbug.ads, exp_dbug.adb (Get_Homonym_Number): Remove.
|
||||
|
|
|
@ -1582,7 +1582,7 @@ package body Exp_Ch4 is
|
|||
Index_List1 : constant List_Id := New_List;
|
||||
Index_List2 : constant List_Id := New_List;
|
||||
|
||||
Actuals : List_Id;
|
||||
First_Idx : Node_Id;
|
||||
Formals : List_Id;
|
||||
Func_Name : Entity_Id;
|
||||
Func_Body : Node_Id;
|
||||
|
@ -1594,6 +1594,10 @@ package body Exp_Ch4 is
|
|||
Rtyp : Entity_Id;
|
||||
-- The parameter types to be used for the formals
|
||||
|
||||
New_Lhs : Node_Id;
|
||||
New_Rhs : Node_Id;
|
||||
-- The LHS and RHS converted to the parameter types
|
||||
|
||||
function Arr_Attr
|
||||
(Arr : Entity_Id;
|
||||
Nam : Name_Id;
|
||||
|
@ -1962,6 +1966,82 @@ package body Exp_Ch4 is
|
|||
pragma Assert (Ltyp = Rtyp);
|
||||
end if;
|
||||
|
||||
-- If the array type is distinct from the type of the arguments, it
|
||||
-- is the full view of a private type. Apply an unchecked conversion
|
||||
-- to ensure that analysis of the code below succeeds.
|
||||
|
||||
if No (Etype (Lhs))
|
||||
or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
|
||||
then
|
||||
New_Lhs := OK_Convert_To (Ltyp, Lhs);
|
||||
else
|
||||
New_Lhs := Lhs;
|
||||
end if;
|
||||
|
||||
if No (Etype (Rhs))
|
||||
or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
|
||||
then
|
||||
New_Rhs := OK_Convert_To (Rtyp, Rhs);
|
||||
else
|
||||
New_Rhs := Rhs;
|
||||
end if;
|
||||
|
||||
First_Idx := First_Index (Ltyp);
|
||||
|
||||
-- If optimization is enabled and the array boils down to a couple of
|
||||
-- consecutive elements, generate a simple conjunction of comparisons
|
||||
-- which should be easier to optimize by the code generator.
|
||||
|
||||
if Optimization_Level > 0
|
||||
and then Ltyp = Rtyp
|
||||
and then Is_Constrained (Ltyp)
|
||||
and then Number_Dimensions (Ltyp) = 1
|
||||
and then Nkind (First_Idx) = N_Range
|
||||
and then Compile_Time_Known_Value (Low_Bound (First_Idx))
|
||||
and then Compile_Time_Known_Value (High_Bound (First_Idx))
|
||||
and then Expr_Value (High_Bound (First_Idx)) =
|
||||
Expr_Value (Low_Bound (First_Idx)) + 1
|
||||
then
|
||||
declare
|
||||
Ctyp : constant Entity_Id := Component_Type (Ltyp);
|
||||
L, R : Node_Id;
|
||||
TestL, TestH : Node_Id;
|
||||
Index_List : List_Id;
|
||||
|
||||
begin
|
||||
Index_List := New_List (New_Copy_Tree (Low_Bound (First_Idx)));
|
||||
|
||||
L :=
|
||||
Make_Indexed_Component (Loc,
|
||||
Prefix => New_Copy_Tree (New_Lhs),
|
||||
Expressions => Index_List);
|
||||
|
||||
R :=
|
||||
Make_Indexed_Component (Loc,
|
||||
Prefix => New_Copy_Tree (New_Rhs),
|
||||
Expressions => Index_List);
|
||||
|
||||
TestL := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);
|
||||
|
||||
Index_List := New_List (New_Copy_Tree (High_Bound (First_Idx)));
|
||||
|
||||
L :=
|
||||
Make_Indexed_Component (Loc,
|
||||
Prefix => New_Lhs,
|
||||
Expressions => Index_List);
|
||||
|
||||
R :=
|
||||
Make_Indexed_Component (Loc,
|
||||
Prefix => New_Rhs,
|
||||
Expressions => Index_List);
|
||||
|
||||
TestH := Expand_Composite_Equality (Nod, Ctyp, L, R, Bodies);
|
||||
|
||||
return
|
||||
Make_And_Then (Loc, Left_Opnd => TestL, Right_Opnd => TestH);
|
||||
end;
|
||||
end if;
|
||||
|
||||
-- Build list of formals for function
|
||||
|
||||
Formals := New_List (
|
||||
|
@ -2004,46 +2084,20 @@ package body Exp_Ch4 is
|
|||
Make_Simple_Return_Statement (Loc,
|
||||
Expression => New_Occurrence_Of (Standard_False, Loc)))),
|
||||
|
||||
Handle_One_Dimension (1, First_Index (Ltyp)),
|
||||
Handle_One_Dimension (1, First_Idx),
|
||||
|
||||
Make_Simple_Return_Statement (Loc,
|
||||
Expression => New_Occurrence_Of (Standard_True, Loc)))));
|
||||
|
||||
Set_Has_Completion (Func_Name, True);
|
||||
Set_Is_Inlined (Func_Name);
|
||||
Set_Has_Completion (Func_Name, True);
|
||||
Set_Is_Inlined (Func_Name);
|
||||
|
||||
-- If the array type is distinct from the type of the arguments, it
|
||||
-- is the full view of a private type. Apply an unchecked conversion
|
||||
-- to ensure that analysis of the call succeeds.
|
||||
Append_To (Bodies, Func_Body);
|
||||
|
||||
declare
|
||||
L, R : Node_Id;
|
||||
|
||||
begin
|
||||
L := Lhs;
|
||||
R := Rhs;
|
||||
|
||||
if No (Etype (Lhs))
|
||||
or else Base_Type (Etype (Lhs)) /= Base_Type (Ltyp)
|
||||
then
|
||||
L := OK_Convert_To (Ltyp, Lhs);
|
||||
end if;
|
||||
|
||||
if No (Etype (Rhs))
|
||||
or else Base_Type (Etype (Rhs)) /= Base_Type (Rtyp)
|
||||
then
|
||||
R := OK_Convert_To (Rtyp, Rhs);
|
||||
end if;
|
||||
|
||||
Actuals := New_List (L, R);
|
||||
end;
|
||||
|
||||
Append_To (Bodies, Func_Body);
|
||||
|
||||
return
|
||||
Make_Function_Call (Loc,
|
||||
Name => New_Occurrence_Of (Func_Name, Loc),
|
||||
Parameter_Associations => Actuals);
|
||||
return
|
||||
Make_Function_Call (Loc,
|
||||
Name => New_Occurrence_Of (Func_Name, Loc),
|
||||
Parameter_Associations => New_List (New_Lhs, New_Rhs));
|
||||
end Expand_Array_Equality;
|
||||
|
||||
-----------------------------
|
||||
|
|
Loading…
Reference in New Issue