From patchwork Tue Dec 8 17:11:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1412787 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=acm.org Authentication-Results: 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=20161025 header.b=Ebby4xS/; 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 4Cr6Cf48Bsz9sWR for ; Wed, 9 Dec 2020 04:11:24 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B1B38384607B; Tue, 8 Dec 2020 17:11:21 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by sourceware.org (Postfix) with ESMTPS id E92A3384A033 for ; Tue, 8 Dec 2020 17:11:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org E92A3384A033 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qt1-x831.google.com with SMTP id c14so2823166qtn.0 for ; Tue, 08 Dec 2020 09:11:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=PHXQSoN5XxujkFLj61XJFd23w4To5fyDUrGeo3DB6aQ=; b=Ebby4xS/9vd8enhAVsWrRALJ+d/wJ7WQ7Ly7rA7RL1qAWOLrflT0bnRD6RQ3WAup3e 2vzWSWxpF105PLTFW6KL9owhBwMDL+s+/koKcDBDTBBcDtpSiSXuHMECZU/cuhxBBm/M saaBnDngACat7xwMp8tqR/nM259kN6ZNSiQ+xoIb0gNW5ETkNYbRV0XV9A0yiwar3l/i af1w46UxGEuKbXIFUkCm18rEpz3JoOCAHK6BqHFLLOGzW1XdKkMjJZad+8js540l/++b MwUTtVWji3fvhazZrWjhuUCDNGgAHFcoT/GTiQguR/lfYoHENAVJwJlwkkVcUBwSNaan 88Xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=PHXQSoN5XxujkFLj61XJFd23w4To5fyDUrGeo3DB6aQ=; b=JW1O3EsF/kwtRuqR2qJ0zmlcBgK/JyP5M/tm9gqnKPLmwno+munZXyKKM9S4av0Aqy wvbcDchdf8SWsqWZgMLwIelLD+HX2ncOQixUV6seNQ7ZKQ9zrIArYZPwzhkF8X9mL0sv JZrlq1I0KIdRBjgGDkxdIf3RVCXlyYzxkqJI4AlPA+LTMuIn70zs0mclKYmulYViRFhY KBOW6zw7xX4gBUMJmnwgi8yF4P54xB/7TkJD6Adf5Bj31z3ndVofzpUphGc/HVZzrCl5 oBC2aod/XetGrgvZIuLcildnuOzdz7+eUpxyTKKHnloxwCyPvsA1jos1bXxaWbOo10CU NHpg== X-Gm-Message-State: AOAM531HGq7e7RfFBCBia1KRiugHG3Kz40OzahaEHWWqoK6Q761xlufm GdauwIgqxgiGJ9W4vhP0R3c= X-Google-Smtp-Source: ABdhPJwf8FdVQE4dPsPcTbYShCZXc9PwI5jEBwiDMVyRL4BjRxIHMXVYqqQ9q3BCjeY1Ibz5jnRUyA== X-Received: by 2002:ac8:5ac3:: with SMTP id d3mr31053939qtd.66.1607447477099; Tue, 08 Dec 2020 09:11:17 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:9e5:be57:d7de:21c6? ([2620:10d:c091:480::1:a476]) by smtp.googlemail.com with ESMTPSA id a28sm3735377qtm.80.2020.12.08.09.11.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 08 Dec 2020 09:11:15 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: c++: Named module global initializers Message-ID: <82e2e961-0a77-2084-4380-fa12bed1a192@acm.org> Date: Tue, 8 Dec 2020 12:11:14 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.4 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 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" C++ 20 modules adds some new rules about when the global initializers of imported modules run. They must run no later than before any initializers in the importer that appear after the import. To provide this, each named module emits an idempotent global initializer that calls the global initializer functions of its imports (these of course may call further import initializers). This is the machinery in our global-init emission to accomplish that, other than the actual emission of calls, which is in the module file. The naming of this global init is a new piece of the ABI. FWIW, the module's emitter does some optimization to avoid calling a direct import's initializer when it can determine thatr import is also indirect. gcc/cp/ * decl2.c (start_objects): Refactor and adjust for named module initializers. (finish_objects): Likewise. (generate_ctor_or_dtor_function): Likewise. * module.cc (module_initializer_kind) (module_add_import_initializers): Stubs. pushing to trunk diff --git i/gcc/cp/decl2.c w/gcc/cp/decl2.c index 46069cb66a6..e713033a7f4 100644 --- i/gcc/cp/decl2.c +++ w/gcc/cp/decl2.c @@ -3636,35 +3636,45 @@ generate_tls_wrapper (tree fn) static tree start_objects (int method_type, int initp) { - tree body; - tree fndecl; - char type[14]; - /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ + int module_init = 0; + + if (initp == DEFAULT_INIT_PRIORITY && method_type == 'I') + module_init = module_initializer_kind (); - if (initp != DEFAULT_INIT_PRIORITY) + tree name = NULL_TREE; + if (module_init > 0) + name = mangle_module_global_init (0); + else { - char joiner; + char type[14]; + unsigned len = sprintf (type, "sub_%c", method_type); + if (initp != DEFAULT_INIT_PRIORITY) + { + char joiner = '_'; #ifdef JOINER - joiner = JOINER; -#else - joiner = '_'; + joiner = JOINER; #endif + type[len++] = joiner; + sprintf (type + len, "%.5u", initp); + } + name = get_file_function_name (type); + } - sprintf (type, "sub_%c%c%.5u", method_type, joiner, initp); + tree fntype = build_function_type (void_type_node, void_list_node); + tree fndecl = build_lang_decl (FUNCTION_DECL, name, fntype); + DECL_CONTEXT (fndecl) = FROB_CONTEXT (global_namespace); + if (module_init > 0) + { + SET_DECL_ASSEMBLER_NAME (fndecl, name); + TREE_PUBLIC (fndecl) = true; + determine_visibility (fndecl); } else - sprintf (type, "sub_%c", method_type); - - fndecl = build_lang_decl (FUNCTION_DECL, - get_file_function_name (type), - build_function_type_list (void_type_node, - NULL_TREE)); + TREE_PUBLIC (fndecl) = 0; start_preparsed_function (fndecl, /*attrs=*/NULL_TREE, SF_PRE_PARSED); - TREE_PUBLIC (current_function_decl) = 0; - /* Mark as artificial because it's not explicitly in the user's source code. */ DECL_ARTIFICIAL (current_function_decl) = 1; @@ -3678,7 +3688,35 @@ start_objects (int method_type, int initp) else DECL_GLOBAL_DTOR_P (current_function_decl) = 1; - body = begin_compound_stmt (BCS_FN_BODY); + tree body = begin_compound_stmt (BCS_FN_BODY); + + if (module_init > 0) + { + // 'static bool __in_chrg = false; + // if (__inchrg) return; + // __inchrg = true + tree var = build_lang_decl (VAR_DECL, in_charge_identifier, + boolean_type_node); + DECL_CONTEXT (var) = fndecl; + DECL_ARTIFICIAL (var) = true; + TREE_STATIC (var) = true; + pushdecl (var); + cp_finish_decl (var, NULL_TREE, false, NULL_TREE, 0); + + tree if_stmt = begin_if_stmt (); + finish_if_stmt_cond (var, if_stmt); + finish_return_stmt (NULL_TREE); + finish_then_clause (if_stmt); + finish_if_stmt (if_stmt); + + tree assign = build2 (MODIFY_EXPR, boolean_type_node, + var, boolean_true_node); + TREE_SIDE_EFFECTS (assign) = true; + finish_expr_stmt (assign); + } + + if (module_init) + module_add_import_initializers (); return body; } @@ -3689,11 +3727,9 @@ start_objects (int method_type, int initp) static void finish_objects (int method_type, int initp, tree body) { - tree fn; - /* Finish up. */ finish_compound_stmt (body); - fn = finish_function (/*inline_p=*/false); + tree fn = finish_function (/*inline_p=*/false); if (method_type == 'I') { @@ -4228,50 +4264,50 @@ static void generate_ctor_or_dtor_function (bool constructor_p, int priority, location_t *locus) { - char function_key; - tree fndecl; - tree body; - size_t i; - input_location = *locus; - /* ??? */ - /* Was: locus->line++; */ /* We use `I' to indicate initialization and `D' to indicate destruction. */ - function_key = constructor_p ? 'I' : 'D'; + char function_key = constructor_p ? 'I' : 'D'; /* We emit the function lazily, to avoid generating empty global constructors and destructors. */ - body = NULL_TREE; + tree body = NULL_TREE; - /* For Objective-C++, we may need to initialize metadata found in this module. - This must be done _before_ any other static initializations. */ - if (c_dialect_objc () && (priority == DEFAULT_INIT_PRIORITY) - && constructor_p && objc_static_init_needed_p ()) + if (constructor_p && priority == DEFAULT_INIT_PRIORITY) { - body = start_objects (function_key, priority); - objc_generate_static_init_call (NULL_TREE); + bool objc = c_dialect_objc () && objc_static_init_needed_p (); + + /* We may have module initialization to emit and/or insert + before other intializations. */ + if (module_initializer_kind () || objc) + body = start_objects (function_key, priority); + + /* For Objective-C++, we may need to initialize metadata found + in this module. This must be done _before_ any other static + initializations. */ + if (objc) + objc_generate_static_init_call (NULL_TREE); } /* Call the static storage duration function with appropriate arguments. */ + tree fndecl; + size_t i; FOR_EACH_VEC_SAFE_ELT (ssdf_decls, i, fndecl) { /* Calls to pure or const functions will expand to nothing. */ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE))) { - tree call; - if (! body) body = start_objects (function_key, priority); - call = cp_build_function_call_nary (fndecl, tf_warning_or_error, - build_int_cst (NULL_TREE, - constructor_p), - build_int_cst (NULL_TREE, - priority), - NULL_TREE); + tree call = cp_build_function_call_nary (fndecl, tf_warning_or_error, + build_int_cst (NULL_TREE, + constructor_p), + build_int_cst (NULL_TREE, + priority), + NULL_TREE); finish_expr_stmt (call); } } diff --git i/gcc/cp/module.cc w/gcc/cp/module.cc index 9a5d73af20e..705804a5515 100644 --- i/gcc/cp/module.cc +++ w/gcc/cp/module.cc @@ -82,6 +82,17 @@ mangle_module_fini () { } +int +module_initializer_kind () +{ + return 0; +} + +void +module_add_import_initializers () +{ +} + int get_originating_module (tree, bool) {