From patchwork Fri Jul 29 06:28:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1661894 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.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=gZzyWbQW; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from 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 RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LvHfM3vvSz9sPC for ; Fri, 29 Jul 2022 16:28:59 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 27DC1385482A for ; Fri, 29 Jul 2022 06:28:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 27DC1385482A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1659076137; bh=j982+YDUyAHtFEjz28PShxI6nafjwlKNgF033kPU0q4=; h=To:Subject:References:Date:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=gZzyWbQWpojNi30jZEcUTiCJJU3S89ufF81pPfGGVfp/X2GlDAX1LPI5qZEJufWQn 22omithG80/gICXai8+dSVSmh8RBAcyTBjR70tuyHu/M+kp3VGsmzD4NTERBVKUlUx nJRQjt7WRFTvqcDlH7HNijMtzdb7szdWyZReVM9c= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTPS id E2CC93851C19 for ; Fri, 29 Jul 2022 06:28:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E2CC93851C19 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 5F4441168D2; Fri, 29 Jul 2022 02:28:35 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 7gZe6jAsxN9q; Fri, 29 Jul 2022 02:28:35 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 1D2951168CD; Fri, 29 Jul 2022 02:28:34 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 26T6SQ5R1852115 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 29 Jul 2022 03:28:26 -0300 To: gcc-patches@gcc.gnu.org Subject: [PATCH v2 07/10] Introduce strub: infrastructure interfaces and adjustments Organization: Free thinker, does not speak for AdaCore References: Date: Fri, 29 Jul 2022 03:28:26 -0300 In-Reply-To: (Alexandre Oliva's message of "Fri, 29 Jul 2022 03:16:41 -0300") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Alexandre Oliva via Gcc-patches From: Alexandre Oliva Reply-To: Alexandre Oliva Cc: Jan Hubicka , Jim Wilson , Graham Markall Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Introduce the new strub passes, adjust other passes and front-end declaration for strub. for gcc/ChangeLog * Makefile.in (OBJS): Add ipa-strub.o. * ipa-inline.cc: Include ipa-strub.h. (can_inline_edge_p): Test strub_inlinable_to_p. * ipa-split.cc: Include ipa-strub.h. (execute_split_functions): Test strub_splittable_p. * ipa-strub.h: New. * passes.def: Add strub_mode and strub passes. * tree-cfg.cc (gimple_verify_flow_info): Note on debug stmts. * tree-pass.h (make_pass_ipa_strub_mode): Declare. (make_pass_ipa_strub): Declare. (make_pass_ipa_function_and_variable_visibility): Fix formatting. * tree-ssa-ccp.cc (optimize_stack_restore): Keep restores before strub leave. * multiple_target.cc (pass_target_clone::gate): Test seen_error. for gcc/ada/ChangeLog * gcc-interface/trans.cc: Include ipa-strub.h. (gigi): Make internal decls for targets of compiler-generated calls strub-callable too. (build_raise_check): Likewise. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 203f0a15187d2..4100531d73ae7 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1480,6 +1480,7 @@ OBJS = \ ipa-reference.o \ ipa-ref.o \ ipa-utils.o \ + ipa-strub.o \ ipa.o \ ira.o \ ira-build.o \ diff --git a/gcc/ada/gcc-interface/trans.cc b/gcc/ada/gcc-interface/trans.cc index c1dd567b2e4e2..e3553a7a87bfc 100644 --- a/gcc/ada/gcc-interface/trans.cc +++ b/gcc/ada/gcc-interface/trans.cc @@ -69,6 +69,21 @@ #include "ada-tree.h" #include "gigi.h" +/* The following #include is for strub_make_callable. + + This function marks a function as safe to call from strub contexts. We mark + Ada subprograms that may be called implicitly by the compiler, and that won't + leave on the stack caller data passed to them. This stops implicit calls + introduced in subprograms that have their stack scrubbed from being flagged + as unsafe, even in -fstrub=strict mode. + + These subprograms are also marked with the strub(callable) attribute in Ada + sources, but their declarations aren't necessarily imported by GNAT, or made + visible to gigi, in units that end up relying on them. So when gigi + introduces their declarations on its own, it must also add the attribute, by + calling strub_make_callable. */ +#include "ipa-strub.h" + /* We should avoid allocating more than ALLOCA_THRESHOLD bytes via alloca, for fear of running out of stack space. If we need more, we use xmalloc instead. */ @@ -449,6 +464,7 @@ gigi (Node_Id gnat_root, int64_type, NULL_TREE), NULL_TREE, is_default, true, true, true, false, false, NULL, Empty); + strub_make_callable (mulv64_decl); if (Enable_128bit_Types) { @@ -461,6 +477,7 @@ gigi (Node_Id gnat_root, NULL_TREE), NULL_TREE, is_default, true, true, true, false, false, NULL, Empty); + strub_make_callable (mulv128_decl); } /* Name of the _Parent field in tagged record types. */ @@ -716,6 +733,7 @@ build_raise_check (int check, enum exception_info_kind kind) = create_subprog_decl (get_identifier (Name_Buffer), NULL_TREE, ftype, NULL_TREE, is_default, true, true, true, false, false, NULL, Empty); + strub_make_callable (result); return result; } diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc index 14969198cde1c..0674fe138574d 100644 --- a/gcc/ipa-inline.cc +++ b/gcc/ipa-inline.cc @@ -119,6 +119,7 @@ along with GCC; see the file COPYING3. If not see #include "stringpool.h" #include "attribs.h" #include "asan.h" +#include "ipa-strub.h" typedef fibonacci_heap edge_heap_t; typedef fibonacci_node edge_heap_node_t; @@ -397,6 +398,11 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, inlinable = false; } + if (inlinable && !strub_inlinable_to_p (callee, caller)) + { + e->inline_failed = CIF_UNSPECIFIED; + inlinable = false; + } if (!inlinable && report) report_inline_failed_reason (e); return inlinable; diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc index 16734617d0381..b3b9963f13669 100644 --- a/gcc/ipa-split.cc +++ b/gcc/ipa-split.cc @@ -104,6 +104,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-fnsummary.h" #include "cfgloop.h" #include "attribs.h" +#include "ipa-strub.h" /* Per basic block info. */ @@ -1810,6 +1811,12 @@ execute_split_functions (void) "section.\n"); return 0; } + if (!strub_splittable_p (node)) + { + if (dump_file) + fprintf (dump_file, "Not splitting: function is a strub context.\n"); + return 0; + } /* We enforce splitting after loop headers when profile info is not available. */ diff --git a/gcc/ipa-strub.h b/gcc/ipa-strub.h new file mode 100644 index 0000000000000..29869fadfa6c9 --- /dev/null +++ b/gcc/ipa-strub.h @@ -0,0 +1,45 @@ +/* strub (stack scrubbing) infrastructure. + Copyright (C) 2021-2022 Free Software Foundation, Inc. + Contributed by Alexandre Oliva . + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Return TRUE if CALLEE can be inlined into CALLER, as far as stack scrubbing + constraints are concerned. CALLEE doesn't have to be called directly by + CALLER, but the returned value says nothing about intervening functions. */ +extern bool strub_inlinable_to_p (cgraph_node *callee, cgraph_node *caller); + +/* Return FALSE if NODE is a strub context, and TRUE otherwise. */ +extern bool strub_splittable_p (cgraph_node *node); + +/* Locate and return the watermark_ptr parameter for FNDECL. If FNDECL is not a + strub context, return NULL. */ +extern tree strub_watermark_parm (tree fndecl); + +/* Make a function type or declaration callable. */ +extern void strub_make_callable (tree fndecl); + +/* Return zero iff ID is NOT an acceptable parameter for a user-supplied strub + attribute for a function. Otherwise, return >0 if it enables strub, <0 if it + does not. Return +/-1 if the attribute-modified type is compatible with the + type without the attribute, or +/-2 if it is not compatible. */ +extern int strub_validate_fn_attr_parm (tree id); + +/* Like comptypes, return 0 if t1 and t2 are not compatible, 1 if they are + compatible, and 2 if they are nearly compatible. Same strub mode is + compatible, interface-compatible strub modes are nearly compatible. */ +extern int strub_comptypes (tree t1, tree t2); diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc index 3e2d26882c8e9..7cbd0a571e1ff 100644 --- a/gcc/multiple_target.cc +++ b/gcc/multiple_target.cc @@ -536,7 +536,7 @@ public: bool pass_target_clone::gate (function *) { - return true; + return !seen_error (); } } // anon namespace diff --git a/gcc/passes.def b/gcc/passes.def index 6bb92efacd451..513c5c29cd281 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3. If not see INSERT_PASSES_AFTER (all_small_ipa_passes) NEXT_PASS (pass_ipa_free_lang_data); NEXT_PASS (pass_ipa_function_and_variable_visibility); + NEXT_PASS (pass_ipa_strub_mode); NEXT_PASS (pass_build_ssa_passes); PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes) NEXT_PASS (pass_fixup_cfg); @@ -113,6 +114,7 @@ along with GCC; see the file COPYING3. If not see POP_INSERT_PASSES () NEXT_PASS (pass_ipa_remove_symbols); + NEXT_PASS (pass_ipa_strub); NEXT_PASS (pass_ipa_oacc); PUSH_INSERT_PASSES_WITHIN (pass_ipa_oacc) NEXT_PASS (pass_ipa_pta); diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc index 5bcf78198e78b..6144b9ee4fca4 100644 --- a/gcc/tree-cfg.cc +++ b/gcc/tree-cfg.cc @@ -5658,6 +5658,7 @@ gimple_verify_flow_info (void) { gimple *stmt = gsi_stmt (gsi); + /* Do NOT disregard debug stmts after found_ctrl_stmt. */ if (found_ctrl_stmt) { error ("control flow in the middle of basic block %d", diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 4dfe05ed8e0de..ecf1f9ef28b12 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -502,8 +502,9 @@ extern gimple_opt_pass *make_pass_adjust_alignment (gcc::context *ctxt); /* IPA Passes */ extern simple_ipa_opt_pass *make_pass_ipa_lower_emutls (gcc::context *ctxt); -extern simple_ipa_opt_pass - *make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt); +extern simple_ipa_opt_pass *make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt); +extern simple_ipa_opt_pass *make_pass_ipa_strub_mode (gcc::context *ctxt); +extern simple_ipa_opt_pass *make_pass_ipa_strub (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_tree_profile (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_auto_profile (gcc::context *ctxt); diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc index 85c046078249c..8d04e55ba6523 100644 --- a/gcc/tree-ssa-ccp.cc +++ b/gcc/tree-ssa-ccp.cc @@ -3054,7 +3054,9 @@ optimize_stack_restore (gimple_stmt_iterator i) if (!callee || !fndecl_built_in_p (callee, BUILT_IN_NORMAL) /* All regular builtins are ok, just obviously not alloca. */ - || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))) + || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)) + /* Do not remove stack updates before strub leave. */ + || fndecl_built_in_p (callee, BUILT_IN___STRUB_LEAVE)) return NULL_TREE; if (fndecl_built_in_p (callee, BUILT_IN_STACK_RESTORE))