From patchwork Tue Sep 5 09:28:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 810050 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-461469-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ramMUHg6"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xmhGz6bM5z9s0g for ; Tue, 5 Sep 2017 19:28:43 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=PvNmyu5dR+G+x6+h ImSw6DH6qmOSzTu4+SzgR5Tzb+co1ZNULvR7445R3J41/1LOXsQqN0xyx53SritT olgWAfKmrbNlEt96EHalyLWuy6mQPvYJ402AfvLqVC/D7CmselwmpTh4ODW0J/Fr E3Enkhc0aLtMTKjAFuOdDTq+Rlk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=F38S843Pfluc3uCrIFwpMo sN1nY=; b=ramMUHg6Dt9tNiQgt4IVs3PtGn/2lOOPleWi+Krb4nlD4wP8zaczDn v3vMU24xJrRxBDA9ZhNyw2SoPxckajrW8moP+zkf/T2csF2VT/cWAiDvAbV9NFSD cdaaDTTRnaRojTIpUoNpVWssDf3tAPp8XciKcVba09AVG0LCZ/Q8w= Received: (qmail 51229 invoked by alias); 5 Sep 2017 09:28:33 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 51213 invoked by uid 89); 5 Sep 2017 09:28:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=spoiling X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Sep 2017 09:28:26 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id BD3FB822CA for ; Tue, 5 Sep 2017 11:28:24 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Z6t5kA-xIstY for ; Tue, 5 Sep 2017 11:28:24 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 85D3582266 for ; Tue, 5 Sep 2017 11:28:24 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [Ada] Get rid of call to int->fp conversion routine Date: Tue, 05 Sep 2017 11:28:23 +0200 Message-ID: <4454405.H4XkRasZJl@polaris> User-Agent: KMail/4.14.10 (Linux/3.16.7-53-desktop; KDE/4.14.9; x86_64; ; ) MIME-Version: 1.0 Tested on x86_64-suse-linux, applied on mainline. 2017-09-05 Eric Botcazou * gcc-interface/trans.c (convert_with_check): Use a custom base type if the base type of the expression has a different machine mode. Rename a couple of parameters and local variable. Index: gcc-interface/trans.c =================================================================== --- gcc-interface/trans.c (revision 251704) +++ gcc-interface/trans.c (working copy) @@ -9252,63 +9252,71 @@ emit_check (tree gnu_cond, tree gnu_expr /* Return an expression that converts GNU_EXPR to GNAT_TYPE, doing overflow checks if OVERFLOW_P is true and range checks if RANGE_P is true. - GNAT_TYPE is known to be an integral type. If TRUNCATE_P true, do a - float to integer conversion with truncation; otherwise round. - GNAT_NODE is the GNAT node conveying the source location for which the - error should be signaled. */ + If TRUNCATE_P true, do a float-to-integer conversion with truncation, + otherwise round. GNAT_NODE is the GNAT node conveying the source location + for which the error should be signaled. */ static tree -convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflowp, - bool rangep, bool truncatep, Node_Id gnat_node) +convert_with_check (Entity_Id gnat_type, tree gnu_expr, bool overflow_p, + bool range_p, bool truncate_p, Node_Id gnat_node) { tree gnu_type = get_unpadded_type (gnat_type); - tree gnu_in_type = TREE_TYPE (gnu_expr); - tree gnu_in_basetype = get_base_type (gnu_in_type); tree gnu_base_type = get_base_type (gnu_type); + tree gnu_in_type = TREE_TYPE (gnu_expr); + tree gnu_in_base_type = get_base_type (gnu_in_type); tree gnu_result = gnu_expr; /* If we are not doing any checks, the output is an integral type and the input is not a floating-point type, just do the conversion. This is required for packed array types and is simpler in all cases anyway. */ - if (!rangep - && !overflowp + if (!range_p + && !overflow_p && INTEGRAL_TYPE_P (gnu_base_type) - && !FLOAT_TYPE_P (gnu_in_type)) + && !FLOAT_TYPE_P (gnu_in_base_type)) return convert (gnu_type, gnu_expr); - /* First convert the expression to its base type. This - will never generate code, but makes the tests below much simpler. - But don't do this if converting from an integer type to an unconstrained - array type since then we need to get the bounds from the original - (unpacked) type. */ + /* If the mode of the input base type is larger, then converting to it below + may pessimize the final conversion step, for example generate a libcall + instead of a simple instruction, so use a narrower type in this case. */ + if (TYPE_MODE (gnu_in_base_type) != TYPE_MODE (gnu_in_type) + && !(TREE_CODE (gnu_in_type) == INTEGER_TYPE + && TYPE_BIASED_REPRESENTATION_P (gnu_in_type))) + gnu_in_base_type = gnat_type_for_mode (TYPE_MODE (gnu_in_type), + TYPE_UNSIGNED (gnu_in_type)); + + /* First convert the expression to the base type. This will never generate + code, but makes the tests below simpler. But don't do this if converting + from an integer type to an unconstrained array type since then we need to + get the bounds from the original (unpacked) type. */ if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE) - gnu_result = convert (gnu_in_basetype, gnu_result); + gnu_result = convert (gnu_in_base_type, gnu_result); - /* If overflow checks are requested, we need to be sure the result will - fit in the output base type. But don't do this if the input - is integer and the output floating-point. */ - if (overflowp - && !(FLOAT_TYPE_P (gnu_base_type) && INTEGRAL_TYPE_P (gnu_in_basetype))) + /* If overflow checks are requested, we need to be sure the result will fit + in the output base type. But don't do this if the input is integer and + the output floating-point. */ + if (overflow_p + && !(FLOAT_TYPE_P (gnu_base_type) && INTEGRAL_TYPE_P (gnu_in_base_type))) { /* Ensure GNU_EXPR only gets evaluated once. */ tree gnu_input = gnat_protect_expr (gnu_result); tree gnu_cond = boolean_false_node; - tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_basetype); - tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_basetype); + tree gnu_in_lb = TYPE_MIN_VALUE (gnu_in_base_type); + tree gnu_in_ub = TYPE_MAX_VALUE (gnu_in_base_type); tree gnu_out_lb = TYPE_MIN_VALUE (gnu_base_type); tree gnu_out_ub = TYPE_MAX_VALUE (gnu_base_type); /* Convert the lower bounds to signed types, so we're sure we're comparing them properly. Likewise, convert the upper bounds to unsigned types. */ - if (INTEGRAL_TYPE_P (gnu_in_basetype) && TYPE_UNSIGNED (gnu_in_basetype)) + if (INTEGRAL_TYPE_P (gnu_in_base_type) + && TYPE_UNSIGNED (gnu_in_base_type)) gnu_in_lb - = convert (gnat_signed_type_for (gnu_in_basetype), gnu_in_lb); + = convert (gnat_signed_type_for (gnu_in_base_type), gnu_in_lb); - if (INTEGRAL_TYPE_P (gnu_in_basetype) - && !TYPE_UNSIGNED (gnu_in_basetype)) + if (INTEGRAL_TYPE_P (gnu_in_base_type) + && !TYPE_UNSIGNED (gnu_in_base_type)) gnu_in_ub - = convert (gnat_unsigned_type_for (gnu_in_basetype), gnu_in_ub); + = convert (gnat_unsigned_type_for (gnu_in_base_type), gnu_in_ub); if (INTEGRAL_TYPE_P (gnu_base_type) && TYPE_UNSIGNED (gnu_base_type)) gnu_out_lb @@ -9328,7 +9336,7 @@ convert_with_check (Entity_Id gnat_type, Note that we have to do the comparison which would *fail* in the case of an error since if it's an FP comparison and one of the values is a NaN or Inf, the comparison will fail. */ - if (INTEGRAL_TYPE_P (gnu_in_basetype) + if (INTEGRAL_TYPE_P (gnu_in_base_type) ? tree_int_cst_lt (gnu_in_lb, gnu_out_lb) : (FLOAT_TYPE_P (gnu_base_type) ? real_less (&TREE_REAL_CST (gnu_in_lb), @@ -9337,10 +9345,10 @@ convert_with_check (Entity_Id gnat_type, gnu_cond = invert_truthvalue (build_binary_op (GE_EXPR, boolean_type_node, - gnu_input, convert (gnu_in_basetype, + gnu_input, convert (gnu_in_base_type, gnu_out_lb))); - if (INTEGRAL_TYPE_P (gnu_in_basetype) + if (INTEGRAL_TYPE_P (gnu_in_base_type) ? tree_int_cst_lt (gnu_out_ub, gnu_in_ub) : (FLOAT_TYPE_P (gnu_base_type) ? real_less (&TREE_REAL_CST (gnu_out_ub), @@ -9351,7 +9359,7 @@ convert_with_check (Entity_Id gnat_type, invert_truthvalue (build_binary_op (LE_EXPR, boolean_type_node, gnu_input, - convert (gnu_in_basetype, + convert (gnu_in_base_type, gnu_out_ub)))); if (!integer_zerop (gnu_cond)) @@ -9362,8 +9370,8 @@ convert_with_check (Entity_Id gnat_type, /* Now convert to the result base type. If this is a non-truncating float-to-integer conversion, round. */ if (INTEGRAL_TYPE_P (gnu_base_type) - && FLOAT_TYPE_P (gnu_in_basetype) - && !truncatep) + && FLOAT_TYPE_P (gnu_in_base_type) + && !truncate_p) { REAL_VALUE_TYPE half_minus_pred_half, pred_half; tree gnu_conv, gnu_zero, gnu_comp, calc_type; @@ -9375,7 +9383,7 @@ convert_with_check (Entity_Id gnat_type, precision from spoiling this property, use the widest hardware floating-point type if FP_ARITH_MAY_WIDEN is true. */ calc_type - = fp_arith_may_widen ? longest_float_type_node : gnu_in_basetype; + = fp_arith_may_widen ? longest_float_type_node : gnu_in_base_type; /* Compute the exact value calc_type'Pred (0.5) at compile time. */ fmt = REAL_MODE_FORMAT (TYPE_MODE (calc_type)); @@ -9400,7 +9408,7 @@ convert_with_check (Entity_Id gnat_type, to be scheduled in parallel with retrieval of the constant and conversion of the input to the calc_type (if necessary). */ - gnu_zero = build_real (gnu_in_basetype, dconst0); + gnu_zero = build_real (gnu_in_base_type, dconst0); gnu_result = gnat_protect_expr (gnu_result); gnu_conv = convert (calc_type, gnu_result); gnu_comp @@ -9422,9 +9430,10 @@ convert_with_check (Entity_Id gnat_type, /* Finally, do the range check if requested. Note that if the result type is a modular type, the range check is actually an overflow check. */ - if (rangep - || (TREE_CODE (gnu_base_type) == INTEGER_TYPE - && TYPE_MODULAR_P (gnu_base_type) && overflowp)) + if (range_p + || (overflow_p + && TREE_CODE (gnu_base_type) == INTEGER_TYPE + && TYPE_MODULAR_P (gnu_base_type))) gnu_result = emit_range_check (gnu_result, gnat_type, gnat_node); return convert (gnu_type, gnu_result);