public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Eric Botcazou <botcazou@adacore.com>
To: gcc-patches@gcc.gnu.org
Subject: [patch] Reuse non-gimple_reg variable for inlining
Date: Mon, 03 May 2021 10:04:20 +0200	[thread overview]
Message-ID: <8762858.CDJkKcVGEf@fomalhaut> (raw)

[-- Attachment #1: Type: text/plain, Size: 1498 bytes --]

Hi,

when a call to a function is inlined and takes a parameter whose type is not
gimple_reg, a variable is created in the caller to hold a copy of the argument
passed in the call with the following comment:

      /* We may produce non-gimple trees by adding NOPs or introduce
	 invalid sharing when operand is not really constant.
	 It is not big deal to prohibit constant propagation here as
	 we will constant propagate in DOM1 pass anyway.  *

Of course the second sentence of the comment does not apply to non-gimple_reg
values, unless they get SRAed later, because we do not do constant propagation
for them.  This for example prevents two identical calls to a pure function
from being merged in the attached Ada testcase.

Therefore the attached patch attempts to reuse a read-only or non-addressable
local DECL of the caller, the hitch being that expand_call_inline needs to be
prevented from creating a CLOBBER for the cases where it ends uo being reused.

Tested on x86-64/Linux, OK for the mainline?


2021-05-03  Eric Botcazou  <ebotcazou@adacore.com>

	* tree-inline.c (setup_one_parameter): Do not create a variable if the
	value is either a read-only DECL or a non-addressable local variable.
	Register the variable thus reused instead of creating a new one.
	(expand_call_inline): Do not generate a CLOBBER for these variables.


2021-05-03  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/opt94.adb: New test.
	* gnat.dg/opt94_pkg.ads, opt94.adb: New helper.

-- 
Eric Botcazou

[-- Attachment #2: p.diff --]
[-- Type: text/x-patch, Size: 2441 bytes --]

diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 1dcb31c0267..a05093ab829 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -3460,16 +3460,18 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
      value.  */
   if (TREE_READONLY (p)
       && !TREE_ADDRESSABLE (p)
-      && value && !TREE_SIDE_EFFECTS (value)
+      && value
+      && !TREE_SIDE_EFFECTS (value)
       && !def)
     {
-      /* We may produce non-gimple trees by adding NOPs or introduce
-	 invalid sharing when operand is not really constant.
-	 It is not big deal to prohibit constant propagation here as
-	 we will constant propagate in DOM1 pass anyway.  */
-      if (is_gimple_min_invariant (value)
-	  && useless_type_conversion_p (TREE_TYPE (p),
-						 TREE_TYPE (value))
+      /* We may produce non-gimple trees by adding NOPs or introduce invalid
+	 sharing when the value is not constant or DECL.  And we need to make
+	 sure that it cannot be modified from another path in the callee.  */
+      if ((is_gimple_min_invariant (value)
+	   || (DECL_P (value) && TREE_READONLY (value))
+	   || (auto_var_in_fn_p (value, id->src_fn)
+	       && !TREE_ADDRESSABLE (value)))
+	  && useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value))
 	  /* We have to be very careful about ADDR_EXPR.  Make sure
 	     the base variable isn't a local variable of the inlined
 	     function, e.g., when doing recursive inlining, direct or
@@ -3478,6 +3480,13 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
 	  && ! self_inlining_addr_expr (value, fn))
 	{
 	  insert_decl_map (id, p, value);
+	  /* Prevent expand_call_inline from creating a CLOBBER for it.  */
+	  if (VAR_P (value) & !is_gimple_reg (value))
+	    {
+	      if (!id->debug_map)
+		id->debug_map = new hash_map<tree, tree>;
+	      id->debug_map->put (value, value);
+	    }
 	  insert_debug_decl_map (id, p, var);
 	  return insert_init_debug_bind (id, bb, var, value, NULL);
 	}
@@ -5129,7 +5138,10 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id,
       if (!TREE_THIS_VOLATILE (p))
 	{
 	  tree *varp = id->decl_map->get (p);
-	  if (varp && VAR_P (*varp) && !is_gimple_reg (*varp))
+	  if (varp
+	      && VAR_P (*varp)
+	      && !is_gimple_reg (*varp)
+	      && !(id->debug_map && id->debug_map->get (*varp)))
 	    {
 	      tree clobber = build_clobber (TREE_TYPE (*varp));
 	      gimple *clobber_stmt;

[-- Attachment #3: opt94.adb --]
[-- Type: text/x-adasrc, Size: 341 bytes --]

-- { dg-do compile }
-- { dg-options "-O -gnatn -fdump-tree-optimized" }

with Opt94_Pkg; use Opt94_Pkg;

function Opt94 (S : String) return Integer is
  A : constant String := Get;

begin
  if Valid_Result (A) then
    return Result (A);
  else
    return -1;
  end if;
end;

-- { dg-final { scan-tree-dump-times "worker" 1 "optimized" } }

[-- Attachment #4: opt94_pkg.adb --]
[-- Type: text/x-adasrc, Size: 570 bytes --]

package body Opt94_Pkg is

  function Worker (S : String) return Integer;
  pragma Pure_Function (Worker);

  function Valid_Result (S : String) return Boolean is
  begin
    return Worker (S) > 0;
  end;

  function Result (S : String) return Integer is
    R : constant Integer := Worker (S);
  begin
    if R > 0 then
      return R;
    else
      raise Program_Error;
    end if;
  end;

  function Worker (S : String) return Integer is
  begin
    return Character'Pos (S (1));
  end;

  function Get return String is
  begin
    return "";
  end;

end Opt94_Pkg;

[-- Attachment #5: opt94_pkg.ads --]
[-- Type: text/x-adasrc, Size: 228 bytes --]

package Opt94_Pkg is

  function Valid_Result (S : String) return Boolean;
  pragma Inline (Valid_Result);

  function Result (S : String) return Integer;
  pragma Inline (Result);

  function Get return String;

end Opt94_Pkg;

             reply	other threads:[~2021-05-03  8:07 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-03  8:04 Eric Botcazou [this message]
2021-05-03 11:25 ` Richard Biener
2021-05-03 15:05   ` Eric Botcazou
2021-05-04  8:30     ` Richard Biener
2021-06-09 19:10 ` Jakub Jelinek
2021-06-09 21:37   ` Eric Botcazou
2021-06-10  6:44     ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8762858.CDJkKcVGEf@fomalhaut \
    --to=botcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).