From patchwork Tue Oct 13 09:18:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1381424 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C9VNQ6N0Jz9sTL for ; Tue, 13 Oct 2020 20:19:01 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1D60E38708B8; Tue, 13 Oct 2020 09:18:58 +0000 (GMT) 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 6E7E13857003 for ; Tue, 13 Oct 2020 09:18:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 6E7E13857003 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=hubicka@kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id DFD6C280BB3; Tue, 13 Oct 2020 11:18:52 +0200 (CEST) Date: Tue, 13 Oct 2020 11:18:52 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, mjambor@suse.cz, rguenther@suse.de Subject: Support ofsetted parameters in local modref Message-ID: <20201013091852.GA72371@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=-14.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, this patch makes local modref to track parameters that are passed through with and adjustment (via pointer_plus or addr_expr of mem_ref). I intended to re-use logic in ipa-prop, but it turns out that it is weird: if (TREE_CODE (op1) != ADDR_EXPR) return; op1 = TREE_OPERAND (op1, 0); if (TREE_CODE (TREE_TYPE (op1)) != RECORD_TYPE) return; base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse); offset_int mem_offset; if (!base || TREE_CODE (base) != MEM_REF || !mem_ref_offset (base).is_constant (&mem_offset)) return; offset += mem_offset.to_short_addr () * BITS_PER_UNIT; ssa = TREE_OPERAND (base, 0); if (TREE_CODE (ssa) != SSA_NAME || !SSA_NAME_IS_DEFAULT_DEF (ssa) || offset < 0) return; /* Dynamic types are changed in constructors and destructors. */ index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa)); if (index >= 0 && param_type && POINTER_TYPE_P (param_type)) ipa_set_ancestor_jf (jfunc, offset, index, parm_ref_data_pass_through_p (fbi, index, call, ssa)); First it does not handle POINTER_PLUS that is quite common i.e. for test (int *a) { test2 (a+1); } and also it restrict to access paths that starts by RECORD_TYPE. This seems not to make sense since all ADDR_EXPRs of refs are just pointer adjustements. I think it is leftover from time when ancestor was meant to track C++ type hiearchy. Next it also does refuse negative offset for not very apparent reason (this happens in multiple inheritance in C++). On tramp3d it is also common that the parameter ADDR_EXPR happens in separate statement rather than call itself (i.e. no forward propagation is done) Finally it works on bits witout overflow check and uses HOST_WIDE_INT instead of poly_int64 that I think would be right datatype to accumulate offsets these days. So I implemented my own pattern matching and I think we should switch ipa-prop on it incrementally. It is based on similar logic in ao_ref_init_from_ptr_and_size. I support chained statements since they happen in tramp3d after early opts. Bootstrapped/regtested x86_64-linux. Also ltobootstrapped and I am waiting for cc1plus stats to finish. OK? gcc/ChangeLog: 2020-10-13 Jan Hubicka * ipa-modref.c (merge_call_side_effects): Use unadjusted_ptr_and_unit_offset. * ipa-prop.c (unadjusted_ptr_and_unit_offset): Declare. * ipa-prop.h (unadjusted_ptr_and_unit_offset): New function. diff --git a/gcc/ipa-modref.c b/gcc/ipa-modref.c index 4f86b9ccea1..92119eb6fe3 100644 --- a/gcc/ipa-modref.c +++ b/gcc/ipa-modref.c @@ -531,6 +532,10 @@ merge_call_side_effects (modref_summary *cur_summary, for (unsigned i = 0; i < gimple_call_num_args (stmt); i++) { tree op = gimple_call_arg (stmt, i); + bool offset_known; + poly_int64 offset; + + offset_known = unadjusted_ptr_and_unit_offset (op, &op, &offset); if (TREE_CODE (op) == SSA_NAME && SSA_NAME_IS_DEFAULT_DEF (op) && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL) @@ -547,15 +552,23 @@ merge_call_side_effects (modref_summary *cur_summary, index++; } parm_map[i].parm_index = index; - parm_map[i].parm_offset_known = true; - parm_map[i].parm_offset = 0; + parm_map[i].parm_offset_known = offset_known; + parm_map[i].parm_offset = offset; } else if (points_to_local_or_readonly_memory_p (op)) parm_map[i].parm_index = -2; else parm_map[i].parm_index = -1; if (dump_file) - fprintf (dump_file, " %i", parm_map[i].parm_index); + { + fprintf (dump_file, " %i", parm_map[i].parm_index); + if (parm_map[i].parm_offset_known) + { + fprintf (dump_file, " offset:"); + print_dec ((poly_int64_pod)parm_map[i].parm_offset, + dump_file, SIGNED); + } + } } if (dump_file) fprintf (dump_file, "\n"); diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 2d09d913051..fe317f56e02 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -1222,6 +1222,72 @@ load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi, return index; } +/* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR) + to find original pointer. Initialize RET to the pointer which results from + the walk. + If offset is known return true and initialize OFFSET_RET. */ + +bool +unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret) +{ + poly_int64 offset = 0; + bool offset_known = true; + + while (true) + { + if (TREE_CODE (op) == ADDR_EXPR) + { + poly_int64 extra_offset = 0; + tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0), + &offset); + if (!base) + { + base = get_base_address (TREE_OPERAND (op, 0)); + if (TREE_CODE (base) != MEM_REF) + break; + offset_known = false; + } + else + { + if (TREE_CODE (base) != MEM_REF) + break; + offset += extra_offset; + } + op = TREE_OPERAND (base, 0); + if (mem_ref_offset (base).to_shwi (&extra_offset)) + offset += extra_offset; + else + offset_known = false; + } + else if (TREE_CODE (op) == SSA_NAME + && !SSA_NAME_IS_DEFAULT_DEF (op)) + { + gimple *pstmt = SSA_NAME_DEF_STMT (op); + + if (gimple_assign_single_p (pstmt)) + op = gimple_assign_rhs1 (pstmt); + else if (is_gimple_assign (pstmt) + && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR) + { + poly_int64 extra_offset = 0; + if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt), + &extra_offset)) + offset += extra_offset; + else + offset_known = false; + op = gimple_assign_rhs1 (pstmt); + } + else + break; + } + else + break; + } + *ret = op; + *offset_ret = offset; + return offset_known; +} + /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result of an assignment statement STMT, try to determine whether we are actually handling any of the following cases and construct an appropriate jump diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 8b2edf6300c..0bbbbf9bd9f 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -1144,6 +1144,8 @@ void ipa_dump_param (FILE *, class ipa_node_params *info, int i); void ipa_release_body_info (struct ipa_func_body_info *); tree ipa_get_callee_param_type (struct cgraph_edge *e, int i); bool ipcp_get_parm_bits (tree, tree *, widest_int *); +bool unadjusted_ptr_and_unit_offset (tree op, tree *ret, + poly_int64 *offset_ret); /* From tree-sra.c: */ tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree,