From patchwork Wed Apr 3 12:40:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1919300 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=KlOIUp8D; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4V8krC09FMz1yZJ for ; Wed, 3 Apr 2024 23:40:57 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A4FCD3846402 for ; Wed, 3 Apr 2024 12:40:55 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) by sourceware.org (Postfix) with ESMTPS id 6EDC03858401 for ; Wed, 3 Apr 2024 12:40:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6EDC03858401 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6EDC03858401 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::636 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712148037; cv=none; b=er2gHxJqED2JPrJArAM58/SzDF//yHTO5PfgU74uvy5PCvdzL1yFlQyQ/+NJKshZggrrsrHmUK6zlEeLT7BpB2yBdexKXYn9N52KBmPzpZcGbPOWGog046w1lur3KZoMa4oq0Yy6gr9wWv+Q7/02JQLMyskUUReP/cKjW3QosOA= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1712148037; c=relaxed/simple; bh=jxvKVhQfyU6QTt5WnSdBBZFqQbhKAkJG9qM8IMNJjGI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=xozOuuf5Ghy1HOjHc8C2Coo8VBlkseNXch1oKXYb++v7fzFSP73BnNis3musIXvsvHSuEZbezrQM/HhbnKXhhD+BF/9qLU6wO8DUu2KLtfeIr45316zuzFKMGfWwEr8iRGZEd2GmauF5+wAwT4X6TBAQZfKaOWZrh2zh2z63sEw= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-1e0411c0a52so53740255ad.0 for ; Wed, 03 Apr 2024 05:40:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1712148034; x=1712752834; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=kKQAwpcC0vmZfxrQ/my3dyL8IhTvCzOkAj0hLKbGDHs=; b=KlOIUp8DMIpsPxNpo4LXDPtUUg4pxL+H2ilPSMr08/66rPGnT1LXlvSzVfOWbhllLN 4l8fvHJMejz1RxjHSAQXjwz5Zgq8WktIjBpxSVBS3ob9Po+cLGezuNhlf2RYVbBSmt7B JKVwJH6fTiyQrxYJ1N0tG1llLSSiYrMzRDjFdfVfen3N3f+sM9F4OJSz7lT7eb0VxfoH vpojgknLBMVv7vpc33mNmjWLYd0W35R2KHLwxurwqAPKKYWr0iMKSOQg+yprH8VYHka3 8oT/yH+eqFElxTZY0LxNxNgOHaus5xMg0Q6L2/JfaY71Z8r5U9Tf2zUbKxRxupb+MOiQ YWcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1712148034; x=1712752834; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=kKQAwpcC0vmZfxrQ/my3dyL8IhTvCzOkAj0hLKbGDHs=; b=DauJoLdMdW2ulvsGPBhwbGjVZjK0fBwW8UsHa88ROeM+LZkBpPeSCghsfdK0IWLhXs hRNonfgJnqw9N3YMggOUxNNsMJziYCUJVMWaskBiDbUjyRBEh3g7hROeKUMjzt+BdOne vOaMTANRXWWp48AlOweE2qMMpO9at/aE5NCy9iqmtpUFbN5UgEMZApfxL6X6jR3lbktV fo9TU80ZWoMP/n4c2a6wSfvkv4ipGc9apdc2AeRuK7FyFzsikQq8s5o1BHnwT5j5M0qM s1tdCVaRNhKNtB/Dvh9mHxxcqu9OknoEu8J5BaW2s2htZYjSqEkdJE6D5PhZvfbo4O3N esBw== X-Gm-Message-State: AOJu0YxDxuGltL3CzXXitxRBbG/TQpHFuWw7/gV1qZ8B33NoQgqS7Dv1 koYs91Gxb7YJzXKSePHwXgwXnzvQqYq++JszFOnRCTUz/KlDepFf5UTkEVYa X-Google-Smtp-Source: AGHT+IGLu0xxCvUK5TQ4Tb+KltwitAPuxLH9YwG3UYxnJnOegT5iDycsPmPDNGGBExue5PIYqV4aTw== X-Received: by 2002:a17:903:11cc:b0:1df:fa1a:529f with SMTP id q12-20020a17090311cc00b001dffa1a529fmr15308965plh.24.1712148034022; Wed, 03 Apr 2024 05:40:34 -0700 (PDT) Received: from gnu-cfl-3.localdomain ([172.58.89.72]) by smtp.gmail.com with ESMTPSA id j7-20020a170903024700b001db3361bc1dsm11271110plh.102.2024.04.03.05.40.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Apr 2024 05:40:33 -0700 (PDT) Received: from gnu-cfl-3.. (localhost [IPv6:::1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id 61ABE74016D; Wed, 3 Apr 2024 05:40:32 -0700 (PDT) From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: hubicka@ucw.cz Subject: [PATCH v3] tree-profile: Disable indirect call profiling for IFUNC resolvers Date: Wed, 3 Apr 2024 05:40:32 -0700 Message-ID: <20240403124032.165069-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3020.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_SBL_CSS, SPF_HELO_NONE, SPF_PASS, TXREP 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.30 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 We can't profile indirect calls to IFUNC resolvers nor their callees as it requires TLS which hasn't been set up yet when the dynamic linker is resolving IFUNC symbols. Add an IFUNC resolver caller marker to cgraph_node and set it if the function is called by an IFUNC resolver. Disable indirect call profiling for IFUNC resolvers and their callees. Tested with profiledbootstrap on Fedora 39/x86-64. gcc/ChangeLog: PR tree-optimization/114115 * cgraph.h (symtab_node): Add check_ifunc_callee_symtab_nodes. (cgraph_node): Add called_by_ifunc_resolver. * cgraphunit.cc (symbol_table::compile): Call symtab_node::check_ifunc_callee_symtab_nodes. * symtab.cc (check_ifunc_resolver): New. (ifunc_ref_map): Likewise. (is_caller_ifunc_resolver): Likewise. (symtab_node::check_ifunc_callee_symtab_nodes): Likewise. * tree-profile.cc (gimple_gen_ic_func_profiler): Disable indirect call profiling for IFUNC resolvers and their callees. gcc/testsuite/ChangeLog: PR tree-optimization/114115 * gcc.dg/pr114115.c: New test. --- gcc/cgraph.h | 6 +++ gcc/cgraphunit.cc | 2 + gcc/symtab.cc | 89 +++++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr114115.c | 24 +++++++++ gcc/tree-profile.cc | 5 +- 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr114115.c diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 47f35e8078d..a8c3224802c 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -479,6 +479,9 @@ public: Return NULL if there's no such node. */ static symtab_node *get_for_asmname (const_tree asmname); + /* Check symbol table for callees of IFUNC resolvers. */ + static void check_ifunc_callee_symtab_nodes (void); + /* Verify symbol table for internal consistency. */ static DEBUG_FUNCTION void verify_symtab_nodes (void); @@ -896,6 +899,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node redefined_extern_inline (false), tm_may_enter_irr (false), ipcp_clone (false), declare_variant_alt (false), calls_declare_variant_alt (false), gc_candidate (false), + called_by_ifunc_resolver (false), m_uid (uid), m_summary_id (-1) {} @@ -1495,6 +1499,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node is set for local SIMD clones when they are created and cleared if the vectorizer uses them. */ unsigned gc_candidate : 1; + /* Set if the function is called by an IFUNC resolver. */ + unsigned called_by_ifunc_resolver : 1; private: /* Unique id of the node. */ diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc index d200166f7e9..2bd0289ffba 100644 --- a/gcc/cgraphunit.cc +++ b/gcc/cgraphunit.cc @@ -2317,6 +2317,8 @@ symbol_table::compile (void) symtab_node::checking_verify_symtab_nodes (); + symtab_node::check_ifunc_callee_symtab_nodes (); + timevar_push (TV_CGRAPHOPT); if (pre_ipa_mem_report) dump_memory_report ("Memory consumption before IPA"); diff --git a/gcc/symtab.cc b/gcc/symtab.cc index 4c7e3c135ca..3256133891d 100644 --- a/gcc/symtab.cc +++ b/gcc/symtab.cc @@ -1369,6 +1369,95 @@ symtab_node::verify (void) timevar_pop (TV_CGRAPH_VERIFY); } +/* Return true and set *DATA to true if NODE is an ifunc resolver. */ + +static bool +check_ifunc_resolver (cgraph_node *node, void *data) +{ + if (node->ifunc_resolver) + { + bool *is_ifunc_resolver = (bool *) data; + *is_ifunc_resolver = true; + return true; + } + return false; +} + +static auto_bitmap ifunc_ref_map; + +/* Return true if any caller of NODE is an ifunc resolver. */ + +static bool +is_caller_ifunc_resolver (cgraph_node *node) +{ + bool is_ifunc_resolver = false; + + for (cgraph_edge *e = node->callers; e; e = e->next_caller) + { + /* Return true if caller is known to be an IFUNC resolver. */ + if (e->caller->called_by_ifunc_resolver) + return true; + + /* Check for recursive call. */ + if (e->caller == node) + continue; + + /* Skip if it has been visited. */ + unsigned int uid = e->caller->get_uid (); + if (bitmap_bit_p (ifunc_ref_map, uid)) + continue; + bitmap_set_bit (ifunc_ref_map, uid); + + if (is_caller_ifunc_resolver (e->caller)) + { + /* Return true if caller is an IFUNC resolver. */ + e->caller->called_by_ifunc_resolver = true; + return true; + } + + /* Check if caller's alias is an IFUNC resolver. */ + e->caller->call_for_symbol_and_aliases (check_ifunc_resolver, + &is_ifunc_resolver, + true); + if (is_ifunc_resolver) + { + /* Return true if caller's alias is an IFUNC resolver. */ + e->caller->called_by_ifunc_resolver = true; + return true; + } + } + + return false; +} + +/* Check symbol table for callees of IFUNC resolvers. */ + +void +symtab_node::check_ifunc_callee_symtab_nodes (void) +{ + symtab_node *node; + + FOR_EACH_SYMBOL (node) + { + cgraph_node *cnode = dyn_cast (node); + if (!cnode) + continue; + + unsigned int uid = cnode->get_uid (); + if (bitmap_bit_p (ifunc_ref_map, uid)) + continue; + bitmap_set_bit (ifunc_ref_map, uid); + + bool is_ifunc_resolver = false; + cnode->call_for_symbol_and_aliases (check_ifunc_resolver, + &is_ifunc_resolver, true); + if (is_ifunc_resolver || is_caller_ifunc_resolver (cnode)) + cnode->called_by_ifunc_resolver = true; + } + + bitmap_clear (ifunc_ref_map); +} + /* Verify symbol table for internal consistency. */ DEBUG_FUNCTION void diff --git a/gcc/testsuite/gcc.dg/pr114115.c b/gcc/testsuite/gcc.dg/pr114115.c new file mode 100644 index 00000000000..2629f591877 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114115.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -fprofile-generate -fdump-tree-optimized" } */ +/* { dg-require-profiling "-fprofile-generate" } */ +/* { dg-require-ifunc "" } */ + +void *foo_ifunc2() __attribute__((ifunc("foo_resolver"))); + +void bar(void) +{ +} + +static int f3() +{ + bar (); + return 5; +} + +void (*foo_resolver(void))(void) +{ + f3(); + return bar; +} + +/* { dg-final { scan-tree-dump-not "__gcov_indirect_call_profiler_v" "optimized" } } */ diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc index aed13e2b1bc..373dbd60481 100644 --- a/gcc/tree-profile.cc +++ b/gcc/tree-profile.cc @@ -520,7 +520,10 @@ gimple_gen_ic_func_profiler (void) gcall *stmt1; tree tree_uid, cur_func, void0; - if (c_node->only_called_directly_p ()) + /* Disable indirect call profiling for an IFUNC resolver and its + callees. */ + if (c_node->only_called_directly_p () + || c_node->called_by_ifunc_resolver) return; gimple_init_gcov_profiler ();