From patchwork Thu Jul 30 16:06:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1338968 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=dVhrAKVk; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BHZzb10RXz9sRN for ; Fri, 31 Jul 2020 02:06:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D092A388C03E; Thu, 30 Jul 2020 16:06:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D092A388C03E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1596125206; bh=johHymLIbUUIW5VBalHvxbHaW6l5xpWfZtsqfRwCDl8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=dVhrAKVkvJi8JvwzpnrL+sAWNAmohVG1+6/e8WSBP8jyHY/ZO3vaQgpGJUC/JzxIN 90V2LxKGjVwj9iniW2U7GXeF5tkDTstFioqzXGpUSZhwR6XsaEXEizhHGza2Gy0qXL eNzqn3WJODGgc6GdptBN4JbCaOt6G5DLAZLi8hvY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [IPv6:2001:67c:2050::465:202]) by sourceware.org (Postfix) with ESMTPS id 4C022388A837 for ; Thu, 30 Jul 2020 16:06:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 4C022388A837 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:105:465:1:1:0]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4BHZzN51cKzQlFr; Thu, 30 Jul 2020 18:06:40 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter05.heinlein-hosting.de (spamfilter05.heinlein-hosting.de [80.241.56.123]) (amavisd-new, port 10030) with ESMTP id D_4cP4XCqlmy; Thu, 30 Jul 2020 18:06:37 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Move private functions out of ExprVisitor into local statics Date: Thu, 30 Jul 2020 18:06:35 +0200 Message-Id: <20200730160635.2514488-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: 48 X-Rspamd-Score: 7.32 / 15.00 / 15.00 X-Rspamd-Queue-Id: 91169180E X-Rspamd-UID: a1c7f0 X-Spam-Status: No, score=-16.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, TXREP, URIBL_ABUSE_SURBL autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, This patch breaks out all private functions from ExprVisitor into free standing static functions. None of them need access to the context pointer of the visitor class. Bootstrapped and regression tested on x86_64-linux-gnu, and committed to mainline. Regards Iain --- gcc/d/ChangeLog: * expr.cc (needs_postblit): Move out of ExprVisitor as a static function. Update all callers. (needs_dtor): Likewise. (lvalue_p): Likewise. (binary_op): Likewise. (binop_assignment): Likewise. --- gcc/d/expr.cc | 313 +++++++++++++++++++++++++------------------------- 1 file changed, 159 insertions(+), 154 deletions(-) diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 7a209fbe733..ac9a2820112 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -43,181 +43,186 @@ along with GCC; see the file COPYING3. If not see #include "d-tree.h" -/* Implements the visitor interface to build the GCC trees of all Expression - AST classes emitted from the D Front-end. - All visit methods accept one parameter E, which holds the frontend AST - of the expression to compile. They also don't return any value, instead - generated code is cached in RESULT_ and returned from the caller. */ +/* Determine if type T is a struct that has a postblit. */ -class ExprVisitor : public Visitor +static bool +needs_postblit (Type *t) { - using Visitor::visit; - - tree result_; - bool constp_; + t = t->baseElemOf (); - /* Determine if type is a struct that has a postblit. */ - - bool needs_postblit (Type *t) - { - t = t->baseElemOf (); - - if (TypeStruct *ts = t->isTypeStruct ()) - { - if (ts->sym->postblit) - return true; - } + if (TypeStruct *ts = t->isTypeStruct ()) + { + if (ts->sym->postblit) + return true; + } - return false; - } + return false; +} - /* Determine if type is a struct that has a destructor. */ +/* Determine if type T is a struct that has a destructor. */ - bool needs_dtor (Type *t) - { - t = t->baseElemOf (); +static bool +needs_dtor (Type *t) +{ + t = t->baseElemOf (); - if (TypeStruct *ts = t->isTypeStruct ()) - { - if (ts->sym->dtor) - return true; - } + if (TypeStruct *ts = t->isTypeStruct ()) + { + if (ts->sym->dtor) + return true; + } - return false; - } + return false; +} - /* Determine if expression is suitable lvalue. */ +/* Determine if expression E is a suitable lvalue. */ - bool lvalue_p (Expression *e) - { - SliceExp *se = e->isSliceExp (); - if (se != NULL && se->e1->isLvalue ()) - return true; +static bool +lvalue_p (Expression *e) +{ + SliceExp *se = e->isSliceExp (); + if (se != NULL && se->e1->isLvalue ()) + return true; - CastExp *ce = e->isCastExp (); - if (ce != NULL && ce->e1->isLvalue ()) - return true; + CastExp *ce = e->isCastExp (); + if (ce != NULL && ce->e1->isLvalue ()) + return true; - return (e->op != TOKslice && e->isLvalue ()); - } - - /* Build an expression of code CODE, data type TYPE, and operands ARG0 and - ARG1. Perform relevant conversions needed for correct code operations. */ + return (e->op != TOKslice && e->isLvalue ()); +} - tree binary_op (tree_code code, tree type, tree arg0, tree arg1) - { - tree t0 = TREE_TYPE (arg0); - tree t1 = TREE_TYPE (arg1); - tree ret = NULL_TREE; +/* Build an expression of code CODE, data type TYPE, and operands ARG0 and + ARG1. Perform relevant conversions needed for correct code operations. */ - bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1); +static tree +binary_op (tree_code code, tree type, tree arg0, tree arg1) +{ + tree t0 = TREE_TYPE (arg0); + tree t1 = TREE_TYPE (arg1); + tree ret = NULL_TREE; - /* Deal with float mod expressions immediately. */ - if (code == FLOAT_MOD_EXPR) - return build_float_modulus (type, arg0, arg1); + bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1); - if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1)) - return build_nop (type, build_offset_op (code, arg0, arg1)); + /* Deal with float mod expressions immediately. */ + if (code == FLOAT_MOD_EXPR) + return build_float_modulus (type, arg0, arg1); - if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1)) - return build_nop (type, build_offset_op (code, arg1, arg0)); + if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1)) + return build_nop (type, build_offset_op (code, arg0, arg1)); - if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1)) - { - gcc_assert (code == MINUS_EXPR); - tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0); + if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1)) + return build_nop (type, build_offset_op (code, arg1, arg0)); - /* POINTER_DIFF_EXPR requires a signed integer type of the same size as - pointers. If some platform cannot provide that, or has a larger - ptrdiff_type to support differences larger than half the address - space, cast the pointers to some larger integer type and do the - computations in that type. */ - if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0)) - ret = fold_build2 (MINUS_EXPR, ptrtype, - d_convert (ptrtype, arg0), - d_convert (ptrtype, arg1)); - else - ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1); - } - else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp)) - { - tree inttype = (unsignedp) - ? d_unsigned_type (type) : d_signed_type (type); - ret = fold_build2 (code, inttype, arg0, arg1); - } - else - { - /* If the operation needs excess precision. */ - tree eptype = excess_precision_type (type); - if (eptype != NULL_TREE) - { - arg0 = d_convert (eptype, arg0); - arg1 = d_convert (eptype, arg1); - } - else - { - /* Front-end does not do this conversion and GCC does not - always do it right. */ - if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1)) - arg1 = d_convert (t0, arg1); - else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0)) - arg0 = d_convert (t1, arg0); + if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1)) + { + gcc_assert (code == MINUS_EXPR); + tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0); + + /* POINTER_DIFF_EXPR requires a signed integer type of the same size as + pointers. If some platform cannot provide that, or has a larger + ptrdiff_type to support differences larger than half the address + space, cast the pointers to some larger integer type and do the + computations in that type. */ + if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0)) + ret = fold_build2 (MINUS_EXPR, ptrtype, + d_convert (ptrtype, arg0), + d_convert (ptrtype, arg1)); + else + ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1); + } + else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp)) + { + tree inttype = (unsignedp) + ? d_unsigned_type (type) : d_signed_type (type); + ret = fold_build2 (code, inttype, arg0, arg1); + } + else + { + /* If the operation needs excess precision. */ + tree eptype = excess_precision_type (type); + if (eptype != NULL_TREE) + { + arg0 = d_convert (eptype, arg0); + arg1 = d_convert (eptype, arg1); + } + else + { + /* Front-end does not do this conversion and GCC does not + always do it right. */ + if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1)) + arg1 = d_convert (t0, arg1); + else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0)) + arg0 = d_convert (t1, arg0); + + eptype = type; + } + + ret = fold_build2 (code, eptype, arg0, arg1); + } - eptype = type; - } + return d_convert (type, ret); +} - ret = fold_build2 (code, eptype, arg0, arg1); - } +/* Build a binary expression of code CODE, assigning the result into E1. */ - return d_convert (type, ret); - } +static tree +binop_assignment (tree_code code, Expression *e1, Expression *e2) +{ + /* Skip casts for lhs assignment. */ + Expression *e1b = e1; + while (e1b->op == TOKcast) + { + CastExp *ce = e1b->isCastExp (); + gcc_assert (same_type_p (ce->type, ce->to)); + e1b = ce->e1; + } - /* Build a binary expression of code CODE, assigning the result into E1. */ + /* Stabilize LHS for assignment. */ + tree lhs = build_expr (e1b); + tree lexpr = stabilize_expr (&lhs); - tree binop_assignment (tree_code code, Expression *e1, Expression *e2) - { - /* Skip casts for lhs assignment. */ - Expression *e1b = e1; - while (e1b->op == TOKcast) - { - CastExp *ce = e1b->isCastExp (); - gcc_assert (same_type_p (ce->type, ce->to)); - e1b = ce->e1; - } + /* The LHS expression could be an assignment, to which its operation gets + lost during gimplification. */ + if (TREE_CODE (lhs) == MODIFY_EXPR) + { + /* If LHS has side effects, call stabilize_reference on it, so it can + be evaluated multiple times. */ + if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) + lhs = build_assign (MODIFY_EXPR, + stabilize_reference (TREE_OPERAND (lhs, 0)), + TREE_OPERAND (lhs, 1)); + + lexpr = compound_expr (lexpr, lhs); + lhs = TREE_OPERAND (lhs, 0); + } - /* Stabilize LHS for assignment. */ - tree lhs = build_expr (e1b); - tree lexpr = stabilize_expr (&lhs); + lhs = stabilize_reference (lhs); - /* The LHS expression could be an assignment, to which its operation gets - lost during gimplification. */ - if (TREE_CODE (lhs) == MODIFY_EXPR) - { - /* If LHS has side effects, call stabilize_reference on it, so it can - be evaluated multiple times. */ - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build_assign (MODIFY_EXPR, - stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); + /* Save RHS, to ensure that the expression is evaluated before LHS. */ + tree rhs = build_expr (e2); + tree rexpr = d_save_expr (rhs); - lexpr = compound_expr (lexpr, lhs); - lhs = TREE_OPERAND (lhs, 0); - } + rhs = binary_op (code, build_ctype (e1->type), + convert_expr (lhs, e1b->type, e1->type), rexpr); + if (TREE_SIDE_EFFECTS (rhs)) + rhs = compound_expr (rexpr, rhs); - lhs = stabilize_reference (lhs); + tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type)); + return compound_expr (lexpr, expr); +} - /* Save RHS, to ensure that the expression is evaluated before LHS. */ - tree rhs = build_expr (e2); - tree rexpr = d_save_expr (rhs); +/* Implements the visitor interface to build the GCC trees of all Expression + AST classes emitted from the D Front-end. + All visit methods accept one parameter E, which holds the frontend AST + of the expression to compile. They also don't return any value, instead + generated code is cached in RESULT_ and returned from the caller. */ - rhs = this->binary_op (code, build_ctype (e1->type), - convert_expr (lhs, e1b->type, e1->type), rexpr); - if (TREE_SIDE_EFFECTS (rhs)) - rhs = compound_expr (rexpr, rhs); +class ExprVisitor : public Visitor +{ + using Visitor::visit; - tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type)); - return compound_expr (lexpr, expr); - } + tree result_; + bool constp_; public: ExprVisitor (bool constp) @@ -653,8 +658,8 @@ public: gcc_unreachable (); } - this->result_ = this->binary_op (code, build_ctype (e->type), - build_expr (e->e1), build_expr (e->e2)); + this->result_ = binary_op (code, build_ctype (e->type), + build_expr (e->e1), build_expr (e->e2)); } @@ -807,7 +812,7 @@ public: gcc_unreachable (); } - tree exp = this->binop_assignment (code, e1b, e->e2); + tree exp = binop_assignment (code, e1b, e->e2); this->result_ = convert_expr (exp, e1b->type, e->type); } @@ -915,8 +920,8 @@ public: Type *etype = stype->nextOf ()->toBasetype (); /* Determine if we need to run postblit or dtor. */ - bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2); - bool destructor = this->needs_dtor (etype); + bool postblit = needs_postblit (etype) && lvalue_p (e->e2); + bool destructor = needs_dtor (etype); if (e->memset & blockAssign) { @@ -1098,15 +1103,15 @@ public: gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray); /* Determine if we need to run postblit. */ - bool postblit = this->needs_postblit (etype); - bool destructor = this->needs_dtor (etype); - bool lvalue_p = this->lvalue_p (e->e2); + bool postblit = needs_postblit (etype); + bool destructor = needs_dtor (etype); + bool lvalue = lvalue_p (e->e2); /* Even if the elements in rhs are all rvalues and don't have to call postblits, this assignment should call dtors on old assigned elements. */ if ((!postblit && !destructor) - || (e->op == TOKconstruct && !lvalue_p && postblit) + || (e->op == TOKconstruct && !lvalue && postblit) || (e->op == TOKblit || e->e1->type->size () == 0)) { tree t1 = build_expr (e->e1); @@ -1132,7 +1137,7 @@ public: { /* Generate: _d_arrayassign_l() or: _d_arrayassign_r() */ - libcall_fn libcall = (lvalue_p) + libcall_fn libcall = (lvalue) ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R; tree elembuf = build_local_temp (build_ctype (etype));