From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1914) id 857D73836010; Tue, 10 May 2022 08:23:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 857D73836010 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Pierre-Marie de Rodat To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-251] [Ada] Optimize nonstandard boolean conversions X-Act-Checkin: gcc X-Git-Author: Alexandre Oliva X-Git-Refname: refs/heads/master X-Git-Oldrev: 81d33c5c9211dd65b2ffd29424e403582e4542f9 X-Git-Newrev: bf687b8085403b94209269e15491f286644ec10b Message-Id: <20220510082304.857D73836010@sourceware.org> Date: Tue, 10 May 2022 08:23:04 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 10 May 2022 08:23:04 -0000 https://gcc.gnu.org/g:bf687b8085403b94209269e15491f286644ec10b commit r13-251-gbf687b8085403b94209269e15491f286644ec10b Author: Alexandre Oliva Date: Wed Dec 29 04:10:46 2021 -0300 [Ada] Optimize nonstandard boolean conversions This patch improves the generated code for nonstandard boolean types. One of the improvements extends the code that avoids converting back to the nonstandard boolean type an expression computed as standard boolean, when it will be converted to a(nother) nonstandard boolean type. The other improvement involves using the literal representation constants in an If_Expression instead of dereferencing the T'Val array when converting to a (nonstandard) boolean type. Avoiding the array dereference enables the compiler middle-end to propagate the constants and perform optimizations based on them, to the point of obviating the improvement above. Unfortunately, the code generated with this alternate expansion tends to be slightly larger if it turns out to not enable any further optimization, though it's most certainly faster, especially on targets with conditional moves, more so if "store flag" is slow, as on x86. Still, the array dereference is more straightforward and shorter, so I've arranged for this alternate expansion to be used only when optimizing for speed. gcc/ada/ * exp_util.adb (Adjust_Result_Type): Leave result in Standard.Boolean if it's going to be converted to another boolean type. * exp_ch4.adb (Expand_N_Type_Conversion): When optimizing, convert to nonstandard booleans with an if_expression with boolean literals. Diff: --- gcc/ada/exp_ch4.adb | 37 +++++++++++++++++++++++++++---------- gcc/ada/exp_util.adb | 3 +++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb index 98ce797be68..f827fb037f9 100644 --- a/gcc/ada/exp_ch4.adb +++ b/gcc/ada/exp_ch4.adb @@ -12757,18 +12757,35 @@ package body Exp_Ch4 is if not Has_Compatible_Representation (Target_Type, Operand_Type) and then not Conversion_OK (N) then + if Optimization_Level > 0 + and then Is_Boolean_Type (Target_Type) + then + -- Convert x(y) to (if y then x'(True) else x'(False)). + -- Use literals, instead of indexing x'val, to enable + -- further optimizations in the middle-end. - -- Convert: x(y) to x'val (ytyp'pos (y)) + Rewrite (N, + Make_If_Expression (Loc, + Expressions => New_List ( + Operand, + Convert_To (Target_Type, + New_Occurrence_Of (Standard_True, Loc)), + Convert_To (Target_Type, + New_Occurrence_Of (Standard_False, Loc))))); - Rewrite (N, - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Target_Type, Loc), - Attribute_Name => Name_Val, - Expressions => New_List ( - Make_Attribute_Reference (Loc, - Prefix => New_Occurrence_Of (Operand_Type, Loc), - Attribute_Name => Name_Pos, - Expressions => New_List (Operand))))); + else + -- Convert: x(y) to x'val (ytyp'pos (y)) + + Rewrite (N, + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Target_Type, Loc), + Attribute_Name => Name_Val, + Expressions => New_List ( + Make_Attribute_Reference (Loc, + Prefix => New_Occurrence_Of (Operand_Type, Loc), + Attribute_Name => Name_Pos, + Expressions => New_List (Operand))))); + end if; Analyze_And_Resolve (N, Target_Type); end if; diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb index c28723c35e0..795c1b082f7 100644 --- a/gcc/ada/exp_util.adb +++ b/gcc/ada/exp_util.adb @@ -424,6 +424,9 @@ package body Exp_Util is elsif KP in N_Op_Boolean or else KP in N_Short_Circuit or else KP = N_Op_Not + or else (KP in N_Type_Conversion + | N_Unchecked_Type_Conversion + and then Is_Boolean_Type (Etype (Parent (N)))) then return;