From patchwork Wed Jun 1 15:33:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1638020 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=C/kuLWvR; dkim-atps=neutral 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+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.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 (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LCtTm4RfFz9s09 for ; Thu, 2 Jun 2022 01:33:47 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 582FE382F98F for ; Wed, 1 Jun 2022 15:33:44 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x82f.google.com (mail-qt1-x82f.google.com [IPv6:2607:f8b0:4864:20::82f]) by sourceware.org (Postfix) with ESMTPS id 5843238515DA for ; Wed, 1 Jun 2022 15:33:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5843238515DA Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-qt1-x82f.google.com with SMTP id v1so1417640qtx.5 for ; Wed, 01 Jun 2022 08:33:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=sender:message-id:date:mime-version:user-agent:content-language:to :from:subject; bh=OgllO1sNo0RK8/Ih9Q9fhYnMYpfQTxdyZc3e1HymB9Y=; b=C/kuLWvRyWVSPbYqof05uHmH13075yShL5ZBLLC0EC+eUVpohxpxM65uiIYJMNySAB lPTn8YAK5xCqHlzw4/oeN8NVdcH81SOhbZSaX9HhlJQr9tkOl5Qb74YocKnlXBsevFr0 2dRxgEYGQMWSd4Rnv2krKshOTcT+ddm9w1e93L187mxDKjDkXYfxC5tM2gBzlnqcIztf QHhMyZq2fXeDjk5cdYN2w/MXbo5SHqLv8O5e3OGWJ7tO/dlVbGDIqnBO31/k3pVjZ+09 XeSr1C8HinLvnpbIdSBj9txRfb4MMFq+9RfTs6VlSlerNAWYpfEwovwAo6DxVVkBX+40 6oBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:sender:message-id:date:mime-version:user-agent :content-language:to:from:subject; bh=OgllO1sNo0RK8/Ih9Q9fhYnMYpfQTxdyZc3e1HymB9Y=; b=yHaLhoq0J2c6OZ3b/PIH/H644ikIh/1eCdGsG5oGigbWVdprxb3yp/gJi0uky8cfGc zadLEoCWjRsbPBXpKYlkk3q9nLPSPow/RK5wGOgjAzkV1eeOMVgUVNjTBv02KPF2v3H2 1AkTcgI2ilaqRSMIxRN1RTMgyqd8NyKysrNzR57PlAFSkkgbjMJARKOwtrVJoSnCtZjk SCsxDx62eiYJlDqzj4kDOF4+aqKi8rSx29YqOajJaHkg9McyVNTZXtufRT1HfTRcocjU jL+TUtauYvO16QAIqgDr4LWodt8HzqNZCk/mMSamwQIiUTA2+sHCc1m19oAmc8CDpy9Y EbqQ== X-Gm-Message-State: AOAM533QgSixqgqNVWng1tMpvUNwbsQjAL1jb8X/WHJUetOCSDhgmZZQ +U6eXYnydQoAjSqizF/cwI1KxanGIbA= X-Google-Smtp-Source: ABdhPJxrNOvxSkAJyTPi9qYfk68XHkyCBz0ag2IdMqpEypQYAyMEtRYQYm87y5HghRV5lJZciEeAhg== X-Received: by 2002:a05:622a:1a9f:b0:304:b3f9:457f with SMTP id s31-20020a05622a1a9f00b00304b3f9457fmr95879qtc.641.1654097610408; Wed, 01 Jun 2022 08:33:30 -0700 (PDT) Received: from ?IPV6:2620:10d:c0a3:1407:833b:ea51:fd50:7fc8? ([2620:10d:c091:500::3:5984]) by smtp.googlemail.com with ESMTPSA id g4-20020a37b604000000b006a5fb8219bbsm1467683qkf.44.2022.06.01.08.33.29 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 01 Jun 2022 08:33:29 -0700 (PDT) Message-ID: <92e0c728-4237-606c-58aa-1ec70b9dd55a@acm.org> Date: Wed, 1 Jun 2022 11:33:27 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.2.0 Content-Language: en-US To: GCC Patches From: Nathan Sidwell Subject: c++: Static init guard generation X-Spam-Status: No, score=-3038.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" The guard generation for a static var init was overly verbose. We can use a bit of RAII and avoid some rechecking. Also in the !cxa_atexit case, the only difference is whether can become whether to use post-inc or pre-dec. nathan From 289f860fe62423a66e43989688e1d24bcdb25b5e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 1 Jun 2022 04:52:21 -0700 Subject: [PATCH] c++: Static init guard generation The guard generation for a static var init was overly verbose. We can use a bit of RAII and avoid some rechecking. Also in the !cxa_atexit case, the only difference is whether can become whether to use post-inc or pre-dec. gcc/cp/ * decl2.cc (fix_temporary_vars_context_r): Use data argument for new context. (one_static_initialization_or_destruction): Adjust tree walk call. Refactor guard generation. --- gcc/cp/decl2.cc | 111 ++++++++++++++++++------------------------------ 1 file changed, 42 insertions(+), 69 deletions(-) diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 9de3f806e95..974afe798b6 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -4085,34 +4085,25 @@ get_priority_info (int priority) || DECL_ONE_ONLY (decl) \ || DECL_WEAK (decl))) -/* Called from one_static_initialization_or_destruction(), - via walk_tree. - Walks the initializer list of a global variable and looks for +/* Walks the initializer list of a global variable and looks for temporary variables (DECL_NAME() == NULL and DECL_ARTIFICIAL != 0) - and that have their DECL_CONTEXT() == NULL. - For each such temporary variable, set their DECL_CONTEXT() to - the current function. This is necessary because otherwise - some optimizers (enabled by -O2 -fprofile-arcs) might crash - when trying to refer to a temporary variable that does not have - it's DECL_CONTECT() properly set. */ + and that have their DECL_CONTEXT() == NULL. For each such + temporary variable, set their DECL_CONTEXT() to CTX -- the + initializing function. This is necessary because otherwise some + optimizers (enabled by -O2 -fprofile-arcs) might crash when trying + to refer to a temporary variable that does not have its + DECL_CONTEXT() properly set. */ + static tree fix_temporary_vars_context_r (tree *node, int * /*unused*/, - void * /*unused1*/) + void *ctx) { - gcc_assert (current_function_decl); - if (TREE_CODE (*node) == BIND_EXPR) - { - tree var; - - for (var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var)) - if (VAR_P (var) - && !DECL_NAME (var) - && DECL_ARTIFICIAL (var) - && !DECL_CONTEXT (var)) - DECL_CONTEXT (var) = current_function_decl; - } + for (tree var = BIND_EXPR_VARS (*node); var; var = DECL_CHAIN (var)) + if (VAR_P (var) && !DECL_NAME (var) + && DECL_ARTIFICIAL (var) && !DECL_CONTEXT (var)) + DECL_CONTEXT (var) = tree (ctx); return NULL_TREE; } @@ -4124,9 +4115,6 @@ fix_temporary_vars_context_r (tree *node, static void one_static_initialization_or_destruction (bool initp, tree decl, tree init) { - tree guard_if_stmt = NULL_TREE; - tree guard; - /* If we are supposed to destruct and there's a trivial destructor, nothing has to be done. */ if (!initp @@ -4150,7 +4138,7 @@ one_static_initialization_or_destruction (bool initp, tree decl, tree init) of the temporaries are set to the current function decl. */ cp_walk_tree_without_duplicates (&init, fix_temporary_vars_context_r, - NULL); + current_function_decl); /* Because of: @@ -4171,62 +4159,50 @@ one_static_initialization_or_destruction (bool initp, tree decl, tree init) } /* Assume we don't need a guard. */ - guard = NULL_TREE; + tree guard_if_stmt = NULL_TREE; + /* We need a guard if this is an object with external linkage that might be initialized in more than one place. (For example, a static data member of a template, when the data member requires construction.) */ if (NEEDS_GUARD_P (decl)) { + tree guard = get_guard (decl); tree guard_cond; - guard = get_guard (decl); - - /* When using __cxa_atexit, we just check the GUARD as we would - for a local static. */ if (flag_use_cxa_atexit) { - /* When using __cxa_atexit, we never try to destroy + /* When using __cxa_atexit, we just check the GUARD as we + would for a local static. We never try to destroy anything from a static destructor. */ gcc_assert (initp); guard_cond = get_guard_cond (guard, false); } - /* If we don't have __cxa_atexit, then we will be running - destructors from .fini sections, or their equivalents. So, - we need to know how many times we've tried to initialize this - object. We do initializations only if the GUARD is zero, - i.e., if we are the first to initialize the variable. We do - destructions only if the GUARD is one, i.e., if we are the - last to destroy the variable. */ - else if (initp) - guard_cond - = cp_build_binary_op (input_location, - EQ_EXPR, - cp_build_unary_op (PREINCREMENT_EXPR, - guard, - /*noconvert=*/true, - tf_warning_or_error), - integer_one_node, - tf_warning_or_error); else - guard_cond - = cp_build_binary_op (input_location, - EQ_EXPR, - cp_build_unary_op (PREDECREMENT_EXPR, - guard, - /*noconvert=*/true, - tf_warning_or_error), - integer_zero_node, - tf_warning_or_error); + { + /* If we don't have __cxa_atexit, then we will be running + destructors from .fini sections, or their equivalents. + So, we need to know how many times we've tried to + initialize this object. We do initializations only if + the GUARD was or becomes zero (initp vs !initp + respectively). */ + guard_cond = cp_build_unary_op (initp ? POSTINCREMENT_EXPR + : PREDECREMENT_EXPR, + guard, + /*noconvert=*/true, + tf_warning_or_error); + guard_cond = cp_build_binary_op (input_location, EQ_EXPR, guard_cond, + integer_zero_node, + tf_warning_or_error); + } guard_if_stmt = begin_if_stmt (); finish_if_stmt_cond (guard_cond, guard_if_stmt); - } - /* If we're using __cxa_atexit, we have not already set the GUARD, - so we must do so now. */ - if (guard && initp && flag_use_cxa_atexit) - finish_expr_stmt (set_guard (guard)); + if (flag_use_cxa_atexit) + /* Set the GUARD now. */ + finish_expr_stmt (set_guard (guard)); + } /* Perform the initialization or destruction. */ if (initp) @@ -4235,11 +4211,8 @@ one_static_initialization_or_destruction (bool initp, tree decl, tree init) { finish_expr_stmt (init); if (sanitize_flags_p (SANITIZE_ADDRESS, decl)) - { - varpool_node *vnode = varpool_node::get (decl); - if (vnode) - vnode->dynamically_initialized = 1; - } + if (varpool_node *vnode = varpool_node::get (decl)) + vnode->dynamically_initialized = 1; } /* If we're using __cxa_atexit, register a function that calls the @@ -4251,7 +4224,7 @@ one_static_initialization_or_destruction (bool initp, tree decl, tree init) finish_expr_stmt (build_cleanup (decl)); /* Finish the guard if-stmt, if necessary. */ - if (guard) + if (guard_if_stmt) { finish_then_clause (guard_if_stmt); finish_if_stmt (guard_if_stmt); -- 2.30.2