From patchwork Sun Jan 6 23:56:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1021122 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-493490-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="S+6rb8c/"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43XwRP2BQQz9s7h for ; Mon, 7 Jan 2019 10:56:49 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=OCBScgwiI3qsag34lMW2R7VsOoUyp2wl//adaMrMKMvM8yHmC84q9 C45fHxNkI26RnpbvJ4M4AuM5i84wUEShGEdCgS7DWhdQUfvHtCZhT6MkS0jl2+jZ jjHaAzjkmpr+i4Lei4GAtKyw26lbXMS5kh+D82/v3Cr7TnxTBghr3Y= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=DrwXRxLsBDFQVpmMfOOF8kVPtQY=; b=S+6rb8c/vhdEK16GobA+ R45e1/EmyrBusN8h4kfIe/N0pQS0KY8EALDIYDYX/PNBC+LaazS0jckwtWE9Vmp5 BT/uV611RHjBFy4Yhwj8JNN3AazyiGCD2npZfRFiNb/4LcBImsCnBjNRQyKTzZwS sFxuKzxfLHJxE10APYlDsAw= Received: (qmail 15412 invoked by alias); 6 Jan 2019 23:56:42 -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 15401 invoked by uid 89); 6 Jan 2019 23:56:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=noop, noticed, extensively X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 06 Jan 2019 23:56:39 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id C93C8281E4E; Mon, 7 Jan 2019 00:56:37 +0100 (CET) Date: Mon, 7 Jan 2019 00:56:37 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Handle builtin_expect better in ipa-fnsummary Message-ID: <20190106235637.dh4gqfhzgfsakxsi@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20170113 (1.7.2) Hi, while analyzing Firefox I noticed that it uses builtin_expect quite extensively and this sometimes causes ipa-predicates to be computed very conservatively. There are more possible improvements, but I will leave it for stage1. This handles the common case where builtin_expect is applied to parameter. Bootstrapped/regtested x86_64-linux, will commit it later for tester to catch up. Honza * ipa-fnsummary.c (builtin_expect_call_p, strip_copies): New function. (unmodified_parm, unmodified_parm_or_parm_agg_item, will_be_nonconstant_expr_predicate): Use it. Index: ipa-fnsummary.c =================================================================== --- ipa-fnsummary.c (revision 267610) +++ ipa-fnsummary.c (working copy) @@ -936,6 +936,57 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUS return true; } +/* Return ture if STMT is builtin_expect on one of its variants. */ + +static bool +builtin_expect_call_p (gimple *stmt) +{ + return ((gimple_call_builtin_p (stmt, BUILT_IN_EXPECT) + || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY) + || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT)) + && gimple_call_num_args (stmt)); +} + +/* Walk to the original assignment to OP skipping wrapping noop casts, + builtin expectes etc. */ + +static tree +strip_copies (tree op, gimple **stmt = NULL) +{ + STRIP_NOPS (op); + /* TODO: We should have some common way to tell if function returns its + argument. */ + if (TREE_CODE (op) == CALL_EXPR) + { + tree fndecl = get_callee_fndecl (op); + if (!fndecl) + return op; + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT + || DECL_FUNCTION_CODE (fndecl) + == BUILT_IN_EXPECT_WITH_PROBABILITY)) + return strip_copies (CALL_EXPR_ARG (op, 0), stmt); + return op; + } + if (TREE_CODE (op) == SSA_NAME + && builtin_expect_call_p (SSA_NAME_DEF_STMT (op))) + { + if (stmt) + *stmt = SSA_NAME_DEF_STMT (op); + return strip_copies (gimple_call_arg (SSA_NAME_DEF_STMT (op), 0), stmt); + } + if (TREE_CODE (op) == SSA_NAME + && !SSA_NAME_IS_DEFAULT_DEF (op) + && gimple_assign_single_p (SSA_NAME_DEF_STMT (op))) + { + if (stmt) + *stmt = SSA_NAME_DEF_STMT (op); + return strip_copies (gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)), + stmt); + } + return op; +} + /* If OP refers to value of function parameter, return the corresponding parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the PARM_DECL) will be stored to *SIZE_P in that case too. */ @@ -979,16 +1030,10 @@ unmodified_parm_1 (gimple *stmt, tree op static tree unmodified_parm (gimple *stmt, tree op, HOST_WIDE_INT *size_p) { + op = strip_copies (op, &stmt); tree res = unmodified_parm_1 (stmt, op, size_p); if (res) return res; - - if (TREE_CODE (op) == SSA_NAME - && !SSA_NAME_IS_DEFAULT_DEF (op) - && gimple_assign_single_p (SSA_NAME_DEF_STMT (op))) - return unmodified_parm (SSA_NAME_DEF_STMT (op), - gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)), - size_p); return NULL_TREE; } @@ -1005,6 +1050,7 @@ unmodified_parm_or_parm_agg_item (struct HOST_WIDE_INT *size_p, struct agg_position_info *aggpos) { + op = strip_copies (op, &stmt); tree res = unmodified_parm_1 (stmt, op, size_p); gcc_checking_assert (aggpos); @@ -1450,12 +1496,13 @@ will_be_nonconstant_expr_predicate (stru nonconstant_names); return p2.or_with (summary->conds, p1); } - else if (TREE_CODE (expr) == CALL_EXPR) - return true; - else + else { - debug_tree (expr); - gcc_unreachable (); + tree expr2 = strip_copies (expr); + if (expr2 != expr) + return will_be_nonconstant_expr_predicate (info, summary, expr2, + nonconstant_names); + return true; } return false; }