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 [63.128.21.124]) by sourceware.org (Postfix) with ESMTP id 34565384A87E for ; Mon, 14 Dec 2020 18:07:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 34565384A87E Received: from mail-qk1-f199.google.com (mail-qk1-f199.google.com [209.85.222.199]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-518-aiJMQFSlNjKlvSDDYU61Ig-1; Mon, 14 Dec 2020 13:07:13 -0500 X-MC-Unique: aiJMQFSlNjKlvSDDYU61Ig-1 Received: by mail-qk1-f199.google.com with SMTP id 188so4426070qkh.7 for ; Mon, 14 Dec 2020 10:07:12 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=krB4QXNLJ1V3y2jOChCOozaeYg+pfzN55uyUTcX/uts=; b=XiFiJ/X16kNuW2IDr/B4PcxeIupKgi/O6/hujE0hcoRM91fkhqA7dYSG+bYSSf3S5K FvxhMpRzyfsUP9qDcCZjX94qdnXaHnQDftJ9xx6Kr3ARrCW4PFnknxba+JYGxXQ4bosu gZ8JL7Hu+5AtB/PLfZQwYSLqZHVfW6C+apRQUXG34sR+D/f719xK0yd6Qs83MFWgXmUb w7smFtYKadhWDcnjVatF/4yCEHnuwhp7EoY3ae8YLvquZ7T3mU2VU4dg9pauWC6rKZwi 3XACMSxnc03eBfM72R4gOhhIYyJZKCOviwFE66DmPlUuTY6+6XaKM5otmWZplCkALrc3 6yEw== X-Gm-Message-State: AOAM5326sCjrt+oY7Q5nwhuSvHJwIVGJbaSSzmLLMTDfavKdvMjhbOdr twUkX+W07ahGwou+ZcviQyXuFpKTW0Y42TMp8IA77h8PGffZotfEW3m8r+6aNkKps7epU3CbQ8S ULubfiMMNnQ0gWRRrbFbk0qR0Ybgan0+al8o8Xz49xVLQ/CcKhlsBcbnic/NvpNWp/O0= X-Received: by 2002:ac8:5790:: with SMTP id v16mr21925596qta.332.1607969231790; Mon, 14 Dec 2020 10:07:11 -0800 (PST) X-Google-Smtp-Source: ABdhPJyeJrf3xKxO7IY6BXRZABXYe6a024SxdT3efgMKI6g1Rj8h2G+LBLxbEgy8//6ArJdQnT4gSA== X-Received: by 2002:ac8:5790:: with SMTP id v16mr21925558qta.332.1607969231438; Mon, 14 Dec 2020 10:07:11 -0800 (PST) Received: from localhost.localdomain (ool-457d493a.dyn.optonline.net. [69.125.73.58]) by smtp.gmail.com with ESMTPSA id o21sm13902932qko.9.2020.12.14.10.07.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 14 Dec 2020 10:07:10 -0800 (PST) From: Patrick Palka To: gcc-patches@gcc.gnu.org Subject: [PATCH 4/1] c++: More precise tracking of potentially unstable satisfaction Date: Mon, 14 Dec 2020 13:07:04 -0500 Message-Id: <20201214180704.3346730-2-ppalka@redhat.com> X-Mailer: git-send-email 2.29.2.540.g3cf59784d4 In-Reply-To: <20201214180704.3346730-1-ppalka@redhat.com> References: <20201214180704.3346730-1-ppalka@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-16.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, 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: , X-List-Received-Date: Mon, 14 Dec 2020 18:07:17 -0000 This makes tracking of potentially unstable satisfaction results more precise by recording the specific types for which completion failed during satisfaction. We now recompute a satisfaction result only if one of these types has been completed since the last time we computed the satisfaction result. Thus the number of times that we recompute a satisfaction result is now bounded by the number of such incomplete types, rather than being effectively unbounded. This allows us to remove the invalid assumption in note_ftc_for_satisfaction that was added to avoid a compile time performance regression in cmcstl2 due to repeated re-computation of a satisfaction result that depended on completion of a permanently incomplete class template specialization. In order to continue to detect the instability in concepts-complete3.C, we also need to explicitly keep track of return type deduction failure alongside type completion failure. So this patch also adds a call to note_ftc_for_satisfaction in require_deduced_type. gcc/cp/ChangeLog: * constraint.cc (failed_type_completion_count): Remove. (failed_type_completions): Define. (note_failed_type_completion_for_satisfaction): Append the supplied argument to failed_type_completions. (some_type_complete_p): Define. (sat_entry::maybe_unstable): Replace with ... (sat_entry::ftc_begin, sat_entry::ftc_end): ... these. (satisfaction_cache::ftc_count): Replace with ... (satisfaction_cache::ftc_begin): ... this. (satisfaction_cache::satisfaction_cache): Adjust accordingly. (satisfaction_cache::get): Adjust accordingly, using some_type_complete_p. (satisfaction_cache::save): Adjust accordingly. (satisfy_declaration_constraints): Likewise. * decl.c (require_deduced_type): Call note_failed_type_completion_for_satisfaction. --- gcc/cp/constraint.cc | 89 +++++++++++++++++++++++++++----------------- gcc/cp/decl.c | 1 + 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index dc5c34e7e91..fd5d9429c9d 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -2374,26 +2374,44 @@ tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_ Constraint satisfaction ---------------------------------------------------------------------------*/ -/* A counter incremented by note_failed_type_completion_for_satisfaction(). - It's used by the satisfaction caches in order to flag "potentially unstable" - satisfaction results. */ +/* A vector of incomplete types (and declarations with undeduced return types), + appended to by note_failed_type_completion_for_satisfaction. The + satisfaction caches use this in order to keep track of "potentially unstable" + satisfaction results. -static unsigned failed_type_completion_count; + Since references to entries in vector are stored only in the GC-deletable + sat_cache, it's safe to make this deletable as well. */ -/* Called whenever a type completion failure occurs that definitely affects - the semantics of the program, by e.g. inducing substitution failure. */ +static GTY((deletable)) vec *failed_type_completions; + +/* Called whenever a type completion (or return type deduction) failure occurs + that definitely affects the semantics of the program, by e.g. inducing + substitution failure. */ void -note_failed_type_completion_for_satisfaction (tree type) -{ - gcc_checking_assert (!COMPLETE_TYPE_P (type)); - if (CLASS_TYPE_P (type) - && CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - /* After instantiation, a class template specialization that's - incomplete will remain incomplete, so for our purposes we can - ignore this completion failure event. */; - else - ++failed_type_completion_count; +note_failed_type_completion_for_satisfaction (tree t) +{ + gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t)) + || (DECL_P (t) && undeduced_auto_decl (t))); + vec_safe_push (failed_type_completions, t); +} + +/* Returns true if the range [BEGIN, END) of elements within the + failed_type_completions vector contains a complete type (or a declaration + with a non-placeholder return type). */ + +static bool +some_type_complete_p (int begin, int end) +{ + for (int i = begin; i < end; i++) + { + tree t = (*failed_type_completions)[i]; + if (TYPE_P (t) && COMPLETE_TYPE_P (t)) + return true; + if (DECL_P (t) && !undeduced_auto_decl (t)) + return true; + } + return false; } /* Hash functions and data types for satisfaction cache entries. */ @@ -2417,12 +2435,10 @@ struct GTY((for_user)) sat_entry performed. */ location_t location; - /* True if this satisfaction result is flagged as "potentially unstable", - i.e. the result might change at different points in the program if - recomputed from scratch (which would be ill-formed). This flag controls - whether to recompute a cached satisfaction result from scratch even when - evaluating quietly. */ - bool maybe_unstable; + /* The range of elements appended to the failed_type_completions vector + during computation of this satisfaction result, encoded as a begin/end + pair of offsets. */ + int ftc_begin, ftc_end; /* True if we want to diagnose the above instability when it's detected. We don't always want to do so, in order to avoid emitting duplicate @@ -2531,7 +2547,7 @@ struct satisfaction_cache sat_entry *entry; sat_info info; - unsigned ftc_count; + int ftc_begin; }; /* Constructor for the satisfaction_cache class. We're performing satisfaction @@ -2539,7 +2555,7 @@ struct satisfaction_cache satisfaction_cache ::satisfaction_cache (tree atom, tree args, sat_info info) - : entry(nullptr), info(info), ftc_count(failed_type_completion_count) + : entry(nullptr), info(info), ftc_begin(-1) { if (!sat_cache) sat_cache = hash_table::create_ggc (31); @@ -2578,7 +2594,7 @@ satisfaction_cache entry->args = args; entry->result = NULL_TREE; entry->location = input_location; - entry->maybe_unstable = false; + entry->ftc_begin = entry->ftc_end = -1; entry->diagnose_instability = false; if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom)) /* We always want to diagnose instability of an atom with an @@ -2616,10 +2632,16 @@ satisfaction_cache::get () return error_mark_node; } - if (info.noisy () || entry->maybe_unstable || !entry->result) + /* This satisfaction result is "potentially unstable" if a type for which + type completion failed during its earlier computation is now complete. */ + bool maybe_unstable = some_type_complete_p (entry->ftc_begin, + entry->ftc_end); + + if (info.noisy () || maybe_unstable || !entry->result) { /* We're computing the satisfaction result from scratch. */ entry->evaluating = true; + ftc_begin = vec_safe_length (failed_type_completions); return NULL_TREE; } else @@ -2667,11 +2689,11 @@ satisfaction_cache::save (tree result) if (info.quiet ()) { entry->result = result; - /* We heuristically flag this satisfaction result as potentially unstable - iff during its computation, completion of a type failed. Note that - this may also clear the flag if the result turned out to be - independent of the previously detected type completion failure. */ - entry->maybe_unstable = (ftc_count != failed_type_completion_count); + /* Record the list of relevant failed type completions that occurred + during (re)computation of the satisfaction result. */ + gcc_checking_assert (ftc_begin != -1); + entry->ftc_begin = ftc_begin; + entry->ftc_end = vec_safe_length (failed_type_completions); } return result; @@ -3120,7 +3142,7 @@ satisfy_declaration_constraints (tree t, sat_info info) norm = normalize_nontemplate_requirements (t, info.noisy ()); } - unsigned ftc_count = failed_type_completion_count; + unsigned ftc_count = vec_safe_length (failed_type_completions); tree result = boolean_true_node; if (norm) @@ -3136,8 +3158,7 @@ satisfy_declaration_constraints (tree t, sat_info info) /* True if this satisfaction is (heuristically) potentially unstable, i.e. if its result may depend on where in the program it was performed. */ bool maybe_unstable_satisfaction = false; - - if (ftc_count != failed_type_completion_count) + if (ftc_count != vec_safe_length (failed_type_completions)) /* Type completion failure occurred during satisfaction. The satisfaction result may (or may not) materially depend on the completeness of a type, so we consider it potentially unstable. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b56eb113fd6..6e8dd0b45fd 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -17869,6 +17869,7 @@ require_deduced_type (tree decl, tsubst_flags_t complain) /* We probably already complained about deduction failure. */; else if (complain & tf_error) error ("use of %qD before deduction of %", decl); + note_failed_type_completion_for_satisfaction (decl); return false; } return true; -- 2.29.2.540.g3cf59784d4