From patchwork Thu Nov 24 12:15:39 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Prathamesh Kulkarni X-Patchwork-Id: 83885 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp94806qgi; Thu, 24 Nov 2016 04:16:07 -0800 (PST) X-Received: by 10.84.194.37 with SMTP id g34mr4807466pld.36.1479989767663; Thu, 24 Nov 2016 04:16:07 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id b187si8995552pgc.0.2016.11.24.04.16.07 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 24 Nov 2016 04:16:07 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-442540-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-442540-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-442540-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 :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; q=dns; s=default; b=uWzYYGQEdNqCXnh eYZKoWc1cza6YHi8V00RwfRzG7bUxM1HFgbm3Mdz7DuXOWpi/NyNhcFfdV0ZetzS hpOeq1nXX7/vKTyffOxLcoWUfTrfhINjPDdVvsAKhE8PuRgLqoXGPgfqIyX2ec75 KpQRFJVQuEqsgemVX7n8x3CUGo+8= 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:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; s=default; bh=0UE+rXfImOH9mPjAbgFgC +sKsck=; b=VXw1QE+3uMN5PDUV9sRtrue5aU7+Wjnh5xNhsIEfHw/IGAba5kQOc XmSEoSwYu49HaNftLD2AQl/20sjw47fMPMqwsYs6gOck0n2G9JADvlfLuYf4LmD4 z24Z/7lvNBHRPMIsBq7DeQvGX/0TocwhNzfphQpUNuDShISO/Q7/10= Received: (qmail 127296 invoked by alias); 24 Nov 2016 12:15:51 -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 127275 invoked by uid 89); 24 Nov 2016 12:15:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=no version=3.3.2 spammy=evaluate, 3278 X-HELO: mail-io0-f182.google.com Received: from mail-io0-f182.google.com (HELO mail-io0-f182.google.com) (209.85.223.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 24 Nov 2016 12:15:41 +0000 Received: by mail-io0-f182.google.com with SMTP id j65so76626333iof.0 for ; Thu, 24 Nov 2016 04:15:41 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=jREmRnIksd1vkdJ8LotiMLXna7Zk3sG8PkG44mZo1Hs=; b=S0QUrxWFXXf+tZhaijgzqFCtYdcScDNNe47yQjoyY52tLnqx0uDuGuv5/I3AB0HDOw 7anD/fID+Yt61HVolr9tOqEhlCBhj0H7TakOB2/2EPYx/9Uiv+qVjrGNS8pnmo9ZYvEM 39Yd0utQOxF5my+8iBKO7sPxHhZl7stIl+mTvxoWVe1JEDfUP0ZO0X3ZGd+XNuglQVBQ ZcDGk7DzzIbaQK35ys1pzWQEMJyjASASKRHASP1m1KjAOMo7w7zUMEvF13S5Gaehfyt9 AUS9NFDXPG7NIHA46ey4cusG7I1qy9TGNJOEaW4rlagWxe0zdCnoHEXcfC/fzAloN8rp sgOw== X-Gm-Message-State: AKaTC01KC/m5GhG+KT+opxpngqDdnKfJx4n6KUunvphCiYJToH9mH8EVjJt9QQYAvtYD4zMgkcCsiO/7Wha5DS+R X-Received: by 10.36.194.70 with SMTP id i67mr1830774itg.21.1479989739427; Thu, 24 Nov 2016 04:15:39 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.136.156 with HTTP; Thu, 24 Nov 2016 04:15:39 -0800 (PST) In-Reply-To: References: From: Prathamesh Kulkarni Date: Thu, 24 Nov 2016 17:45:39 +0530 Message-ID: Subject: Re: [tree-tailcall] Check if function returns it's argument To: Richard Biener Cc: gcc Patches X-IsSubscribed: yes On 24 November 2016 at 14:07, Richard Biener wrote: > On Thu, 24 Nov 2016, Prathamesh Kulkarni wrote: > >> Hi, >> Consider following test-case: >> >> void *f(void *a1, void *a2, __SIZE_TYPE__ a3) >> { >> __builtin_memcpy (a1, a2, a3); >> return a1; >> } >> >> return a1 can be considered equivalent to return value of memcpy, >> and the call could be emitted as a tail-call. >> gcc doesn't emit the above call to memcpy as a tail-call, >> but if it is changed to: >> >> void *t1 = __builtin_memcpy (a1, a2, a3); >> return t1; >> >> Then memcpy is emitted as a tail-call. >> The attached patch tries to handle the former case. >> >> Bootstrapped+tested on x86_64-unknown-linux-gnu. >> Cross tested on arm*-*-*, aarch64*-*-* >> Does this patch look OK ? > > +/* Return arg, if function returns it's argument or NULL if it doesn't. > */ > +tree > +gimple_call_return_arg (gcall *call_stmt) > +{ > > > Please just inline it at the single use - the name is not terribly > informative. > > I'm not sure you can rely on code-generation working if you not > effectively change the IL to > > a1 = __builtin_memcpy (a1, a2, a3); > return a1; > > someone more familiar with RTL expansion plus tail call emission on > RTL needs to chime in. Well I was trying to copy-propagate function's argument into uses of it's return value if function returned that argument, so the assignment to lhs of call could be made redundant. eg: void *f(void *a1, void *a2, __SIZE_TYPE__ a3) { void *t1 = __builtin_memcpy (a1, a2, a3); return t1; } After patch, copyprop transformed it into: t1 = __builtin_memcpy (a1, a2, a3); return a1; But this now interferes with tail-call optimization, because it is not able to emit memcpy as tail-call anymore due to which the patch regressed 20050503-1.c. I am not sure how to workaround this. Thanks, Prathamesh > > Richard. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-3.c new file mode 100644 index 0000000..8319e9f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-3.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-copyprop-slim" } */ + +void f(char *dest, const char *src, __SIZE_TYPE__ n) +{ + char *t1 = __builtin_strcpy (dest, src); + if (t1 != dest) + __builtin_abort (); + + char *t2 = __builtin_strncpy (dest, src, n); + if (t2 != dest) + __builtin_abort (); + + char *t3 = __builtin_strcat (dest, src); + if (t3 != dest) + __builtin_abort (); + + char *t4 = __builtin_strncat (dest, src, n); + if (t4 != dest) + __builtin_abort (); + + void *t5 = __builtin_memmove (dest, src, n); + if (t5 != dest) + __builtin_abort (); + + void *t6 = __builtin_memcpy (dest, src, n); + if (t6 != dest) + __builtin_abort (); + + void *t7 = __builtin_memset (dest, 0, n); + if (t7 != dest) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "__builtin_abort" "copyprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-4.c new file mode 100644 index 0000000..199074d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-copyprop-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-copyprop" } */ + +char *f(char *dest, const char *src) +{ + char *t1 = __builtin_strcpy (dest, src); + return t1; +} + +/* { dg-final { scan-tree-dump "return dest_\[0-9\]*\\(D\\);" "copyprop1" } } */ diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index abc6205..77f4ad7 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -80,6 +80,9 @@ stmt_may_generate_copy (gimple *stmt) if (gimple_code (stmt) == GIMPLE_PHI) return !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_phi_result (stmt)); + if (gimple_code (stmt) == GIMPLE_CALL) + return true; + if (gimple_code (stmt) != GIMPLE_ASSIGN) return false; @@ -252,6 +255,40 @@ copy_prop_visit_cond_stmt (gimple *stmt, edge *taken_edge_p) return retval; } +/* Check if call returns one of it's arguments, and in that + case set copy-of (lhs) to the returned argument. */ + +static enum ssa_prop_result +copy_prop_visit_call (gcall *call_stmt, tree *result_p) +{ + tree lhs = gimple_call_lhs (call_stmt); + if (!lhs || TREE_CODE (lhs) != SSA_NAME) + return SSA_PROP_VARYING; + + unsigned rf = gimple_call_return_flags (call_stmt); + if (rf & ERF_RETURNS_ARG) + { + unsigned argnum = rf & ERF_RETURN_ARG_MASK; + if (argnum < gimple_call_num_args (call_stmt)) + { + tree arg = gimple_call_arg (call_stmt, argnum); + if (TREE_CODE (arg) == SSA_NAME) + { + arg = valueize_val (arg); + if (!may_propagate_copy (lhs, arg)) + return SSA_PROP_VARYING; + + *result_p = lhs; + if (set_copy_of_val (*result_p, arg)) + return SSA_PROP_INTERESTING; + else + return SSA_PROP_NOT_INTERESTING; + } + } + } + + return SSA_PROP_VARYING; +} /* Evaluate statement STMT. If the statement produces a new output value, return SSA_PROP_INTERESTING and store the SSA_NAME holding @@ -290,6 +327,8 @@ copy_prop_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *result_p) jump. */ retval = copy_prop_visit_cond_stmt (stmt, taken_edge_p); } + else if (gcall *call_stmt = dyn_cast (stmt)) + retval = copy_prop_visit_call (call_stmt, result_p); else retval = SSA_PROP_VARYING;