From patchwork Thu Mar 15 19:01:51 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Janne Blomqvist X-Patchwork-Id: 147062 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id AE083B6EEE for ; Fri, 16 Mar 2012 06:02:24 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1332442945; h=Comment: DomainKey-Signature:Received:Received:Received:Received: MIME-Version:Received:Received:Date:Message-ID:Subject:From:To: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=JfJ+m7R I3T0cQSfcQumxvrdueUA=; b=lxZGglUeX5PJP27mC170kRLoJY46z/nMDazoy84 bkyq4Gutl52beHJ15RngcE0N9LFBm3VW9tS+wK7mq92xKKs+9G6M3sCP3YaQ7R9i stzeOc71SzKorNwIN59a9qkGD1Lqj3xDu+mnLyoZwHb9fzJ6Wv84uOm97KNSNq1j s+j4= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:MIME-Version:Received:Received:Date:Message-ID:Subject:From:To:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=Pt+KDPTINiLoRDaFmi4orFNQhKDF2BdMz78xtcBA20nE4x7O8bPGG1IzsrfREK WcdxW0vbio/o6geEDHUBfNtMDb8phddRmf//0AxKadoPeYxkGto3ygAAEMRSPtTF SHGA+snp0FEJE01X+V54NgNsJrJgbF2+Nuizyflu5kp2I=; Received: (qmail 22885 invoked by alias); 15 Mar 2012 19:02:19 -0000 Received: (qmail 22859 invoked by uid 22791); 15 Mar 2012 19:02:17 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, TW_VT X-Spam-Check-By: sourceware.org Received: from mail-lpp01m010-f47.google.com (HELO mail-lpp01m010-f47.google.com) (209.85.215.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 15 Mar 2012 19:01:54 +0000 Received: by lagw12 with SMTP id w12so2978234lag.20 for ; Thu, 15 Mar 2012 12:01:51 -0700 (PDT) MIME-Version: 1.0 Received: by 10.152.146.163 with SMTP id td3mr5770191lab.31.1331838111900; Thu, 15 Mar 2012 12:01:51 -0700 (PDT) Received: by 10.152.129.105 with HTTP; Thu, 15 Mar 2012 12:01:51 -0700 (PDT) Date: Thu, 15 Mar 2012 21:01:51 +0200 Message-ID: Subject: [Patch, fortran] Use BUILT_IN_IROUND From: Janne Blomqvist To: Fortran List , GCC Patches 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 Hi, since some time GCC has BUILT_IN_IROUND{F,,L}, similar to lround() and llround() but the result is returned as an integer. As there is no corresponding libc function, this builtin is expanded to lround{f,l} except when -ffast-math is used, in which case it enables slightly shorter and faster code to be generated inline. Attached patch enables this builtin in the gfortran frontend. For the testcase function my_nint(x) implicit none real :: x integer :: my_nint my_nint = nint(x) end function my_nint compiled with "-O2 -ffast-math" on x86-64, the difference between the assembler output of trunk and trunk+patch: Comparing the size of the object files, in the patched version the text section is one byte shorter. Regtested on x86_64-unknown-linux-gnu, Ok for trunk? (As an aside, there were some recent problems with __builtin_iround(), see PR 52592, but they seem to be fixed now so I think this should be safe) 2012-03-15 Janne Blomqvist * f95-lang.c (gfc_init_builtin_functions): Initialize BUILT_IN_IROUND. * mathbuiltins.def: Add IROUND. * trans-intrinsic.c (build_round_expr): Use BUILT_IN_IROUND if type size matches. (gfc_build_intrinsic_lib_fndecls): Build iround functions. diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index 05b598f..3f28e67 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -773,7 +773,11 @@ gfc_init_builtin_functions (void) gfc_define_builtin ("__builtin_fmodf", mfunc_float[1], BUILT_IN_FMODF, "fmodf", ATTR_CONST_NOTHROW_LEAF_LIST); - /* lround{f,,l} and llround{f,,l} */ + /* iround{f,,l}, lround{f,,l} and llround{f,,l} */ + ftype = build_function_type_list (integer_type_node, + float_type_node, NULL_TREE); + gfc_define_builtin("__builtin_iroundf", ftype, BUILT_IN_IROUNDF, + "iroundf", ATTR_CONST_NOTHROW_LEAF_LIST); ftype = build_function_type_list (long_integer_type_node, float_type_node, NULL_TREE); gfc_define_builtin ("__builtin_lroundf", ftype, BUILT_IN_LROUNDF, @@ -783,6 +787,10 @@ gfc_init_builtin_functions (void) gfc_define_builtin ("__builtin_llroundf", ftype, BUILT_IN_LLROUNDF, "llroundf", ATTR_CONST_NOTHROW_LEAF_LIST); + ftype = build_function_type_list (integer_type_node, + double_type_node, NULL_TREE); + gfc_define_builtin("__builtin_iround", ftype, BUILT_IN_IROUND, + "iround", ATTR_CONST_NOTHROW_LEAF_LIST); ftype = build_function_type_list (long_integer_type_node, double_type_node, NULL_TREE); gfc_define_builtin ("__builtin_lround", ftype, BUILT_IN_LROUND, @@ -792,6 +800,10 @@ gfc_init_builtin_functions (void) gfc_define_builtin ("__builtin_llround", ftype, BUILT_IN_LLROUND, "llround", ATTR_CONST_NOTHROW_LEAF_LIST); + ftype = build_function_type_list (integer_type_node, + long_double_type_node, NULL_TREE); + gfc_define_builtin("__builtin_iroundl", ftype, BUILT_IN_IROUNDL, + "iroundl", ATTR_CONST_NOTHROW_LEAF_LIST); ftype = build_function_type_list (long_integer_type_node, long_double_type_node, NULL_TREE); gfc_define_builtin ("__builtin_lroundl", ftype, BUILT_IN_LROUNDL, diff --git a/gcc/fortran/mathbuiltins.def b/gcc/fortran/mathbuiltins.def index b0bcc1f..f6d9586 100644 --- a/gcc/fortran/mathbuiltins.def +++ b/gcc/fortran/mathbuiltins.def @@ -64,6 +64,7 @@ OTHER_BUILTIN (FMOD, "fmod", 2, true) OTHER_BUILTIN (FREXP, "frexp", frexp, false) OTHER_BUILTIN (LLROUND, "llround", llround, true) OTHER_BUILTIN (LROUND, "lround", lround, true) +OTHER_BUILTIN (IROUND, "iround", iround, true) OTHER_BUILTIN (NEXTAFTER, "nextafter", 2, true) OTHER_BUILTIN (POW, "pow", 1, true) OTHER_BUILTIN (ROUND, "round", 1, true) diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index ac9f507..5e54d8e 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -376,28 +376,24 @@ build_round_expr (tree arg, tree restype) { tree argtype; tree fn; - bool longlong; int argprec, resprec; argtype = TREE_TYPE (arg); argprec = TYPE_PRECISION (argtype); resprec = TYPE_PRECISION (restype); - /* Depending on the type of the result, choose the long int intrinsic - (lround family) or long long intrinsic (llround). We might also - need to convert the result afterwards. */ - if (resprec <= LONG_TYPE_SIZE) - longlong = false; + /* Depending on the type of the result, choose the int intrinsic + (iround, available only as a builtin), long int intrinsic (lround + family) or long long intrinsic (llround). We might also need to + convert the result afterwards. */ + if (resprec <= INT_TYPE_SIZE) + fn = builtin_decl_for_precision (BUILT_IN_IROUND, argprec); + else if (resprec <= LONG_TYPE_SIZE) + fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec); else if (resprec <= LONG_LONG_TYPE_SIZE) - longlong = true; - else - gcc_unreachable (); - - /* Now, depending on the argument type, we choose between intrinsics. */ - if (longlong) fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec); else - fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec); + gcc_unreachable (); return fold_convert (restype, build_call_expr_loc (input_location, fn, 1, arg)); @@ -623,7 +619,7 @@ gfc_build_intrinsic_lib_fndecls (void) q-suffixed functions. */ tree type, complex_type, func_1, func_2, func_cabs, func_frexp; - tree func_lround, func_llround, func_scalbn, func_cpow; + tree func_iround, func_lround, func_llround, func_scalbn, func_cpow; memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1)); @@ -631,6 +627,9 @@ gfc_build_intrinsic_lib_fndecls (void) complex_type = complex_float128_type_node; /* type (*) (type) */ func_1 = build_function_type_list (type, type, NULL_TREE); + /* int (*) (type) */ + func_iround = build_function_type_list (integer_type_node, + type, NULL_TREE); /* long (*) (type) */ func_lround = build_function_type_list (long_integer_type_node, type, NULL_TREE);