From patchwork Mon Oct 24 23:18:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kugan Vivekanandarajah X-Patchwork-Id: 79106 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp2832071qge; Mon, 24 Oct 2016 16:18:51 -0700 (PDT) X-Received: by 10.98.149.149 with SMTP id c21mr33954335pfk.100.1477351131420; Mon, 24 Oct 2016 16:18:51 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id y14si17761960pgc.57.2016.10.24.16.18.51 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Oct 2016 16:18:51 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439460-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439460-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439460-patch=linaro.org@gcc.gnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:message-id:date:mime-version:content-type; q=dns; s= default; b=RvwNGSHtdJ41iSrO+19kcTvQAfJh5JyskAC7NQOzF/+G+ginlYNrP ZQfO8rFAYKjIF5rpI37VUPvthffHKxV5ReIsMSN5xp8HRlAyrttoryJ0j7VaII7a 7wX5bCvgC70sy58BpiudIfeGRYJrylFR5p62ddmfuHY8oqsxUWOTxE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:message-id:date:mime-version:content-type; s= default; bh=BStj9l4lVWqtjn3gUXZe55unB+s=; b=tUtKSfxWE7IZkjGB/kwD o21fWBwHNW6uGlFjTBVcoJa13brltn+pBxh+jTUjffwE2kTcxMjxyAKwAw78W/dY ijD154cObw1S5dUSyv0azs9rOtA2eY6CbH5cJ5V/8Bn9dzg5DTVIKG8BGBL45A3x bfvIQbkmnXlyhP8OtDKU8PQ= Received: (qmail 66581 invoked by alias); 24 Oct 2016 23:18:35 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 66558 invoked by uid 89); 24 Oct 2016 23:18:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=fbi, UD:gimple.h, gimple.h, gimpleh X-HELO: mail-pf0-f175.google.com Received: from mail-pf0-f175.google.com (HELO mail-pf0-f175.google.com) (209.85.192.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 24 Oct 2016 23:18:31 +0000 Received: by mail-pf0-f175.google.com with SMTP id s8so106702220pfj.2 for ; Mon, 24 Oct 2016 16:18:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:message-id:date:user-agent :mime-version; bh=wMB+CDU7YTPqQtcPC45sRu35qnw0qI0M2y/0WaEnzfw=; b=cBaye2LSqCDPRqMZmzcN7C1OEeHKVr+lwYlpzRYfh6eCfw7E4O3iM27sL4D6Hok2fN 5XAMNg1Fakd67SGEJXVtfihaqwjSMh4yY7yQypg/CHJ+pU5FXPcOA2b1HapK/r3Naxk0 7/svQYMjZ7BywvzFfRb+M5S0YMTryVHjHG3Dsbbk6aKSBCrx4SwsobqGKfrE+1sH7306 TYYXUXr4d6Q3A/syzkI8LlLGHdBs3nnAz68xBhtWGaqf/wmeKv6AUW8yagnynISxaK11 O+7IjAsLzTOTDa2vcVUYKjGiSFLKN+ImwgALllk+Abhw7LLJdtI1nE00ae2U+sUVCPFO PCpQ== X-Gm-Message-State: ABUngven6QHheDgokhwPLnaLiOSb2TO1oSP9IrbT83zgC55L8yOEZYl971SSf78vDeiYlHqM X-Received: by 10.99.161.2 with SMTP id b2mr17574266pgf.5.1477351109958; Mon, 24 Oct 2016 16:18:29 -0700 (PDT) Received: from [10.1.1.7] (58-6-183-210.dyn.iinet.net.au. [58.6.183.210]) by smtp.gmail.com with ESMTPSA id b139sm27824753pfb.8.2016.10.24.16.18.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 24 Oct 2016 16:18:29 -0700 (PDT) From: kugan To: "gcc-patches@gcc.gnu.org" , Jan Hubicka , Martin Jambor Subject: [RFC] Handle unary pass-through jump functions for ipa-vrp Message-ID: <1549ba52-153b-6bf1-28f6-5a1d2a2562fd@linaro.org> Date: Tue, 25 Oct 2016 10:18:25 +1100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, Attached RFC patch handles unary pass-through jump functions for ipa-vrp such that in the following case: int bar (int j) { foo (~j); foo (abs (j)); foo (j); return 0; } We can infer value ranges for argument foo from bar. See test-case vrp7.c in the patch. I will also try to handle other passes like constant propagation as follow up based on the comments. LTO bootstrapped and regression tested on x86_64-linux-gnu with no new regressions. Does this look OK? Thanks, Kugan gcc/testsuite/ChangeLog: 2016-10-25 Kugan Vivekanandarajah * gcc.dg/ipa/vrp7.c: New test. gcc/ChangeLog: 2016-10-25 Kugan Vivekanandarajah * ipa-cp.c (ipa_get_jf_pass_through_result): Skip unary expressions. (propagate_vr_accross_jump_function): Handle unary expressions. (propagate_constants_accross_call): Pass param type to propagate_vr_accross_jump_function. * ipa-prop.c (load_from_param): Renamed from load_from_unmodified_param. Also handles unary expr. (ipa_set_jf_unary_pass_through): New. (ipa_load_from_parm_agg): Renamed load_from_unmodified_param. (compute_complex_assign_jump_func): Handle unary expressions. (ipa_write_jump_function): Likewise. (ipa_read_jump_function): Likewise. * ipa-prop.h: export ipa_get_callee_param_type. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 1dc5cb6..d0dc3d7 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -122,6 +122,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-inline.h" #include "ipa-utils.h" #include "tree-ssa-ccp.h" +#include "gimple.h" template class ipcp_value; @@ -1221,7 +1222,12 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input) if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) return input; - if (!is_gimple_ip_invariant (input)) + + if (!is_gimple_ip_invariant (input) + /* TODO: Unary expressions are not handles in ipa constant + propagation. */ + || (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) + == tcc_unary)) return NULL_TREE; if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) @@ -1845,7 +1851,8 @@ propagate_bits_accross_jump_function (cgraph_edge *cs, int idx, ipa_jump_func *j static bool propagate_vr_accross_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc, - struct ipcp_param_lattices *dest_plats) + struct ipcp_param_lattices *dest_plats, + tree param_type) { struct ipcp_param_lattices *src_lats; ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range; @@ -1863,18 +1870,43 @@ propagate_vr_accross_jump_function (cgraph_edge *cs, if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) return dest_lat->meet_with (src_lats->m_value_range); + else if (param_type + && (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc)) + == tcc_unary)) + { + value_range vr; + memset (&vr, 0, sizeof (vr)); + tree operand_type = ipa_get_type (caller_info, src_idx); + + if (src_lats->m_value_range.bottom_p ()) + return false; + + extract_range_from_unary_expr (&vr, + ipa_get_jf_pass_through_operation (jfunc), + param_type, + &src_lats->m_value_range.m_vr, + operand_type); + return dest_lat->meet_with (&vr); + } } - else if (jfunc->type == IPA_JF_CONST) + else if (param_type + && jfunc->type == IPA_JF_CONST) { tree val = ipa_get_jf_constant (jfunc); if (TREE_CODE (val) == INTEGER_CST) { + value_range vr; if (TREE_OVERFLOW_P (val)) val = drop_tree_overflow (val); - jfunc->vr_known = true; - jfunc->m_vr.type = VR_RANGE; - jfunc->m_vr.min = val; - jfunc->m_vr.max = val; + + vr.type = VR_RANGE; + vr.min = val; + vr.max = val; + vr.equiv = NULL; + extract_range_from_unary_expr (&jfunc->m_vr, + NOP_EXPR, + param_type, + &vr, TREE_TYPE (val)); return dest_lat->meet_with (&jfunc->m_vr); } } @@ -2220,6 +2252,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs) { struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i); struct ipcp_param_lattices *dest_plats; + tree param_type = ipa_get_callee_param_type (cs, i); dest_plats = ipa_get_parm_lattices (callee_info, i); if (availability == AVAIL_INTERPOSABLE) @@ -2236,7 +2269,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs) dest_plats); if (opt_for_fn (callee->decl, flag_ipa_vrp)) ret |= propagate_vr_accross_jump_function (cs, - jump_func, dest_plats); + jump_func, dest_plats, + param_type); else ret |= dest_plats->m_value_range.set_to_bottom (); } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 1629870..9147b27 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -446,6 +446,18 @@ ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id, jfunc->value.pass_through.agg_preserved = agg_preserved; } +/* Set JFUNC to be an unary pass through jump function. */ + +static void +ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id, + enum tree_code operation) +{ + jfunc->type = IPA_JF_PASS_THROUGH; + jfunc->value.pass_through.operand = NULL_TREE; + jfunc->value.pass_through.formal_id = formal_id; + jfunc->value.pass_through.operation = operation; + jfunc->value.pass_through.agg_preserved = false; +} /* Set JFUNC to be an arithmetic pass through jump function. */ static void @@ -850,18 +862,17 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index, } /* If STMT is an assignment that loads a value from an parameter declaration, - return the index of the parameter in ipa_node_params which has not been - modified. Otherwise return -1. */ + return the index of the parameter in ipa_node_params. Otherwise return -1. */ static int -load_from_unmodified_param (struct ipa_func_body_info *fbi, - vec descriptors, - gimple *stmt) +load_from_param (struct ipa_func_body_info *fbi, + vec descriptors, + gimple *stmt) { int index; tree op1; - if (!gimple_assign_single_p (stmt)) + if (!is_gimple_assign (stmt)) return -1; op1 = gimple_assign_rhs1 (stmt); @@ -1025,7 +1036,7 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi, */ gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0)); - index = load_from_unmodified_param (fbi, descriptors, def); + index = load_from_param (fbi, descriptors, def); } if (index >= 0) @@ -1109,6 +1120,7 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, tree op1, tc_ssa, base, ssa; bool reverse; int index; + gimple *stmt2 = stmt; op1 = gimple_assign_rhs1 (stmt); @@ -1117,13 +1129,16 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, if (SSA_NAME_IS_DEFAULT_DEF (op1)) index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1)); else - index = load_from_unmodified_param (fbi, info->descriptors, - SSA_NAME_DEF_STMT (op1)); + { + index = load_from_param (fbi, info->descriptors, + SSA_NAME_DEF_STMT (op1)); + stmt2 = SSA_NAME_DEF_STMT (op1); + } tc_ssa = op1; } else { - index = load_from_unmodified_param (fbi, info->descriptors, stmt); + index = load_from_param (fbi, info->descriptors, stmt); tc_ssa = gimple_assign_lhs (stmt); } @@ -1147,6 +1162,13 @@ compute_complex_assign_jump_func (struct ipa_func_body_info *fbi, bool agg_p = parm_ref_data_pass_through_p (fbi, index, call, tc_ssa); ipa_set_jf_simple_pass_through (jfunc, index, agg_p); } + else if (is_gimple_assign (stmt2) + && (gimple_expr_code (stmt2) != NOP_EXPR) + && (TREE_CODE_CLASS (gimple_expr_code (stmt2)) == tcc_unary)) + { + ipa_set_jf_unary_pass_through (jfunc, index, + gimple_assign_rhs_code (stmt2)); + } return; } @@ -1595,7 +1617,7 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg, } } -static tree +tree ipa_get_callee_param_type (struct cgraph_edge *e, int i) { int n; @@ -4663,6 +4685,10 @@ ipa_write_jump_function (struct output_block *ob, bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1); streamer_write_bitpack (&bp); } + else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation) == tcc_unary) + { + streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id); + } else { stream_write_tree (ob, jump_func->value.pass_through.operand, true); @@ -4742,6 +4768,11 @@ ipa_read_jump_function (struct lto_input_block *ib, bool agg_preserved = bp_unpack_value (&bp, 1); ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved); } + else if (TREE_CODE_CLASS (operation) == tcc_unary) + { + int formal_id = streamer_read_uhwi (ib); + ipa_set_jf_unary_pass_through (jump_func, formal_id, operation); + } else { tree operand = stream_read_tree (ib, data_in); diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 4eeae88..0e75cf4 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -818,6 +818,7 @@ ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *, ipa_parm_adjustment_vec, bool); void ipa_release_body_info (struct ipa_func_body_info *); +tree ipa_get_callee_param_type (struct cgraph_edge *e, int i); /* From tree-sra.c: */ tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, bool, tree, diff --git a/gcc/testsuite/gcc.dg/ipa/vrp7.c b/gcc/testsuite/gcc.dg/ipa/vrp7.c index e69de29..e4e0bc6 100644 --- a/gcc/testsuite/gcc.dg/ipa/vrp7.c +++ b/gcc/testsuite/gcc.dg/ipa/vrp7.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-cp-details" } */ + +volatile int cond; +int abs (int); + +static __attribute__((noinline, noclone)) +int foo (int i) +{ + if (i < 5) + __builtin_abort (); + return 0; +} + +static __attribute__((noinline, noclone)) +int bar (int j) +{ + foo (~j); + foo (abs (j)); + foo (j); + return 0; +} + +int main () +{ + for (unsigned int i = 0; i < 10; ++i) + bar (i); + + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Setting value range of param 0 \\\[-10, 9\\\]" 1 "cp" } } */