From patchwork Sun Jun 10 12:50:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 927335 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-479405-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=netcologne.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="nsaDwybr"; 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 413bcR6YQhz9rvt for ; Sun, 10 Jun 2018 22:51:18 +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:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=xKQCwjc/E8cKm+1VFcfN8+ysi8J+/4cptJvUwlYpfqYDOE7gR6 O1sMtRYEhjFecWiy6YeY00aq1OUjEmSd/QckwsU56A4R7eQsfJhfT6ghP2qEjozQ i5O2Bfi5wsoZxgnFULjm0TwCqCbg6XwdYJSLqaWKcsCj4rLXjIUY6+AWA= 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:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=zWfWfPPRqaNpmkc3gluNGMbooXo=; b=nsaDwybrvLWt6r2Dgm+Z kmFpyJLtK+oHaTfwDO0TmLAs/D1me9Ogzot21R0O4ZoaAxZrf4hDPCGZZe7YmAFt IVNoGdGPdqdeY0nq/LuGSe0qm4DPfJ3gyj9VJPXPiQJZupr1a6S+V35u11rFElm+ pnxaZFQWLLtNUeiZhUdyRww= Received: (qmail 81718 invoked by alias); 10 Jun 2018 12:51:03 -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 81604 invoked by uid 89); 10 Jun 2018 12:51:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=desire, se, associate, Associate X-Spam-User: qpsmtpd, 2 recipients X-HELO: cc-smtpout3.netcologne.de Received: from cc-smtpout3.netcologne.de (HELO cc-smtpout3.netcologne.de) (89.1.8.213) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 10 Jun 2018 12:51:00 +0000 Received: from cc-smtpin1.netcologne.de (cc-smtpin1.netcologne.de [89.1.8.201]) by cc-smtpout3.netcologne.de (Postfix) with ESMTP id D0ECA12654; Sun, 10 Jun 2018 14:50:57 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by cc-smtpin1.netcologne.de (Postfix) with ESMTP id C51CB11DC9; Sun, 10 Jun 2018 14:50:57 +0200 (CEST) Received: from [78.35.152.204] (helo=cc-smtpin1.netcologne.de) by localhost with ESMTP (eXpurgate 4.1.9) (envelope-from ) id 5b1d1eb1-029d-7f0000012729-7f00000181ed-1 for ; Sun, 10 Jun 2018 14:50:57 +0200 Received: from [192.168.178.68] (xdsl-78-35-152-204.netcologne.de [78.35.152.204]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by cc-smtpin1.netcologne.de (Postfix) with ESMTPSA; Sun, 10 Jun 2018 14:50:56 +0200 (CEST) To: "fortran@gcc.gnu.org" , gcc-patches From: Thomas Koenig Subject: [patch, fortran] Remove bounds checking in DO loops for inline matmul Message-ID: <3c202f86-fbfb-f072-6e9d-b365a70eafff@netcologne.de> Date: Sun, 10 Jun 2018 14:50:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 Hello world, the attached patch was motivated by the desire to reduce the runtime of programs with -fcheck=bounds with (some) optimization, in order to make debugging less time consuming. This patch removes the run-time bounds checks with -fcheck=bounds in the DO loops created by matmul inlining. The Necessary checks are already performed outside the loop, so the inner tests are not needed. OK for trunk? Regards Thomas 2018-06-10 Thomas Koenig * gfortran.h (gfc_expr): Add no_bounds_check field. * frontend-passes.c (get_array_inq_function): Set no_bounds_check on function and function argument. (inline_matmul_assign): Set no_bounds_check on zero expression and on lhs of zero expression. Also handle A1B2 case if realloc on assigment is active. * trans-array.c (gfc_conv_array_ref): Don't do range checking if expr has no_bounds_check set. (gfc_conv_expr_descriptor): Set no_bounds_check on ss if expr has it set. * trans-expr.c (gfc_trans_assignment_1): Set no_bounds_check on lss and lss if the corresponding expressions have it set. 2018-06-10 Thomas Koenig * gfortran.dg/inline_matmul_23.f90: New test. Index: gfortran.h =================================================================== --- gfortran.h (Revision 261245) +++ gfortran.h (Arbeitskopie) @@ -2144,6 +2144,10 @@ typedef struct gfc_expr /* Will require finalization after use. */ unsigned int must_finalize : 1; + /* Set this if no range check should be performed on this expression. */ + + unsigned int no_bounds_check : 1; + /* If an expression comes from a Hollerith constant or compile-time evaluation of a transfer statement, it may have a prescribed target- memory representation, and these cannot always be backformed from Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 261248) +++ frontend-passes.c (Arbeitskopie) @@ -2938,9 +2938,14 @@ get_array_inq_function (gfc_isym_id id, gfc_expr * gfc_index_integer_kind); ec = gfc_copy_expr (e); + + /* No bounds checking, this will be done before the loops if -fcheck=bounds + is in effect. */ + ec->no_bounds_check = 1; fcn = gfc_build_intrinsic_call (current_ns, id, name, e->where, 3, ec, dim_arg, kind); gfc_simplify_expr (fcn, 0); + fcn->no_bounds_check = 1; return fcn; } @@ -3645,6 +3650,9 @@ scalarized_expr (gfc_expr *e_in, gfc_expr **index, } } + /* Bounds checking will be done before the loops if -fcheck=bounds + is in effect. */ + e->no_bounds_check = 1; return e; } @@ -3832,7 +3840,7 @@ inline_matmul_assign (gfc_code **c, int *walk_subt m_case = A1B2; } } - + if (m_case == none) return 0; @@ -3911,10 +3919,13 @@ inline_matmul_assign (gfc_code **c, int *walk_subt next_code_point = &if_limit->block->next; } + zero_e->no_bounds_check = 1; + assign_zero = XCNEW (gfc_code); assign_zero->op = EXEC_ASSIGN; assign_zero->loc = co->loc; assign_zero->expr1 = gfc_copy_expr (expr1); + assign_zero->expr1->no_bounds_check = 1; assign_zero->expr2 = zero_e; /* Handle the reallocation, if needed. */ @@ -3926,20 +3937,33 @@ inline_matmul_assign (gfc_code **c, int *walk_subt bounds checking, the rest will be allocated. Also check this for A2B1. */ - if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && (m_case == A2B2 || m_case == A2B1)) + if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) { gfc_code *test; - gfc_expr *a2, *b1; + if (m_case == A2B2 || m_case == A2B1) + { + gfc_expr *a2, *b1; - a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2); - b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1); - test = runtime_error_ne (b1, a2, "Dimension of array B incorrect " - "in MATMUL intrinsic: Is %ld, should be %ld"); - *next_code_point = test; - next_code_point = &test->next; + a2 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 2); + b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1); + test = runtime_error_ne (b1, a2, "Dimension of array B incorrect " + "in MATMUL intrinsic: Is %ld, should be %ld"); + *next_code_point = test; + next_code_point = &test->next; + } + else if (m_case == A1B2) + { + gfc_expr *a1, *b1; + + a1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_a, 1); + b1 = get_array_inq_function (GFC_ISYM_SIZE, matrix_b, 1); + test = runtime_error_ne (b1, a1, "Dimension of array B incorrect " + "in MATMUL intrinsic: Is %ld, should be %ld"); + *next_code_point = test; + next_code_point = &test->next; + } } - lhs_alloc = matmul_lhs_realloc (expr1, matrix_a, matrix_b, m_case); *next_code_point = lhs_alloc; Index: trans-array.c =================================================================== --- trans-array.c (Revision 261348) +++ trans-array.c (Arbeitskopie) @@ -3583,7 +3583,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * a gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type); gfc_add_block_to_block (&se->pre, &indexse.pre); - if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) + if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && ! expr->no_bounds_check) { /* Check array bounds. */ tree cond; @@ -7181,6 +7181,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *ex /* The right-hand side of a pointer assignment mustn't use a temporary. */ gcc_assert (!se->direct_byref); + /* Do we need bounds checking or not? */ + ss->no_bounds_check = expr->no_bounds_check; + /* Setup the scalarizing loops and bounds. */ gfc_conv_ss_startstride (&loop); Index: trans-expr.c =================================================================== --- trans-expr.c (Revision 261348) +++ trans-expr.c (Arbeitskopie) @@ -9991,6 +9991,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr || expr2->value.function.isym->conversion))) lss->is_alloc_lhs = 1; } + else + lss->no_bounds_check = expr1->no_bounds_check; rss = NULL; @@ -10045,6 +10047,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr if (is_poly_assign && expr2->rank == 0 && !UNLIMITED_POLY (expr2)) rss->info->type = GFC_SS_REFERENCE; + rss->no_bounds_check = expr2->no_bounds_check; /* Associate the SS with the loop. */ gfc_add_ss_to_loop (&loop, lss); gfc_add_ss_to_loop (&loop, rss);