From patchwork Mon Aug 29 14:38:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 815 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:ecc5:0:0:0:0:0 with SMTP id s5csp1448425wro; Mon, 29 Aug 2022 07:39:08 -0700 (PDT) X-Google-Smtp-Source: AA6agR4FbpHzw1zoCqNTELDGd+i4+AY3gC3W7gXStIySefuA0hT42XN13YE1wm/iovkkXI2v9FFk X-Received: by 2002:a17:906:974b:b0:733:10e:b940 with SMTP id o11-20020a170906974b00b00733010eb940mr13884160ejy.326.1661783948749; Mon, 29 Aug 2022 07:39:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661783948; cv=none; d=google.com; s=arc-20160816; b=V57tQx0dHfD++CCLJ/mWrJOpQCNThPOCOGOSux0JBwxj5dp4s746/c2p7tPKs4sT3q NCdcCyOZr+aHVep6cTZNVd8UzYicptzRcoBHYA/8YwLfUnvFmfaKwqF0/+a7alw+FyDn qv3w9sH/y0GQMWItOBbL0OrVBH8yd07RY3yT0FVsDNAWuMI9qAUat3orqVEiJUcrBD39 s2leZsNk/dmhn9vSv5EVLtFAbh3i9/YpD/V85a8i84h93+N9mbrfL7ndUUTkwVco0vmp 4NdIS2lRt9FN64tWlLq99YlaCphO26dxbBsNNo8HqzyRsNaaAiI7AIISXfmSajEiIUE/ ALDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:message-id :mime-version:subject:to:date:dmarc-filter:delivered-to :dkim-signature:dkim-filter; bh=dY15tBUW9izJd+X+9guOZrtJzOrSKWNPcCyTjWVo43s=; b=dcj74Zn4ugvn8UZgGCDWqxKe9nzmDtve4WHlwh/Fq3aEYK/jYi48V0BFghlUU0I+/h Xx86eEDgVXht32nIAFCnsbwuhtL8qFWeFxkaJx9YV+oN+LXHdVUm3j6wRj/FHXuwkdBd fyKRNy1mOD4Rawx0pkZypZVBKuhOSyxMY5cv8DC9f6h2TJxWqdVEfcQCkZYpex48K2QB 8BHdzWWfTUvl10eJaFaq1oKDYtfl6WExbP3PxereUTS/bHFYEomqJtQLPK4hEFLHrEFL Bxo0+S33605B4a/xvlIQKvTmG4q1FtxW+RkE8Y57jJONK69TNIgIg6pksJE128ZdFGMS ai1w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kXdoYbPU; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id l18-20020a1709067d5200b0073d8ccd2bacsi6177647ejp.116.2022.08.29.07.39.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Aug 2022 07:39:08 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=kXdoYbPU; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3CB0338582BA for ; Mon, 29 Aug 2022 14:38:58 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3CB0338582BA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661783938; bh=dY15tBUW9izJd+X+9guOZrtJzOrSKWNPcCyTjWVo43s=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=kXdoYbPUvI2COg8FycTDeXIDlVjvPApEiTzsXjzJyR7sT2NPT6H0Y1Pbuhy+ROwjC Dq1OVeuVq+CmTacsZwYb3qspqzrgqRFAxY/u7QPMyj2S5+vQ0ElayZWR0sjjn9jRbb dx7nLN2Bh/U4WRL71PtiBSTXoaQo7VDpInfPdUGc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out1.suse.de (smtp-out1.suse.de [IPv6:2001:67c:2178:6::1c]) by sourceware.org (Postfix) with ESMTPS id 3BE223858D32 for ; Mon, 29 Aug 2022 14:38:13 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3BE223858D32 Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 1935F336A6 for ; Mon, 29 Aug 2022 14:38:11 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 0620D133A6 for ; Mon, 29 Aug 2022 14:38:11 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id wzlNAFPPDGMLcQAAMHmgww (envelope-from ) for ; Mon, 29 Aug 2022 14:38:11 +0000 Date: Mon, 29 Aug 2022 16:38:10 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/56654 - sort uninit candidates after RPO MIME-Version: 1.0 Message-Id: <20220829143811.0620D133A6@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_PASS, 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-Patchwork-Original-From: Richard Biener via Gcc-patches From: Richard Biener Reply-To: Richard Biener Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1742506765773456745?= X-GMAIL-MSGID: =?utf-8?q?1742506765773456745?= The following sorts the immediate uses of a possibly uninitialized SSA variable after their RPO order so we prefer warning for an earlier occuring use rather than issueing the diagnostic for the first uninitialized immediate use. The sorting will inevitably be imperfect but it also allows us to optimize the expensive predicate check for the case where there are multiple uses in the same basic-block which is a nice side-effect. Bootstrap and regtest running on x86_64-unknown-linux-gnu. PR tree-optimization/56654 * tree-ssa-uninit.cc (cand_cmp): New. (find_uninit_use): First process all PHIs and collect candidate stmts, then sort those after RPO. (warn_uninitialized_phi): Pass on bb_to_rpo. (execute_late_warn_uninitialized): Compute and pass on reverse lookup of RPO number from basic block index. --- gcc/tree-ssa-uninit.cc | 92 ++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 31 deletions(-) diff --git a/gcc/tree-ssa-uninit.cc b/gcc/tree-ssa-uninit.cc index 3e5816f1ebb..0bd567f237c 100644 --- a/gcc/tree-ssa-uninit.cc +++ b/gcc/tree-ssa-uninit.cc @@ -1154,6 +1154,21 @@ uninit_undef_val_t::phi_arg_set (gphi *phi) return compute_uninit_opnds_pos (phi); } +/* sort helper for find_uninit_use. */ + +static int +cand_cmp (const void *a, const void *b, void *data) +{ + int *bb_to_rpo = (int *)data; + const gimple *sa = *(const gimple * const *)a; + const gimple *sb = *(const gimple * const *)b; + if (bb_to_rpo[gimple_bb (sa)->index] < bb_to_rpo[gimple_bb (sb)->index]) + return -1; + else if (bb_to_rpo[gimple_bb (sa)->index] > bb_to_rpo[gimple_bb (sb)->index]) + return 1; + return 0; +} + /* Searches through all uses of a potentially uninitialized variable defined by PHI and returns a use statement if the use is not properly guarded. It returns @@ -1161,7 +1176,7 @@ uninit_undef_val_t::phi_arg_set (gphi *phi) holding the position(s) of uninit PHI operands. */ static gimple * -find_uninit_use (gphi *phi, unsigned uninit_opnds) +find_uninit_use (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo) { /* The Boolean predicate guarding the PHI definition. Initialized lazily from PHI in the first call to is_use_guarded() and cached @@ -1169,54 +1184,70 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds) uninit_undef_val_t eval; uninit_analysis def_preds (eval); + /* First process PHIs and record other candidates. */ + auto_vec cands; use_operand_p use_p; imm_use_iterator iter; tree phi_result = gimple_phi_result (phi); - gimple *uninit_use = NULL; FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result) { gimple *use_stmt = USE_STMT (use_p); if (is_gimple_debug (use_stmt)) continue; - basic_block use_bb; if (gphi *use_phi = dyn_cast (use_stmt)) { - edge e = gimple_phi_arg_edge (use_phi, - PHI_ARG_INDEX_FROM_USE (use_p)); - use_bb = e->src; + unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p); + edge e = gimple_phi_arg_edge (use_phi, idx); /* Do not look for uses in the next iteration of a loop, predicate analysis will not use the appropriate predicates to prove reachability. */ if (e->flags & EDGE_DFS_BACK) continue; - } - else if (uninit_use) - /* Only process the first real uninitialized use, but continue - looking for unguarded uses in PHIs. */ - continue; - else - use_bb = gimple_bb (use_stmt); - if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds)) - { - /* For a guarded use in a PHI record the PHI argument as - initialized. */ - if (gphi *use_phi = dyn_cast (use_stmt)) + basic_block use_bb = e->src; + if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds)) { - unsigned idx = PHI_ARG_INDEX_FROM_USE (use_p); + /* For a guarded use in a PHI record the PHI argument as + initialized. */ if (idx < uninit_analysis::func_t::max_phi_args) { bool existed_p; auto &def_mask - = defined_args->get_or_insert (use_phi, &existed_p); + = defined_args->get_or_insert (use_phi, &existed_p); if (!existed_p) def_mask = 0; MASK_SET_BIT (def_mask, idx); } + continue; } - continue; + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Found unguarded use in bb %u: ", + use_bb->index); + print_gimple_stmt (dump_file, use_stmt, 0); + } + /* Found a phi use that is not guarded, mark the phi_result as + possibly undefined. */ + possibly_undefined_names->add (phi_result); } + else + cands.safe_push (use_stmt); + } + + /* Sort candidates after RPO. */ + cands.stablesort (cand_cmp, bb_to_rpo); + basic_block use_bb = NULL; + for (gimple *use_stmt : cands) + { + /* We only have to try diagnosing the first use in each block. */ + if (gimple_bb (use_stmt) == use_bb) + continue; + + use_bb = gimple_bb (use_stmt); + if (def_preds.is_use_guarded (use_stmt, use_bb, phi, uninit_opnds)) + continue; if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1224,15 +1255,10 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds) use_bb->index); print_gimple_stmt (dump_file, use_stmt, 0); } - /* Found a phi use that is not guarded, mark the phi_result as - possibly undefined. */ - if (is_a (use_stmt)) - possibly_undefined_names->add (phi_result); - else - uninit_use = use_stmt; + return use_stmt; } - return uninit_use; + return NULL; } /* Look for inputs to PHI that are SSA_NAMEs that have empty definitions @@ -1242,7 +1268,7 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds) by the compiler, the fewer false positives the warning is. */ static void -warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds) +warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds, int *bb_to_rpo) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -1250,7 +1276,7 @@ warn_uninitialized_phi (gphi *phi, unsigned uninit_opnds) print_gimple_stmt (dump_file, phi, 0); } - gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds); + gimple *uninit_use_stmt = find_uninit_use (phi, uninit_opnds, bb_to_rpo); /* All uses are properly guarded. */ if (!uninit_use_stmt) @@ -1336,6 +1362,9 @@ execute_late_warn_uninitialized (function *fun) mark_dfs_back_edges (fun); int *rpo = XNEWVEC (int, n_basic_blocks_for_fn (fun)); int n = pre_and_rev_post_order_compute_fn (fun, NULL, rpo, false); + int *bb_to_rpo = XNEWVEC (int, last_basic_block_for_fn (fun)); + for (int i = 0; i < n; ++i) + bb_to_rpo[rpo[i]] = i; /* Re-do the plain uninitialized variable check, as optimization may have straightened control flow. Do this first so that we don't accidentally @@ -1365,10 +1394,11 @@ execute_late_warn_uninitialized (function *fun) if (MASK_EMPTY (uninit_opnds)) continue; - warn_uninitialized_phi (phi, uninit_opnds); + warn_uninitialized_phi (phi, uninit_opnds, bb_to_rpo); } free (rpo); + free (bb_to_rpo); delete possibly_undefined_names; possibly_undefined_names = NULL; delete defined_args;