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 713C93857806 for ; Mon, 27 Jun 2022 16:31:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 713C93857806 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-524-GgcV1N_FMF2Vyt__k9p9jA-1; Mon, 27 Jun 2022 12:31:22 -0400 X-MC-Unique: GgcV1N_FMF2Vyt__k9p9jA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D008C811E75 for ; Mon, 27 Jun 2022 16:31:21 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.30]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8B9092166B26; Mon, 27 Jun 2022 16:31:21 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 25RGVIu21931540 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 27 Jun 2022 18:31:19 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 25RGVIwL1931539; Mon, 27 Jun 2022 18:31:18 +0200 Date: Mon, 27 Jun 2022 18:31:18 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: Re: [PATCH] c++, v2: Add support for __real__/__imag__ modifications in constant expressions [PR88174] Message-ID: Reply-To: Jakub Jelinek References: <4d9319d5-1890-7c99-6c1b-d940f873a590@redhat.com> <38ccc92a-6772-75d9-1ac9-fc3252734291@redhat.com> MIME-Version: 1.0 In-Reply-To: <38ccc92a-6772-75d9-1ac9-fc3252734291@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-3.8 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 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-List-Received-Date: Mon, 27 Jun 2022 16:31:24 -0000 On Mon, Jun 20, 2022 at 04:03:50PM -0400, Jason Merrill wrote: > > + if (code == COMPLEX_TYPE) > > + { > > + if (TREE_CODE (*valp) == COMPLEX_CST) > > + *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp), > > + TREE_IMAGPART (*valp)); > > + else if (TREE_CODE (*valp) == CONSTRUCTOR > > + && CONSTRUCTOR_NELTS (*valp) == 0 > > + && CONSTRUCTOR_NO_CLEARING (*valp)) > > + { > > + tree r = build_constructor (reftype, NULL); > > + CONSTRUCTOR_NO_CLEARING (r) = 1; > > + *valp = build2 (COMPLEX_EXPR, type, r, r); > > + } > > + gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR); > > + ctors.safe_push (valp); > > + vec_safe_push (indexes, index); > > + valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR); > > + gcc_checking_assert (refs->is_empty ()); > > + type = reftype; > > + break; > > + } ... > > @@ -5949,6 +5986,28 @@ cxx_eval_store_expression (const constex > > valp = ctx->global->values.get (object); > > for (unsigned i = 0; i < vec_safe_length (indexes); i++) > > { > > + ctors[i] = valp; > > + if (TREE_CODE (indexes[i]) == REALPART_EXPR > > + || TREE_CODE (indexes[i]) == IMAGPART_EXPR) > > + { > > + if (TREE_CODE (*valp) == COMPLEX_CST) > > + *valp = build2 (COMPLEX_EXPR, TREE_TYPE (*valp), > > + TREE_REALPART (*valp), > > + TREE_IMAGPART (*valp)); > > + else if (TREE_CODE (*valp) == CONSTRUCTOR > > + && CONSTRUCTOR_NELTS (*valp) == 0 > > + && CONSTRUCTOR_NO_CLEARING (*valp)) > > + { > > + tree r = build_constructor (TREE_TYPE (TREE_TYPE (*valp)), > > + NULL); > > + CONSTRUCTOR_NO_CLEARING (r) = 1; > > + *valp = build2 (COMPLEX_EXPR, TREE_TYPE (*valp), r, r); > > + } > > + gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR); > > + valp = &TREE_OPERAND (*valp, > > + TREE_CODE (indexes[i]) == IMAGPART_EXPR); > > + break; > > + } > > Hmm, why do we need to handle complex in the !preeval case? I'd think we > want to preevaluate all complex values or components thereof. Because the late evaluation of the initializer could have touched the destination, so we need to reevaluate it. Same reason why we call get_or_insert_ctor_field again in the second loop as we call it in the first loop. If it would help, I could move that repeated part into: tree canonicalize_complex_to_complex_expr (tree t) { if (TREE_CODE (t) == COMPLEX_CST) t = build2 (COMPLEX_EXPR, TREE_TYPE (t), TREE_REALPART (t), TREE_IMAGPART (t)); else if (TREE_CODE (t) == CONSTRUCTOR && CONSTRUCTOR_NELTS (t) == 0 && CONSTRUCTOR_NO_CLEARING (t)) { tree r = build_constructor (TREE_TYPE (TREE_TYPE (t)), NULL); CONSTRUCTOR_NO_CLEARING (r) = 1; t = build2 (COMPLEX_EXPR, TREE_TYPE (t), r, r); } return t; } and use that to shorten the code. > > > constructor_elt *cep > > = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]); > > valp = &cep->value; > > @@ -6012,17 +6071,41 @@ cxx_eval_store_expression (const constex > > bool c = TREE_CONSTANT (init); > > bool s = TREE_SIDE_EFFECTS (init); > > if (!c || s || activated_union_member_p) > > - for (tree elt : *ctors) > > + for (tree *elt : ctors) > > { > > + if (TREE_CODE (*elt) != CONSTRUCTOR) > > + continue; > > if (!c) > > - TREE_CONSTANT (elt) = false; > > + TREE_CONSTANT (*elt) = false; > > if (s) > > - TREE_SIDE_EFFECTS (elt) = true; > > + TREE_SIDE_EFFECTS (*elt) = true; > > /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of > > this union. */ > > - if (TREE_CODE (TREE_TYPE (elt)) == UNION_TYPE) > > - CONSTRUCTOR_NO_CLEARING (elt) = false; > > + if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE) > > + CONSTRUCTOR_NO_CLEARING (*elt) = false; > > } > > + if (!indexes->is_empty ()) > > + { > > + tree last = indexes->last (); > > + if (TREE_CODE (last) == REALPART_EXPR > > + || TREE_CODE (last) == IMAGPART_EXPR) > > + { > > + tree *cexpr = ctors.last (); > > + if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr), > > + TREE_OPERAND (*cexpr, 0), > > + TREE_OPERAND (*cexpr, 1))) > > + *cexpr = c; > > + else > > + { > > + TREE_CONSTANT (*cexpr) > > + = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0)) > > + & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1))); > > + TREE_SIDE_EFFECTS (*cexpr) > > + = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0)) > > + | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1))); > > This seems like it needs to come before the ctors loop, so that these flags > can be propagated out to enclosing constructors. I could indeed move this in between bool c = TREE_CONSTANT (init); bool s = TREE_SIDE_EFFECTS (init); and if (!c || s || activated_union_member_p) and update c and s from *cexpr flags. Jakub