From patchwork Mon Nov 22 09:30:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 47994 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 3732B3858422 for ; Mon, 22 Nov 2021 09:31:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3732B3858422 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637573464; bh=QtltkcIJOdg7FHYIUFw5dk6NnlQ8RxcjZGsGvkHMEow=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=EU0xuRsRS1aLJtDN12uOh6Ux1fdnCbuERWU+cR2CAtO5E3Pqe6Bf6301PyCUVg1UN QAIRF3daZ9fR6HUEUSrfibWf2uVlmPIKwlOqvpaI7THElHBrZ51Izkbj4dJDStSi7t u/a80ObvjsM5nZXzz0AdoIrvCDkhETpUowRO1DAo= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id E44C03858406 for ; Mon, 22 Nov 2021 09:30:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E44C03858406 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id B6E4A2809DA; Mon, 22 Nov 2021 10:30:28 +0100 (CET) Date: Mon, 22 Nov 2021 10:30:28 +0100 To: gcc-patches@gcc.gnu.org Subject: Improve modref tracking of base pointers Message-ID: <20211122093028.GD68091@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Jan Hubicka via Gcc-patches From: Jan Hubicka Reply-To: Jan Hubicka Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi, on exchange2 benchamrk we miss some useful propagation because modref gives up very early on analyzing accesses through pointers. For example in int test (int *a) { int i; for (i=0; a[i];i++); return i+a[i]; } We are not able to determine that a[i] accesses are relative to a. This is because get_access requires the SSA name that is in MEM_REF to be PARM_DECL while on other places we use ipa-prop helper to work out the proper base pointers. This patch commonizes the code in get_access and parm_map_for_arg so both use the check properly and extends it to also figure out that newly allocated memory is not a side effect to caller. It improves disambiguation rates: Alias oracle query stats: refs_may_alias_p: 77359588 disambiguations, 102170294 queries ref_maybe_used_by_call_p: 645390 disambiguations, 78392252 queries call_may_clobber_ref_p: 386653 disambiguations, 389576 queries stmt_kills_ref_p: 106470 kills, 5685744 queries nonoverlapping_component_refs_p: 0 disambiguations, 8923 queries nonoverlapping_refs_since_match_p: 30581 disambiguations, 65481 must overlaps, 97009 queries aliasing_component_refs_p: 56854 disambiguations, 15459249 queries TBAA oracle: 28236957 disambiguations 104812620 queries 15360807 are in alias set 0 8863925 queries asked about the same object 99 queries asked about the same alias set 0 access volatile 50367859 are dependent in the DAG 1982973 are aritificially in conflict with void * Modref stats: modref kill: 71 kills, 8151 queries modref use: 25273 disambiguations, 704264 queries modref clobber: 1676006 disambiguations, 21805867 queries 5264985 tbaa queries (0.241448 per modref query) 762265 base compares (0.034957 per modref query) PTA query stats: pt_solution_includes: 13460623 disambiguations, 40881373 queries pt_solutions_intersect: 1668037 disambiguations, 13958255 queries to: Alias oracle query stats: refs_may_alias_p: 77575173 disambiguations, 102390852 queries ref_maybe_used_by_call_p: 645932 disambiguations, 78607413 queries call_may_clobber_ref_p: 386813 disambiguations, 389693 queries stmt_kills_ref_p: 106551 kills, 5688432 queries nonoverlapping_component_refs_p: 0 disambiguations, 8936 queries nonoverlapping_refs_since_match_p: 30583 disambiguations, 65514 must overlaps, 97044 queries aliasing_component_refs_p: 56847 disambiguations, 15459371 queries TBAA oracle: 28238952 disambiguations 104938558 queries 15435200 are in alias set 0 8876784 queries asked about the same object 89 queries asked about the same alias set 0 access volatile 50400613 are dependent in the DAG 1986920 are aritificially in conflict with void * Modref stats: modref kill: 71 kills, 8130 queries modref use: 30684 disambiguations, 704287 queries modref clobber: 1694295 disambiguations, 21697882 queries 5233712 tbaa queries (0.241208 per modref query) 902240 base compares (0.041582 per modref query) PTA query stats: pt_solution_includes: 13495059 disambiguations, 40917961 queries pt_solutions_intersect: 1667032 disambiguations, 13951159 queries So 20% more modref use disambiguations which accounts to 0.3% overal disambiguation and alo improves a bit situation with exchange2 benchmark, while the real problem is still present (as dicussed in the pr) gcc/ChangeLog: 2021-11-21 Jan Hubicka PR ipa/103227 * ipa-modref.c (parm_map_for_arg): Rename to ... (parm_map_for_ptr): .. this one; handle static chain and calls to malloc functions. (modref_access_analysis::get_access): Use parm_map_for_ptr. (modref_access_analysis::process_fnspec): Update. (modref_access_analysis::analyze_load): Update. (modref_access_analysis::analyze_store): Update. gcc/testsuite/ChangeLog: 2021-11-21 Jan Hubicka PR ipa/103227 * gcc.dg/tree-ssa/modref-15.c: New test. diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index a04e5855a9a..4f9323165ea 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -812,14 +812,15 @@ ignore_stores_p (tree caller, int flags) return false; } -/* Determine parm_map for argument OP. */ +/* Determine parm_map for PTR which is supposed to be a pointer. */ modref_parm_map -parm_map_for_arg (tree op) +parm_map_for_ptr (tree op) { bool offset_known; poly_int64 offset; struct modref_parm_map parm_map; + gcall *call; parm_map.parm_offset_known = false; parm_map.parm_offset = 0; @@ -830,22 +831,26 @@ parm_map_for_arg (tree op) && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL) { int index = 0; - for (tree t = DECL_ARGUMENTS (current_function_decl); - t != SSA_NAME_VAR (op); t = DECL_CHAIN (t)) - { - if (!t) - { - index = MODREF_UNKNOWN_PARM; - break; - } + + if (cfun->static_chain_decl + && op == ssa_default_def (cfun, cfun->static_chain_decl)) + index = MODREF_STATIC_CHAIN_PARM; + else + for (tree t = DECL_ARGUMENTS (current_function_decl); + t != SSA_NAME_VAR (op); t = DECL_CHAIN (t)) index++; - } parm_map.parm_index = index; parm_map.parm_offset_known = offset_known; parm_map.parm_offset = offset; } else if (points_to_local_or_readonly_memory_p (op)) parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM; + /* Memory allocated in the function is not visible to caller before the + call and thus we do not need to record it as load/stores/kills. */ + else if (TREE_CODE (op) == SSA_NAME + && (call = dyn_cast(SSA_NAME_DEF_STMT (op))) != NULL + && gimple_call_flags (call) & ECF_MALLOC) + parm_map.parm_index = MODREF_LOCAL_MEMORY_PARM; else parm_map.parm_index = MODREF_UNKNOWN_PARM; return parm_map; @@ -955,33 +960,19 @@ modref_access_analysis::get_access (ao_ref *ref) if (TREE_CODE (base) == MEM_REF || TREE_CODE (base) == TARGET_MEM_REF) { tree memref = base; - base = TREE_OPERAND (base, 0); - - if (TREE_CODE (base) == SSA_NAME - && SSA_NAME_IS_DEFAULT_DEF (base) - && TREE_CODE (SSA_NAME_VAR (base)) == PARM_DECL) - { - a.parm_index = 0; - if (cfun->static_chain_decl - && base == ssa_default_def (cfun, cfun->static_chain_decl)) - a.parm_index = MODREF_STATIC_CHAIN_PARM; - else - for (tree t = DECL_ARGUMENTS (current_function_decl); - t != SSA_NAME_VAR (base); t = DECL_CHAIN (t)) - a.parm_index++; - } - else - a.parm_index = MODREF_UNKNOWN_PARM; + modref_parm_map m = parm_map_for_ptr (TREE_OPERAND (base, 0)); - if (a.parm_index != MODREF_UNKNOWN_PARM - && TREE_CODE (memref) == MEM_REF) + a.parm_index = m.parm_index; + if (a.parm_index != MODREF_UNKNOWN_PARM && TREE_CODE (memref) == MEM_REF) { a.parm_offset_known = wi::to_poly_wide (TREE_OPERAND (memref, 1)).to_shwi (&a.parm_offset); + if (a.parm_offset_known && m.parm_offset_known) + a.parm_offset += m.parm_offset; + else + a.parm_offset_known = false; } - else - a.parm_offset_known = false; } else a.parm_index = MODREF_UNKNOWN_PARM; @@ -1220,7 +1211,7 @@ modref_access_analysis::merge_call_side_effects parm_map.safe_grow_cleared (gimple_call_num_args (stmt), true); for (unsigned i = 0; i < gimple_call_num_args (stmt); i++) { - parm_map[i] = parm_map_for_arg (gimple_call_arg (stmt, i)); + parm_map[i] = parm_map_for_ptr (gimple_call_arg (stmt, i)); if (dump_file) { fprintf (dump_file, " %i", parm_map[i].parm_index); @@ -1236,7 +1227,7 @@ modref_access_analysis::merge_call_side_effects modref_parm_map chain_map; if (gimple_call_chain (stmt)) { - chain_map = parm_map_for_arg (gimple_call_chain (stmt)); + chain_map = parm_map_for_ptr (gimple_call_chain (stmt)); if (dump_file) { fprintf (dump_file, "static chain %i", chain_map.parm_index); @@ -1390,7 +1381,7 @@ modref_access_analysis::process_fnspec (gcall *call) else if (!fnspec.arg_specified_p (i) || fnspec.arg_maybe_read_p (i)) { - modref_parm_map map = parm_map_for_arg + modref_parm_map map = parm_map_for_ptr (gimple_call_arg (call, i)); if (map.parm_index == MODREF_LOCAL_MEMORY_PARM) @@ -1401,6 +1392,8 @@ modref_access_analysis::process_fnspec (gcall *call) break; } modref_access_node a = get_access_for_fnspec (call, fnspec, i, map); + if (a.parm_index == MODREF_LOCAL_MEMORY_PARM) + continue; if (m_summary) m_summary->loads->insert (0, 0, a, false); if (m_summary_lto) @@ -1419,7 +1412,7 @@ modref_access_analysis::process_fnspec (gcall *call) else if (!fnspec.arg_specified_p (i) || fnspec.arg_maybe_written_p (i)) { - modref_parm_map map = parm_map_for_arg + modref_parm_map map = parm_map_for_ptr (gimple_call_arg (call, i)); if (map.parm_index == MODREF_LOCAL_MEMORY_PARM) @@ -1430,6 +1423,8 @@ modref_access_analysis::process_fnspec (gcall *call) break; } modref_access_node a = get_access_for_fnspec (call, fnspec, i, map); + if (a.parm_index == MODREF_LOCAL_MEMORY_PARM) + continue; if (m_summary) m_summary->stores->insert (0, 0, a, false); if (m_summary_lto) @@ -1553,6 +1548,8 @@ modref_access_analysis::analyze_load (gimple *, tree, tree op, void *data) ao_ref r; ao_ref_init (&r, op); modref_access_node a = get_access (&r); + if (a.parm_index == MODREF_LOCAL_MEMORY_PARM) + return false; if (t->m_summary) t->record_access (t->m_summary->loads, &r, a); @@ -1581,6 +1578,8 @@ modref_access_analysis::analyze_store (gimple *stmt, tree, tree op, void *data) ao_ref r; ao_ref_init (&r, op); modref_access_node a = get_access (&r); + if (a.parm_index == MODREF_LOCAL_MEMORY_PARM) + return false; if (t->m_summary) t->record_access (t->m_summary->stores, &r, a); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-15.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-15.c new file mode 100644 index 00000000000..06881f2a760 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-15.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-modref1" } */ +int test (int *a) +{ + int i; + for (i=0; a[i];i++); + return i+a[i]; +} +/* { dg-final { scan-tree-dump "access: Parm 0" "modref1"} } */