From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id CC1933857B89 for ; Thu, 7 Jul 2022 20:47:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CC1933857B89 Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-544-XPx79s8eNo28oyd0qbaxYA-1; Thu, 07 Jul 2022 16:47:08 -0400 X-MC-Unique: XPx79s8eNo28oyd0qbaxYA-1 Received: by mail-qk1-f200.google.com with SMTP id bm2-20020a05620a198200b006a5dac37fa2so18995569qkb.16 for ; Thu, 07 Jul 2022 13:47:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=Itjfu3KcXRbdxFG4gu3QXQIk15wQGUKgi942h5wTlBg=; b=KrkUfzClkb9svjuAGBWgo4g/fyhdOgTE3bgZ6U40QqjaKTthGJ9vF1e/ZIU0ztW2VZ Pif9T87P6cbNIftttGQbC8G/1s4KCkhRUFzbjvP/Za+ki4EGonI/cJcRV7MNBSlK/6Ox RBtvcfD7WoISldN4Kll0nKi45t8JWV7w7HdGqm+f+aYjB8DpsmFrwHFw2m26E/Z3ru6x wVnAVV9A5pcYCNFn87lECrESdF3RNtxE0uVrQTGbKmGde60DXGCSz+9KmLUrBBzMt5M8 jptaZozLZR+d2xsPct+nPslECzVmSWPPDe+i29i3ck7b0r297Vb8lgCwm/slOFk3C906 zGew== X-Gm-Message-State: AJIora8O7PjGtZAQbLu1oru5HxrQ8N6PaSYz98XdUEmd0ZWr0+xG4gPM 0/zRR1ZCa6n0mZ7er14jBg05aPQLhCs2Jdz5thtE7vSvz4ioQ40jvcxZgZUuJcfP4f6HV3LLhT4 b7cnztC+kR4idUNMs0ctHZojXyKR1gyzRjA== X-Received: by 2002:a0c:8cc4:0:b0:472:f9c0:9fc3 with SMTP id q4-20020a0c8cc4000000b00472f9c09fc3mr18091629qvb.29.1657226828037; Thu, 07 Jul 2022 13:47:08 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tMRUoLNngc6NIeetEtX0Vj7Zv7l2K9+qWEdsFUl6zNDP6jr2Xp1ylNaSAuqppw+DP6rRAg0YGl6NgGKj12O18= X-Received: by 2002:a0c:8cc4:0:b0:472:f9c0:9fc3 with SMTP id q4-20020a0c8cc4000000b00472f9c09fc3mr18091612qvb.29.1657226827803; Thu, 07 Jul 2022 13:47:07 -0700 (PDT) MIME-Version: 1.0 References: <20220707171436.1419387-1-jwakely@redhat.com> <0d01f096-d12a-c4f1-9917-7ef681154b5e@redhat.com> In-Reply-To: <0d01f096-d12a-c4f1-9917-7ef681154b5e@redhat.com> From: Jonathan Wakely Date: Thu, 7 Jul 2022 21:46:57 +0100 Message-ID: Subject: Re: [PATCH] c++: Define built-in for std::tuple_element [PR100157] To: Jason Merrill Cc: "libstdc++" , gcc Patches , Marek Polacek X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE, WEIRD_PORT autolearn=unavailable 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-List-Received-Date: Thu, 07 Jul 2022 20:47:17 -0000 On Thu, 7 Jul 2022 at 20:29, Jason Merrill wrote: > > On 7/7/22 13:14, Jonathan Wakely wrote: > > This adds a new built-in to replace the recursive class template > > instantiations done by traits such as std::tuple_element and > > std::variant_alternative. The purpose is to select the Nth type from a > > list of types, e.g. __builtin_type_pack_element(1, char, int, float) is > > int. > > > > For a pathological example tuple_element_t<1000, tuple<2000 types...>> > > the compilation time is reduced by more than 90% and the memory used by > > the compiler is reduced by 97%. In realistic examples the gains will be > > much smaller, but still relevant. > > > > Clang has a similar built-in, __type_pack_element, but that's a > > "magic template" built-in using <> syntax, which GCC doesn't support. So > > this provides an equivalent feature, but as a built-in function using > > parens instead of <>. I don't really like the name "type pack element" > > (it gives you an element from a pack of types) but the semi-consistency > > with Clang seems like a reasonable argument in favour of keeping the > > name. I'd be open to alternative names though, e.g. __builtin_nth_type > > or __builtin_type_at_index. > > > > > > The patch has some problems though ... > > > > FIXME 1: Marek pointed out that this this ICEs: > > template using type = __builtin_type_pack_element(sizeof(T), T...); > > type c; > > > > The sizeof(T) expression is invalid, because T is an unexpanded pack, > > but it's not rejected and instead crashes: > > > > ice.C: In substitution of 'template using type = __builtin_type_pack_element (sizeof (T), T ...) [with T = {int, char}]': > > ice.C:2:15: required from here > > ice.C:1:63: internal compiler error: in dependent_type_p, at cp/pt.cc:27490 > > 1 | template using type = __builtin_type_pack_element(sizeof(T), T...); > > | ^~~~~~~~~ > > 0xe13eea dependent_type_p(tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:27490 > > 0xeb1286 cxx_sizeof_or_alignof_type(unsigned int, tree_node*, tree_code, bool, bool) > > /home/jwakely/src/gcc/gcc/gcc/cp/typeck.cc:1912 > > 0xdf4fcc tsubst_copy_and_build(tree_node*, tree_node*, int, tree_node*, bool, bool) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:20582 > > 0xdd9121 tsubst_tree_list(tree_node*, tree_node*, int, tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:15587 > > 0xddb583 tsubst(tree_node*, tree_node*, int, tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:16056 > > 0xddcc9d tsubst(tree_node*, tree_node*, int, tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:16436 > > 0xdd6d45 tsubst_decl > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:15038 > > 0xdd952a tsubst(tree_node*, tree_node*, int, tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:15668 > > 0xdfb9a1 instantiate_template(tree_node*, tree_node*, int) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:21811 > > 0xdfc1b6 instantiate_alias_template > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:21896 > > 0xdd9796 tsubst(tree_node*, tree_node*, int, tree_node*) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:15696 > > 0xdbaba5 lookup_template_class(tree_node*, tree_node*, tree_node*, tree_node*, int, int) > > /home/jwakely/src/gcc/gcc/gcc/cp/pt.cc:10131 > > 0xe4bac0 finish_template_type(tree_node*, tree_node*, int) > > /home/jwakely/src/gcc/gcc/gcc/cp/semantics.cc:3727 > > 0xd334c8 cp_parser_template_id > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:18458 > > 0xd429b0 cp_parser_class_name > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:25923 > > 0xd1ade9 cp_parser_qualifying_entity > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:7193 > > 0xd1a2c8 cp_parser_nested_name_specifier_opt > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:6875 > > 0xd4eefd cp_parser_template_introduction > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:31668 > > 0xd4f416 cp_parser_template_declaration_after_export > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:31840 > > 0xd2d60e cp_parser_declaration > > /home/jwakely/src/gcc/gcc/gcc/cp/parser.cc:15083 > > > > > > FIXME 2: I want to mangle __builtin_type_pack_element(N, T...) the same as > > typename std::_Nth_type::type but I don't know how. Instead of > > trying to fake the mangled string, it's probably better to build a decl > > for that nested type, right? Any suggestions where to find something > > similar I can learn from? > > The tricky thing is dealing with mangling compression, where we use a > substitution instead of repeating a type; that's definitely easier if we > actually have the type. Yeah, that's what I discovered when trying to fudge it as "19__builtin_type_pack_elementE" etc. > So you'd probably want to have a declaration of std::_Nth_type to work > with, and lookup_template_class to get the type of that specialization. > And then if it's complete, look up ...::type; if not, we could > probably stuff a ...::type in its TYPE_FIELDS that would get clobbered > if we actually instantiated the type... > > > The reason to mangle it that way is that it preserves the same symbol > > names as the library produced in GCC 12, and that it will still produce > > with non-GCC compilers (see the definitions of std::_Nth_type in the > > library parts of the patch). If we don't do that then either we need to > > ensure it never appears in a mangled name, or define some other > > GCC-specific mangling for this built-in (e.g. we could just mangle it as > > though it's a function, "19__builtin_type_pack_elementELm1EJDpT_E" or > > something like that!). If we ensure it doesn't appear in mangled names > > that means we still need to instantiate the _Nth_type class template, > > rather than defining the alias template _Nth_type_t to use the built-in > > directly. That loses a little of the compilation performance gain that > > comes from defining the built-in in the first place (although avoid the > > recusrion is the biggest gain, which we'd still get). > > ...but this seems a lot simpler. Yeah, it works fine, and if the built-in ever accidentally creeps into a mangled name we get a sorry, not an incorrect mangling. OK, I'll keep it simple. I'll try Marek's fix for the ICE and will not worry about mangling for now. We can revisit later if we decide to care more about it.