From patchwork Tue Aug 28 11:26:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 145307 Delivered-To: patch@linaro.org Received: by 2002:a2e:1648:0:0:0:0:0 with SMTP id 8-v6csp1066664ljw; Tue, 28 Aug 2018 04:27:07 -0700 (PDT) X-Google-Smtp-Source: ANB0VdYw1J8MiVsIELx4ugmiqzSFuUUCdy80Pex007WxTggP+pLGX5n+Svc8HIZ5JJ0t4+szBGyf X-Received: by 2002:a65:6309:: with SMTP id g9-v6mr1131196pgv.153.1535455627147; Tue, 28 Aug 2018 04:27:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535455627; cv=none; d=google.com; s=arc-20160816; b=jd3iB7girPjFWA483dwdrXoyaZfXC3nPj31N8wVi5hOyDANwCE7W6mWYjlvBCWaRKV I0Lawq96hTkLenZZqgxeisqX4XyGfy46Yjzn2AKIUHPSz2OTFsVmnUJllSYG/gw1A+E5 dNw92Y1RGKGPxrVMC5i7xLLTTsAxrTfGY8pjxbJksP/n/I+xCAzo9KRQ6rfBrdoB6x3Y jmvTxutfo+SkXyuMb+fDQtQJcdoujiRXOqkKEn0DwZc65VOtN1gVyX1R5FkT8zFfmzU8 elZmIj0yXYtZ0YcrNLfaTnHBJtphTfPQUR7usbfId4QPypJ/CRYdpkGUj68gN2jgyq/f 1m8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=to:subject:message-id:date:from:mime-version:dkim-signature :delivered-to:sender:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=GMRdfqN+jR1jkl8s0R1zns2VdmCYvm0x7PGuBGLb/Ik=; b=yDWYE1w/sXY9aHYJIzeRuoATyem5gdnBdhpy0R/Y/aQko+j6wYKB4ShnZCccCylBbK 0aE0d7VXD1Sv573vVNxzbhcYgn2ZFJU0MIZWCLNIGgEv9kKOwB5bGoWef/eUFy1s7Cga u6gkAok9cT4MDvyD/Q5hwsoA8fcGDEe6PvWgrYDTbNNt2PLWh37h7VSiSzOfncr7lTYe LRAqorOAdzhl/bsxODC9On6r1PYxEfoAshToA9lQ7p1xZZ+7PFRUW4csk89hPabsRAMY i+gj8eRppS9SO/UWKtL4LOD7RhHQ7lbPwvrqylxd/89IBRUn2E1j7nTw5eW6e56vXXPY LMOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=lqsGnfjx; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=bKi6p8ZC; spf=pass (google.com: domain of gcc-patches-return-484584-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-484584-patch=linaro.org@gcc.gnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id f21-v6si912541pgk.418.2018.08.28.04.27.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 28 Aug 2018 04:27:07 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-484584-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 header.s=default header.b=lqsGnfjx; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=bKi6p8ZC; spf=pass (google.com: domain of gcc-patches-return-484584-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="gcc-patches-return-484584-patch=linaro.org@gcc.gnu.org"; dmarc=fail (p=NONE sp=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 :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=X05zCPtaxjhJyFkB4ZlSj3N6LbTol4enXWI5Rvc2bmVfpJ Nwj0745tNuS+aVAGJTE0JPYm7gqG5Jcs7NlDPw4FkJ/uEfPRB3KhIMiymmC1qDxv vay+68/6BNxUb+Bgv9sPPZ0d0aqPrypL97mlq4Rxs+KkK8gC+vVsEkPzFQTGI= 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 :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=4HFztZ4p2o4aWRjNQDqXb/qype4=; b=lqsGnfjxyfJaU7jRqwdX 42Ie3E92sg31eBFbFQvni1oFMIYDaZv222EBRROKCxorMO4EtX81LnZDIpTXNeEs nRaY9Bwa7JZbS465xIWhwYo1Sn6srNWE3EoQU8RF9+KXRelT56Jfulwua08Ffha/ hqJarUTomG94Qdzrj49I0ME= Received: (qmail 51150 invoked by alias); 28 Aug 2018 11:26:54 -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 51139 invoked by uid 89); 28 Aug 2018 11:26:54 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-22.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SEM_URI, SEM_URIRED, SPF_PASS autolearn=ham version=3.3.2 spammy=DECL_IS_MALLOC, cond1, decl_is_malloc, H*r:a5d X-HELO: mail-wm0-f49.google.com Received: from mail-wm0-f49.google.com (HELO mail-wm0-f49.google.com) (74.125.82.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 28 Aug 2018 11:26:52 +0000 Received: by mail-wm0-f49.google.com with SMTP id o18-v6so1641211wmc.0 for ; Tue, 28 Aug 2018 04:26:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:from:date:message-id:subject:to; bh=uJAh5qfuqykgkfBgrIv/3OqKhxW04cjBxazvr5Vw/wc=; b=bKi6p8ZC78qLECOSuvM37HUcAeQwZaoVWywthf0wsgvigwkY5/ebgKLwhcEG99kBEL 8YJYKNNyDS8renOnhFHRdTPehrtJya1BqdSUSMIf9Pbp17UT9/RQzUfMMhgQ810F22Fp jb+P+CLDebve7H3+5ClFEGh2f4Q86SizExkrY= MIME-Version: 1.0 Received: by 2002:a5d:4042:0:0:0:0:0 with HTTP; Tue, 28 Aug 2018 04:26:49 -0700 (PDT) From: Prathamesh Kulkarni Date: Tue, 28 Aug 2018 16:56:49 +0530 Message-ID: Subject: PR85787: Extend malloc_candidate_p to handle multiple phis. To: gcc Patches , Richard Biener , Jan Hubicka X-IsSubscribed: yes H The attached patch extends malloc_candidate_p to handle multiple phis. There's a lot of noise in the patch because I moved most of malloc_candidate_p into new function malloc_candidate_p_1. The only real change is following hunk: + gimple *arg_def = SSA_NAME_DEF_STMT (arg); + if (is_a (arg_def)) + { + if (!malloc_candidate_p_1 (fun, arg, phi, ipa)) + DUMP_AND_RETURN ("nested phi fail") + continue; + } + Which checks recursively that the phi argument is used only within comparisons against 0 and the phi. Bootstrapped+tested on x86_64-unknown-linux-gnu. OK to commit ? Thanks, Prathamesh 2018-08-28 Prathamesh Kulkarni PR tree-optimization/85787 * ipa-pure-const.c (malloc_candidate_p_1): Move most of malloc_candidate_p into this function and add support for detecting multiple phis. (DUMP_AND_RETURN): Move from malloc_candidate_p into top-level macro. diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index a9a8863d907..66c81be23ec 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -869,14 +869,6 @@ check_retval_uses (tree retval, gimple *stmt) and return_stmt (and likewise a phi arg has immediate use only within comparison or the phi stmt). */ -static bool -malloc_candidate_p (function *fun, bool ipa) -{ - basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (fun); - edge e; - edge_iterator ei; - cgraph_node *node = cgraph_node::get_create (fun->decl); - #define DUMP_AND_RETURN(reason) \ { \ if (dump_file && (dump_flags & TDF_DETAILS)) \ @@ -885,6 +877,96 @@ malloc_candidate_p (function *fun, bool ipa) return false; \ } +static bool +malloc_candidate_p_1 (function *fun, tree retval, gimple *ret_stmt, bool ipa) +{ + cgraph_node *node = cgraph_node::get_create (fun->decl); + + if (!check_retval_uses (retval, ret_stmt)) + DUMP_AND_RETURN("Return value has uses outside return stmt" + " and comparisons against 0.") + + gimple *def = SSA_NAME_DEF_STMT (retval); + + if (gcall *call_stmt = dyn_cast (def)) + { + tree callee_decl = gimple_call_fndecl (call_stmt); + if (!callee_decl) + return false; + + if (!ipa && !DECL_IS_MALLOC (callee_decl)) + DUMP_AND_RETURN("callee_decl does not have malloc attribute for" + " non-ipa mode.") + + cgraph_edge *cs = node->get_edge (call_stmt); + if (cs) + { + ipa_call_summary *es = ipa_call_summaries->get_create (cs); + es->is_return_callee_uncaptured = true; + } + } + + else if (gphi *phi = dyn_cast (def)) + { + bool all_args_zero = true; + for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) + { + tree arg = gimple_phi_arg_def (phi, i); + if (integer_zerop (arg)) + continue; + + all_args_zero = false; + if (TREE_CODE (arg) != SSA_NAME) + DUMP_AND_RETURN ("phi arg is not SSA_NAME."); + if (!check_retval_uses (arg, phi)) + DUMP_AND_RETURN ("phi arg has uses outside phi" + " and comparisons against 0.") + + gimple *arg_def = SSA_NAME_DEF_STMT (arg); + if (is_a (arg_def)) + { + if (!malloc_candidate_p_1 (fun, arg, phi, ipa)) + DUMP_AND_RETURN ("nested phi fail") + continue; + } + + gcall *call_stmt = dyn_cast (arg_def); + if (!call_stmt) + DUMP_AND_RETURN ("phi arg is a not a call_stmt.") + + tree callee_decl = gimple_call_fndecl (call_stmt); + if (!callee_decl) + return false; + if (!ipa && !DECL_IS_MALLOC (callee_decl)) + DUMP_AND_RETURN("callee_decl does not have malloc attribute" + " for non-ipa mode.") + + cgraph_edge *cs = node->get_edge (call_stmt); + if (cs) + { + ipa_call_summary *es = ipa_call_summaries->get_create (cs); + es->is_return_callee_uncaptured = true; + } + } + + if (all_args_zero) + DUMP_AND_RETURN ("Return value is a phi with all args equal to 0.") + } + + else + DUMP_AND_RETURN("def_stmt of return value is not a call or phi-stmt.") + + return true; +} + +static bool +malloc_candidate_p (function *fun, bool ipa) +{ + basic_block exit_block = EXIT_BLOCK_PTR_FOR_FN (fun); + edge e; + edge_iterator ei; + cgraph_node *node = cgraph_node::get_create (fun->decl); + if (EDGE_COUNT (exit_block->preds) == 0 || !flag_delete_null_pointer_checks) return false; @@ -905,80 +987,17 @@ malloc_candidate_p (function *fun, bool ipa) || TREE_CODE (TREE_TYPE (retval)) != POINTER_TYPE) DUMP_AND_RETURN("Return value is not SSA_NAME or not a pointer type.") - if (!check_retval_uses (retval, ret_stmt)) - DUMP_AND_RETURN("Return value has uses outside return stmt" - " and comparisons against 0.") - - gimple *def = SSA_NAME_DEF_STMT (retval); - if (gcall *call_stmt = dyn_cast (def)) - { - tree callee_decl = gimple_call_fndecl (call_stmt); - if (!callee_decl) - return false; - - if (!ipa && !DECL_IS_MALLOC (callee_decl)) - DUMP_AND_RETURN("callee_decl does not have malloc attribute for" - " non-ipa mode.") - - cgraph_edge *cs = node->get_edge (call_stmt); - if (cs) - { - ipa_call_summary *es = ipa_call_summaries->get_create (cs); - es->is_return_callee_uncaptured = true; - } - } - - else if (gphi *phi = dyn_cast (def)) - { - bool all_args_zero = true; - for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i) - { - tree arg = gimple_phi_arg_def (phi, i); - if (integer_zerop (arg)) - continue; - - all_args_zero = false; - if (TREE_CODE (arg) != SSA_NAME) - DUMP_AND_RETURN ("phi arg is not SSA_NAME."); - if (!check_retval_uses (arg, phi)) - DUMP_AND_RETURN ("phi arg has uses outside phi" - " and comparisons against 0.") - - gimple *arg_def = SSA_NAME_DEF_STMT (arg); - gcall *call_stmt = dyn_cast (arg_def); - if (!call_stmt) - return false; - tree callee_decl = gimple_call_fndecl (call_stmt); - if (!callee_decl) - return false; - if (!ipa && !DECL_IS_MALLOC (callee_decl)) - DUMP_AND_RETURN("callee_decl does not have malloc attribute" - " for non-ipa mode.") - - cgraph_edge *cs = node->get_edge (call_stmt); - if (cs) - { - ipa_call_summary *es = ipa_call_summaries->get_create (cs); - es->is_return_callee_uncaptured = true; - } - } - - if (all_args_zero) - DUMP_AND_RETURN ("Return value is a phi with all args equal to 0."); - } - - else - DUMP_AND_RETURN("def_stmt of return value is not a call or phi-stmt.") + if (!malloc_candidate_p_1 (fun, retval, ret_stmt, ipa)) + return false; } if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "\nFound %s to be candidate for malloc attribute\n", IDENTIFIER_POINTER (DECL_NAME (fun->decl))); return true; - -#undef DUMP_AND_RETURN } +#undef DUMP_AND_RETURN /* This is the main routine for finding the reference patterns for global variables within a function FN. */ diff --git a/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c b/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c new file mode 100644 index 00000000000..4c40d63f63d --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/propmalloc-4.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-local-pure-const-details" } */ + +void *foo(int cond1, int cond2, int cond3) +{ + void *ret; + void *a; + void *b; + + if (cond1) + a = __builtin_malloc (10); + else + a = __builtin_malloc (20); + + if (cond2) + b = __builtin_malloc (30); + else + b = __builtin_malloc (40); + + if (cond3) + ret = a; + else + ret = b; + + return ret; +} + +void *foo2(int cond1, int cond2, int cond3) +{ + void *ret; + void *a; + void *b; + void bar(void *, void *); + + if (cond1) + a = __builtin_malloc (10); + else + a = __builtin_malloc (20); + + if (cond2) + b = __builtin_malloc (30); + else + b = __builtin_malloc (40); + + bar (a, b); + + if (cond3) + ret = a; + else + ret = b; + + return ret; +} + +/* { dg-final { scan-tree-dump "Function found to be malloc: foo" "local-pure-const1" } } */ +/* { dg-final { scan-tree-dump-not "Function found to be malloc: foo2" "local-pure-const1" } } */