From patchwork Thu Sep 22 10:50:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 57890 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8B7193857C46 for ; Thu, 22 Sep 2022 10:52:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8B7193857C46 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663843926; bh=0i5uNjBcoPQ8sMQy2+iozDRio4FlB/IRbRPofHYPV1g=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=lKix3jOaGL6GBk0iJHEWUiCJ9Ko5rNFn6554p/qQdm/RHmeH4848ELFkWHHoIzgPv 7ADL8vAF4Sz2Q0g2m/gN5aEFztmRtTS1kuFpbpKLT8SoDZhPCCJUhWIDiXNqa/kvrA osgnVRVGNYvEXKOkICmecMF1NHseEB2tcuroqI/Q= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from smtp-out2.suse.de (smtp-out2.suse.de [IPv6:2001:67c:2178:6::1d]) by sourceware.org (Postfix) with ESMTPS id 1CE993858438 for ; Thu, 22 Sep 2022 10:50:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1CE993858438 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-out2.suse.de (Postfix) with ESMTPS id 009EE1F8C0 for ; Thu, 22 Sep 2022 10:50:54 +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 E298E1346B for ; Thu, 22 Sep 2022 10:50:53 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id UQRPNg0+LGNYKAAAMHmgww (envelope-from ) for ; Thu, 22 Sep 2022 10:50:53 +0000 Date: Thu, 22 Sep 2022 12:50:53 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] tree-optimization/99407 - DSE with data-ref analysis MIME-Version: 1.0 Message-Id: <20220922105053.E298E1346B@imap2.suse-dmz.suse.de> X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" The following resolves the issue that DSE cannot handle references with variable offsets well when identifying possible uses of a store. Instead of just relying on ref_maybe_used_by_stmt_p we use data-ref analysis, making sure to perform that at most once per stmt. The new mode is only exercised by the DSE pass before loop optimization as specified by a new pass parameter and when expensive optimizations are enabled, so it's disabled below -O2. Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. PR tree-optimization/99407 * tree-ssa-dse.c (dse_stmt_to_dr_map): New global. (dse_classify_store): Use data-ref analysis to disambiguate more uses. (pass_dse::use_dr_analysis_p): New pass parameter. (pass_dse::set_pass_param): Implement. (pass_dse::execute): Allocate and deallocate dse_stmt_to_dr_map. * gcc.dg/vect/tsvc/vect-tsvc-s243.c: Remove XFAIL. --- gcc/passes.def | 2 +- .../gcc.dg/vect/tsvc/vect-tsvc-s243.c | 2 +- gcc/tree-ssa-dse.cc | 51 ++++++++++++++++++- 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/gcc/passes.def b/gcc/passes.def index 6bb92efacd4..939ec3e29c8 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -263,7 +263,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_sancov); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); - NEXT_PASS (pass_dse); + NEXT_PASS (pass_dse, true /* use DR analysis */); NEXT_PASS (pass_dce); /* Pass group that runs when 1) enabled, 2) there are loops in the function. Make sure to run pass_fix_loops before diff --git a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c index 93618213c74..6eb0240da40 100644 --- a/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c +++ b/gcc/testsuite/gcc.dg/vect/tsvc/vect-tsvc-s243.c @@ -38,4 +38,4 @@ int main (int argc, char **argv) return 0; } -/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } } */ diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index 34cfd1a8802..2411ac711de 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -18,6 +18,7 @@ along with GCC; see the file COPYING3. If not see . */ #include "config.h" +#define INCLUDE_MEMORY #include "system.h" #include "coretypes.h" #include "backend.h" @@ -45,6 +46,8 @@ along with GCC; see the file COPYING3. If not see #include "ipa-modref.h" #include "target.h" #include "tree-ssa-loop-niter.h" +#include "cfgloop.h" +#include "tree-data-ref.h" /* This file implements dead store elimination. @@ -937,6 +940,10 @@ contains_phi_arg (gphi *phi, tree arg) return false; } +/* Hash map of the memory use in a GIMPLE assignment to its + data reference. If NULL data-ref analysis isn't used. */ +static hash_map *dse_stmt_to_dr_map; + /* A helper of dse_optimize_stmt. Given a GIMPLE_ASSIGN in STMT that writes to REF, classify it according to downstream uses and defs. Sets *BY_CLOBBER_P to true @@ -951,6 +958,8 @@ dse_classify_store (ao_ref *ref, gimple *stmt, gimple *temp; int cnt = 0; auto_bitmap visited; + std::unique_ptr + dra (nullptr, free_data_ref); if (by_clobber_p) *by_clobber_p = true; @@ -1019,6 +1028,28 @@ dse_classify_store (ao_ref *ref, gimple *stmt, /* If the statement is a use the store is not dead. */ else if (ref_maybe_used_by_stmt_p (use_stmt, ref)) { + if (dse_stmt_to_dr_map + && ref->ref + && is_gimple_assign (use_stmt)) + { + if (!dra) + dra.reset (create_data_ref (NULL, NULL, ref->ref, stmt, + false, false)); + bool existed_p; + data_reference_p &drb + = dse_stmt_to_dr_map->get_or_insert (use_stmt, &existed_p); + if (!existed_p) + drb = create_data_ref (NULL, NULL, + gimple_assign_rhs1 (use_stmt), + use_stmt, false, false); + if (!dr_may_alias_p (dra.get (), drb, NULL)) + { + if (gimple_vdef (use_stmt)) + defs.safe_push (use_stmt); + continue; + } + } + /* Handle common cases where we can easily build an ao_ref structure for USE_STMT and in doing so we find that the references hit non-live bytes and thus can be ignored. @@ -1535,14 +1566,21 @@ class pass_dse : public gimple_opt_pass { public: pass_dse (gcc::context *ctxt) - : gimple_opt_pass (pass_data_dse, ctxt) + : gimple_opt_pass (pass_data_dse, ctxt), use_dr_analysis_p (false) {} /* opt_pass methods: */ opt_pass * clone () final override { return new pass_dse (m_ctxt); } + void set_pass_param (unsigned n, bool param) final override + { + gcc_assert (n == 0); + use_dr_analysis_p = param; + } bool gate (function *) final override { return flag_tree_dse != 0; } unsigned int execute (function *) final override; +private: + bool use_dr_analysis_p; }; // class pass_dse unsigned int @@ -1554,6 +1592,8 @@ pass_dse::execute (function *fun) need_eh_cleanup = BITMAP_ALLOC (NULL); need_ab_cleanup = BITMAP_ALLOC (NULL); auto_sbitmap live_bytes (param_dse_max_object_size); + if (flag_expensive_optimizations && use_dr_analysis_p) + dse_stmt_to_dr_map = new hash_map; renumber_gimple_stmt_uids (fun); @@ -1644,6 +1684,15 @@ pass_dse::execute (function *fun) if (released_def) free_numbers_of_iterations_estimates (fun); + if (flag_expensive_optimizations && use_dr_analysis_p) + { + for (auto i = dse_stmt_to_dr_map->begin (); + i != dse_stmt_to_dr_map->end (); ++i) + free_data_ref ((*i).second); + delete dse_stmt_to_dr_map; + dse_stmt_to_dr_map = NULL; + } + return todo; }