tree-inline.c revision 90075
190075Sobrien/* Control and data flow functions for trees.
290075Sobrien   Copyright 2001, 2002 Free Software Foundation, Inc.
390075Sobrien   Contributed by Alexandre Oliva <aoliva@redhat.com>
490075Sobrien
590075SobrienThis file is part of GNU CC.
690075Sobrien
790075SobrienGNU CC is free software; you can redistribute it and/or modify
890075Sobrienit under the terms of the GNU General Public License as published by
990075Sobrienthe Free Software Foundation; either version 2, or (at your option)
1090075Sobrienany later version.
1190075Sobrien
1290075SobrienGNU CC is distributed in the hope that it will be useful,
1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1590075SobrienGNU General Public License for more details.
1690075Sobrien
1790075SobrienYou should have received a copy of the GNU General Public License
1890075Sobrienalong with GNU CC; see the file COPYING.  If not, write to
1990075Sobrienthe Free Software Foundation, 59 Temple Place - Suite 330,
2090075SobrienBoston, MA 02111-1307, USA.  */
2190075Sobrien
2290075Sobrien#include "config.h"
2390075Sobrien#include "system.h"
2490075Sobrien#include "toplev.h"
2590075Sobrien#include "tree.h"
2690075Sobrien#include "tree-inline.h"
2790075Sobrien#include "rtl.h"
2890075Sobrien#include "expr.h"
2990075Sobrien#include "flags.h"
3090075Sobrien#include "params.h"
3190075Sobrien#include "input.h"
3290075Sobrien#include "insn-config.h"
3390075Sobrien#include "integrate.h"
3490075Sobrien#include "varray.h"
3590075Sobrien#include "hashtab.h"
3690075Sobrien#include "splay-tree.h"
3790075Sobrien#include "langhooks.h"
3890075Sobrien
3990075Sobrien/* This should be eventually be generalized to other languages, but
4090075Sobrien   this would require a shared function-as-trees infrastructure.  */
4190075Sobrien#include "c-common.h"
4290075Sobrien
4390075Sobrien/* 0 if we should not perform inlining.
4490075Sobrien   1 if we should expand functions calls inline at the tree level.
4590075Sobrien   2 if we should consider *all* functions to be inline
4690075Sobrien   candidates.  */
4790075Sobrien
4890075Sobrienint flag_inline_trees = 0;
4990075Sobrien
5090075Sobrien/* To Do:
5190075Sobrien
5290075Sobrien   o In order to make inlining-on-trees work, we pessimized
5390075Sobrien     function-local static constants.  In particular, they are now
5490075Sobrien     always output, even when not addressed.  Fix this by treating
5590075Sobrien     function-local static constants just like global static
5690075Sobrien     constants; the back-end already knows not to output them if they
5790075Sobrien     are not needed.
5890075Sobrien
5990075Sobrien   o Provide heuristics to clamp inlining of recursive template
6090075Sobrien     calls?  */
6190075Sobrien
6290075Sobrien/* Data required for function inlining.  */
6390075Sobrien
6490075Sobrientypedef struct inline_data
6590075Sobrien{
6690075Sobrien  /* A stack of the functions we are inlining.  For example, if we are
6790075Sobrien     compiling `f', which calls `g', which calls `h', and we are
6890075Sobrien     inlining the body of `h', the stack will contain, `h', followed
6990075Sobrien     by `g', followed by `f'.  The first few elements of the stack may
7090075Sobrien     contain other functions that we know we should not recurse into,
7190075Sobrien     even though they are not directly being inlined.  */
7290075Sobrien  varray_type fns;
7390075Sobrien  /* The index of the first element of FNS that really represents an
7490075Sobrien     inlined function.  */
7590075Sobrien  unsigned first_inlined_fn;
7690075Sobrien  /* The label to jump to when a return statement is encountered.  If
7790075Sobrien     this value is NULL, then return statements will simply be
7890075Sobrien     remapped as return statements, rather than as jumps.  */
7990075Sobrien  tree ret_label;
8090075Sobrien  /* The map from local declarations in the inlined function to
8190075Sobrien     equivalents in the function into which it is being inlined.  */
8290075Sobrien  splay_tree decl_map;
8390075Sobrien  /* Nonzero if we are currently within the cleanup for a
8490075Sobrien     TARGET_EXPR.  */
8590075Sobrien  int in_target_cleanup_p;
8690075Sobrien  /* A stack of the TARGET_EXPRs that we are currently processing.  */
8790075Sobrien  varray_type target_exprs;
8890075Sobrien  /* A list of the functions current function has inlined.  */
8990075Sobrien  varray_type inlined_fns;
9090075Sobrien  /* The approximate number of statements we have inlined in the
9190075Sobrien     current call stack.  */
9290075Sobrien  int inlined_stmts;
9390075Sobrien  /* We use the same mechanism to build clones that we do to perform
9490075Sobrien     inlining.  However, there are a few places where we need to
9590075Sobrien     distinguish between those two situations.  This flag is true if
9690075Sobrien     we are cloning, rather than inlining.  */
9790075Sobrien  bool cloning_p;
9890075Sobrien  /* Hash table used to prevent walk_tree from visiting the same node
9990075Sobrien     umpteen million times.  */
10090075Sobrien  htab_t tree_pruner;
10190075Sobrien} inline_data;
10290075Sobrien
10390075Sobrien/* Prototypes.  */
10490075Sobrien
10590075Sobrienstatic tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
10690075Sobrienstatic tree declare_return_variable PARAMS ((inline_data *, tree *));
10790075Sobrienstatic tree copy_body_r PARAMS ((tree *, int *, void *));
10890075Sobrienstatic tree copy_body PARAMS ((inline_data *));
10990075Sobrienstatic tree expand_call_inline PARAMS ((tree *, int *, void *));
11090075Sobrienstatic void expand_calls_inline PARAMS ((tree *, inline_data *));
11190075Sobrienstatic int inlinable_function_p PARAMS ((tree, inline_data *));
11290075Sobrienstatic tree remap_decl PARAMS ((tree, inline_data *));
11390075Sobrienstatic void remap_block PARAMS ((tree, tree, inline_data *));
11490075Sobrienstatic void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
11590075Sobrien
11690075Sobrien/* The approximate number of instructions per statement.  This number
11790075Sobrien   need not be particularly accurate; it is used only to make
11890075Sobrien   decisions about when a function is too big to inline.  */
11990075Sobrien#define INSNS_PER_STMT (10)
12090075Sobrien
12190075Sobrien/* Remap DECL during the copying of the BLOCK tree for the function.  */
12290075Sobrien
12390075Sobrienstatic tree
12490075Sobrienremap_decl (decl, id)
12590075Sobrien     tree decl;
12690075Sobrien     inline_data *id;
12790075Sobrien{
12890075Sobrien  splay_tree_node n;
12990075Sobrien  tree fn;
13090075Sobrien
13190075Sobrien  /* We only remap local variables in the current function.  */
13290075Sobrien  fn = VARRAY_TOP_TREE (id->fns);
13390075Sobrien  if (! (*lang_hooks.tree_inlining.auto_var_in_fn_p) (decl, fn))
13490075Sobrien    return NULL_TREE;
13590075Sobrien
13690075Sobrien  /* See if we have remapped this declaration.  */
13790075Sobrien  n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
13890075Sobrien  /* If we didn't already have an equivalent for this declaration,
13990075Sobrien     create one now.  */
14090075Sobrien  if (!n)
14190075Sobrien    {
14290075Sobrien      tree t;
14390075Sobrien
14490075Sobrien      /* Make a copy of the variable or label.  */
14590075Sobrien      t = copy_decl_for_inlining (decl, fn,
14690075Sobrien				  VARRAY_TREE (id->fns, 0));
14790075Sobrien
14890075Sobrien      /* The decl T could be a dynamic array or other variable size type,
14990075Sobrien	 in which case some fields need to be remapped because they may
15090075Sobrien	 contain SAVE_EXPRs.  */
15190075Sobrien      if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
15290075Sobrien	  && TYPE_DOMAIN (TREE_TYPE (t)))
15390075Sobrien	{
15490075Sobrien	  TREE_TYPE (t) = copy_node (TREE_TYPE (t));
15590075Sobrien	  TYPE_DOMAIN (TREE_TYPE (t))
15690075Sobrien	    = copy_node (TYPE_DOMAIN (TREE_TYPE (t)));
15790075Sobrien	  walk_tree (&TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))),
15890075Sobrien		     copy_body_r, id, NULL);
15990075Sobrien	}
16090075Sobrien
16190075Sobrien      if (! DECL_NAME (t) && TREE_TYPE (t)
16290075Sobrien	  && (*lang_hooks.tree_inlining.anon_aggr_type_p) (TREE_TYPE (t)))
16390075Sobrien	{
16490075Sobrien	  /* For a VAR_DECL of anonymous type, we must also copy the
16590075Sobrien	     member VAR_DECLS here and rechain the
16690075Sobrien	     DECL_ANON_UNION_ELEMS.  */
16790075Sobrien	  tree members = NULL;
16890075Sobrien	  tree src;
16990075Sobrien
17090075Sobrien	  for (src = DECL_ANON_UNION_ELEMS (t); src;
17190075Sobrien	       src = TREE_CHAIN (src))
17290075Sobrien	    {
17390075Sobrien	      tree member = remap_decl (TREE_VALUE (src), id);
17490075Sobrien
17590075Sobrien	      if (TREE_PURPOSE (src))
17690075Sobrien		abort ();
17790075Sobrien	      members = tree_cons (NULL, member, members);
17890075Sobrien	    }
17990075Sobrien	  DECL_ANON_UNION_ELEMS (t) = nreverse (members);
18090075Sobrien	}
18190075Sobrien
18290075Sobrien      /* Remember it, so that if we encounter this local entity
18390075Sobrien	 again we can reuse this copy.  */
18490075Sobrien      n = splay_tree_insert (id->decl_map,
18590075Sobrien			     (splay_tree_key) decl,
18690075Sobrien			     (splay_tree_value) t);
18790075Sobrien    }
18890075Sobrien
18990075Sobrien  return (tree) n->value;
19090075Sobrien}
19190075Sobrien
19290075Sobrien/* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain
19390075Sobrien   remapped versions of the variables therein.  And hook the new block
19490075Sobrien   into the block-tree.  If non-NULL, the DECLS are declarations to
19590075Sobrien   add to use instead of the BLOCK_VARS in the old block.  */
19690075Sobrien
19790075Sobrienstatic void
19890075Sobrienremap_block (scope_stmt, decls, id)
19990075Sobrien     tree scope_stmt;
20090075Sobrien     tree decls;
20190075Sobrien     inline_data *id;
20290075Sobrien{
20390075Sobrien  /* We cannot do this in the cleanup for a TARGET_EXPR since we do
20490075Sobrien     not know whether or not expand_expr will actually write out the
20590075Sobrien     code we put there.  If it does not, then we'll have more BLOCKs
20690075Sobrien     than block-notes, and things will go awry.  At some point, we
20790075Sobrien     should make the back-end handle BLOCK notes in a tidier way,
20890075Sobrien     without requiring a strict correspondence to the block-tree; then
20990075Sobrien     this check can go.  */
21090075Sobrien  if (id->in_target_cleanup_p)
21190075Sobrien    {
21290075Sobrien      SCOPE_STMT_BLOCK (scope_stmt) = NULL_TREE;
21390075Sobrien      return;
21490075Sobrien    }
21590075Sobrien
21690075Sobrien  /* If this is the beginning of a scope, remap the associated BLOCK.  */
21790075Sobrien  if (SCOPE_BEGIN_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
21890075Sobrien    {
21990075Sobrien      tree old_block;
22090075Sobrien      tree new_block;
22190075Sobrien      tree old_var;
22290075Sobrien      tree fn;
22390075Sobrien
22490075Sobrien      /* Make the new block.  */
22590075Sobrien      old_block = SCOPE_STMT_BLOCK (scope_stmt);
22690075Sobrien      new_block = make_node (BLOCK);
22790075Sobrien      TREE_USED (new_block) = TREE_USED (old_block);
22890075Sobrien      BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
22990075Sobrien      SCOPE_STMT_BLOCK (scope_stmt) = new_block;
23090075Sobrien
23190075Sobrien      /* Remap its variables.  */
23290075Sobrien      for (old_var = decls ? decls : BLOCK_VARS (old_block);
23390075Sobrien	   old_var;
23490075Sobrien	   old_var = TREE_CHAIN (old_var))
23590075Sobrien	{
23690075Sobrien	  tree new_var;
23790075Sobrien
23890075Sobrien	  /* Remap the variable.  */
23990075Sobrien	  new_var = remap_decl (old_var, id);
24090075Sobrien	  /* If we didn't remap this variable, so we can't mess with
24190075Sobrien	     its TREE_CHAIN.  If we remapped this variable to
24290075Sobrien	     something other than a declaration (say, if we mapped it
24390075Sobrien	     to a constant), then we must similarly omit any mention
24490075Sobrien	     of it here.  */
24590075Sobrien	  if (!new_var || !DECL_P (new_var))
24690075Sobrien	    ;
24790075Sobrien	  else
24890075Sobrien	    {
24990075Sobrien	      TREE_CHAIN (new_var) = BLOCK_VARS (new_block);
25090075Sobrien	      BLOCK_VARS (new_block) = new_var;
25190075Sobrien	    }
25290075Sobrien	}
25390075Sobrien      /* We put the BLOCK_VARS in reverse order; fix that now.  */
25490075Sobrien      BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
25590075Sobrien      fn = VARRAY_TREE (id->fns, 0);
25690075Sobrien      if (id->cloning_p)
25790075Sobrien	/* We're building a clone; DECL_INITIAL is still
25890075Sobrien	   error_mark_node, and current_binding_level is the parm
25990075Sobrien	   binding level.  */
26090075Sobrien	insert_block (new_block);
26190075Sobrien      else
26290075Sobrien	{
26390075Sobrien	  /* Attach this new block after the DECL_INITIAL block for the
26490075Sobrien	     function into which this block is being inlined.  In
26590075Sobrien	     rest_of_compilation we will straighten out the BLOCK tree.  */
26690075Sobrien	  tree *first_block;
26790075Sobrien	  if (DECL_INITIAL (fn))
26890075Sobrien	    first_block = &BLOCK_CHAIN (DECL_INITIAL (fn));
26990075Sobrien	  else
27090075Sobrien	    first_block = &DECL_INITIAL (fn);
27190075Sobrien	  BLOCK_CHAIN (new_block) = *first_block;
27290075Sobrien	  *first_block = new_block;
27390075Sobrien	}
27490075Sobrien      /* Remember the remapped block.  */
27590075Sobrien      splay_tree_insert (id->decl_map,
27690075Sobrien			 (splay_tree_key) old_block,
27790075Sobrien			 (splay_tree_value) new_block);
27890075Sobrien    }
27990075Sobrien  /* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
28090075Sobrien     remapped block.  */
28190075Sobrien  else if (SCOPE_END_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
28290075Sobrien    {
28390075Sobrien      splay_tree_node n;
28490075Sobrien
28590075Sobrien      /* Find this block in the table of remapped things.  */
28690075Sobrien      n = splay_tree_lookup (id->decl_map,
28790075Sobrien			     (splay_tree_key) SCOPE_STMT_BLOCK (scope_stmt));
28890075Sobrien      if (! n)
28990075Sobrien	abort ();
29090075Sobrien      SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value;
29190075Sobrien    }
29290075Sobrien}
29390075Sobrien
29490075Sobrien/* Copy the SCOPE_STMT pointed to by TP.  */
29590075Sobrien
29690075Sobrienstatic void
29790075Sobriencopy_scope_stmt (tp, walk_subtrees, id)
29890075Sobrien     tree *tp;
29990075Sobrien     int *walk_subtrees;
30090075Sobrien     inline_data *id;
30190075Sobrien{
30290075Sobrien  tree block;
30390075Sobrien
30490075Sobrien  /* Remember whether or not this statement was nullified.  When
30590075Sobrien     making a copy, copy_tree_r always sets SCOPE_NULLIFIED_P (and
30690075Sobrien     doesn't copy the SCOPE_STMT_BLOCK) to free callers from having to
30790075Sobrien     deal with copying BLOCKs if they do not wish to do so.  */
30890075Sobrien  block = SCOPE_STMT_BLOCK (*tp);
30990075Sobrien  /* Copy (and replace) the statement.  */
31090075Sobrien  copy_tree_r (tp, walk_subtrees, NULL);
31190075Sobrien  /* Restore the SCOPE_STMT_BLOCK.  */
31290075Sobrien  SCOPE_STMT_BLOCK (*tp) = block;
31390075Sobrien
31490075Sobrien  /* Remap the associated block.  */
31590075Sobrien  remap_block (*tp, NULL_TREE, id);
31690075Sobrien}
31790075Sobrien
31890075Sobrien/* Called from copy_body via walk_tree.  DATA is really an
31990075Sobrien   `inline_data *'.  */
32090075Sobrien
32190075Sobrienstatic tree
32290075Sobriencopy_body_r (tp, walk_subtrees, data)
32390075Sobrien     tree *tp;
32490075Sobrien     int *walk_subtrees;
32590075Sobrien     void *data;
32690075Sobrien{
32790075Sobrien  inline_data* id;
32890075Sobrien  tree fn;
32990075Sobrien
33090075Sobrien  /* Set up.  */
33190075Sobrien  id = (inline_data *) data;
33290075Sobrien  fn = VARRAY_TOP_TREE (id->fns);
33390075Sobrien
33490075Sobrien#if 0
33590075Sobrien  /* All automatic variables should have a DECL_CONTEXT indicating
33690075Sobrien     what function they come from.  */
33790075Sobrien  if ((TREE_CODE (*tp) == VAR_DECL || TREE_CODE (*tp) == LABEL_DECL)
33890075Sobrien      && DECL_NAMESPACE_SCOPE_P (*tp))
33990075Sobrien    if (! DECL_EXTERNAL (*tp) && ! TREE_STATIC (*tp))
34090075Sobrien      abort ();
34190075Sobrien#endif
34290075Sobrien
34390075Sobrien  /* If this is a RETURN_STMT, change it into an EXPR_STMT and a
34490075Sobrien     GOTO_STMT with the RET_LABEL as its target.  */
34590075Sobrien  if (TREE_CODE (*tp) == RETURN_STMT && id->ret_label)
34690075Sobrien    {
34790075Sobrien      tree return_stmt = *tp;
34890075Sobrien      tree goto_stmt;
34990075Sobrien
35090075Sobrien      /* Build the GOTO_STMT.  */
35190075Sobrien      goto_stmt = build_stmt (GOTO_STMT, id->ret_label);
35290075Sobrien      TREE_CHAIN (goto_stmt) = TREE_CHAIN (return_stmt);
35390075Sobrien      GOTO_FAKE_P (goto_stmt) = 1;
35490075Sobrien
35590075Sobrien      /* If we're returning something, just turn that into an
35690075Sobrien	 assignment into the equivalent of the original
35790075Sobrien	 RESULT_DECL.  */
35890075Sobrien      if (RETURN_EXPR (return_stmt))
35990075Sobrien	{
36090075Sobrien	  *tp = build_stmt (EXPR_STMT,
36190075Sobrien			    RETURN_EXPR (return_stmt));
36290075Sobrien	  STMT_IS_FULL_EXPR_P (*tp) = 1;
36390075Sobrien	  /* And then jump to the end of the function.  */
36490075Sobrien	  TREE_CHAIN (*tp) = goto_stmt;
36590075Sobrien	}
36690075Sobrien      /* If we're not returning anything just do the jump.  */
36790075Sobrien      else
36890075Sobrien	*tp = goto_stmt;
36990075Sobrien    }
37090075Sobrien  /* Local variables and labels need to be replaced by equivalent
37190075Sobrien     variables.  We don't want to copy static variables; there's only
37290075Sobrien     one of those, no matter how many times we inline the containing
37390075Sobrien     function.  */
37490075Sobrien  else if ((*lang_hooks.tree_inlining.auto_var_in_fn_p) (*tp, fn))
37590075Sobrien    {
37690075Sobrien      tree new_decl;
37790075Sobrien
37890075Sobrien      /* Remap the declaration.  */
37990075Sobrien      new_decl = remap_decl (*tp, id);
38090075Sobrien      if (! new_decl)
38190075Sobrien	abort ();
38290075Sobrien      /* Replace this variable with the copy.  */
38390075Sobrien      STRIP_TYPE_NOPS (new_decl);
38490075Sobrien      *tp = new_decl;
38590075Sobrien    }
38690075Sobrien#if 0
38790075Sobrien  else if (nonstatic_local_decl_p (*tp)
38890075Sobrien	   && DECL_CONTEXT (*tp) != VARRAY_TREE (id->fns, 0))
38990075Sobrien    abort ();
39090075Sobrien#endif
39190075Sobrien  else if (TREE_CODE (*tp) == SAVE_EXPR)
39290075Sobrien    remap_save_expr (tp, id->decl_map, VARRAY_TREE (id->fns, 0),
39390075Sobrien		     walk_subtrees);
39490075Sobrien  else if (TREE_CODE (*tp) == UNSAVE_EXPR)
39590075Sobrien    /* UNSAVE_EXPRs should not be generated until expansion time.  */
39690075Sobrien    abort ();
39790075Sobrien  /* For a SCOPE_STMT, we must copy the associated block so that we
39890075Sobrien     can write out debugging information for the inlined variables.  */
39990075Sobrien  else if (TREE_CODE (*tp) == SCOPE_STMT && !id->in_target_cleanup_p)
40090075Sobrien    copy_scope_stmt (tp, walk_subtrees, id);
40190075Sobrien  /* Otherwise, just copy the node.  Note that copy_tree_r already
40290075Sobrien     knows not to copy VAR_DECLs, etc., so this is safe.  */
40390075Sobrien  else
40490075Sobrien    {
40590075Sobrien      copy_tree_r (tp, walk_subtrees, NULL);
40690075Sobrien
40790075Sobrien      /* The copied TARGET_EXPR has never been expanded, even if the
40890075Sobrien	 original node was expanded already.  */
40990075Sobrien      if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
41090075Sobrien	{
41190075Sobrien	  TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
41290075Sobrien	  TREE_OPERAND (*tp, 3) = NULL_TREE;
41390075Sobrien	}
41490075Sobrien      else if (TREE_CODE (*tp) == MODIFY_EXPR
41590075Sobrien	       && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
41690075Sobrien	       && ((*lang_hooks.tree_inlining.auto_var_in_fn_p)
41790075Sobrien		   (TREE_OPERAND (*tp, 0), fn)))
41890075Sobrien	{
41990075Sobrien	  /* Some assignments VAR = VAR; don't generate any rtl code
42090075Sobrien	     and thus don't count as variable modification.  Avoid
42190075Sobrien	     keeping bogosities like 0 = 0.  */
42290075Sobrien	  tree decl = TREE_OPERAND (*tp, 0), value;
42390075Sobrien	  splay_tree_node n;
42490075Sobrien
42590075Sobrien	  n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
42690075Sobrien	  if (n)
42790075Sobrien	    {
42890075Sobrien	      value = (tree) n->value;
42990075Sobrien	      STRIP_TYPE_NOPS (value);
43090075Sobrien	      if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
43190075Sobrien		*tp = value;
43290075Sobrien	    }
43390075Sobrien	}
43490075Sobrien    }
43590075Sobrien
43690075Sobrien  /* Keep iterating.  */
43790075Sobrien  return NULL_TREE;
43890075Sobrien}
43990075Sobrien
44090075Sobrien/* Make a copy of the body of FN so that it can be inserted inline in
44190075Sobrien   another function.  */
44290075Sobrien
44390075Sobrienstatic tree
44490075Sobriencopy_body (id)
44590075Sobrien     inline_data *id;
44690075Sobrien{
44790075Sobrien  tree body;
44890075Sobrien
44990075Sobrien  body = DECL_SAVED_TREE (VARRAY_TOP_TREE (id->fns));
45090075Sobrien  walk_tree (&body, copy_body_r, id, NULL);
45190075Sobrien
45290075Sobrien  return body;
45390075Sobrien}
45490075Sobrien
45590075Sobrien/* Generate code to initialize the parameters of the function at the
45690075Sobrien   top of the stack in ID from the ARGS (presented as a TREE_LIST).  */
45790075Sobrien
45890075Sobrienstatic tree
45990075Sobrieninitialize_inlined_parameters (id, args, fn)
46090075Sobrien     inline_data *id;
46190075Sobrien     tree args;
46290075Sobrien     tree fn;
46390075Sobrien{
46490075Sobrien  tree init_stmts;
46590075Sobrien  tree parms;
46690075Sobrien  tree a;
46790075Sobrien  tree p;
46890075Sobrien
46990075Sobrien  /* Figure out what the parameters are.  */
47090075Sobrien  parms = DECL_ARGUMENTS (fn);
47190075Sobrien
47290075Sobrien  /* Start with no initializations whatsoever.  */
47390075Sobrien  init_stmts = NULL_TREE;
47490075Sobrien
47590075Sobrien  /* Loop through the parameter declarations, replacing each with an
47690075Sobrien     equivalent VAR_DECL, appropriately initialized.  */
47790075Sobrien  for (p = parms, a = args; p;
47890075Sobrien       a = a ? TREE_CHAIN (a) : a, p = TREE_CHAIN (p))
47990075Sobrien    {
48090075Sobrien      tree init_stmt;
48190075Sobrien      tree var;
48290075Sobrien      tree value;
48390075Sobrien
48490075Sobrien      /* Find the initializer.  */
48590075Sobrien      value = a ? TREE_VALUE (a) : NULL_TREE;
48690075Sobrien
48790075Sobrien      /* If the parameter is never assigned to, we may not need to
48890075Sobrien	 create a new variable here at all.  Instead, we may be able
48990075Sobrien	 to just use the argument value.  */
49090075Sobrien      if (TREE_READONLY (p)
49190075Sobrien	  && !TREE_ADDRESSABLE (p)
49290075Sobrien	  && value && !TREE_SIDE_EFFECTS (value))
49390075Sobrien	{
49490075Sobrien	  /* Simplify the value, if possible.  */
49590075Sobrien	  value = fold (DECL_P (value) ? decl_constant_value (value) : value);
49690075Sobrien
49790075Sobrien	  /* We can't risk substituting complex expressions.  They
49890075Sobrien	     might contain variables that will be assigned to later.
49990075Sobrien	     Theoretically, we could check the expression to see if
50090075Sobrien	     all of the variables that determine its value are
50190075Sobrien	     read-only, but we don't bother.  */
50290075Sobrien	  if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
50390075Sobrien	    {
50490075Sobrien	      /* If this is a declaration, wrap it a NOP_EXPR so that
50590075Sobrien		 we don't try to put the VALUE on the list of
50690075Sobrien		 BLOCK_VARS.  */
50790075Sobrien	      if (DECL_P (value))
50890075Sobrien		value = build1 (NOP_EXPR, TREE_TYPE (value), value);
50990075Sobrien
51090075Sobrien	      splay_tree_insert (id->decl_map,
51190075Sobrien				 (splay_tree_key) p,
51290075Sobrien				 (splay_tree_value) value);
51390075Sobrien	      continue;
51490075Sobrien	    }
51590075Sobrien	}
51690075Sobrien
51790075Sobrien      /* Make an equivalent VAR_DECL.  */
51890075Sobrien      var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
51990075Sobrien      /* Register the VAR_DECL as the equivalent for the PARM_DECL;
52090075Sobrien	 that way, when the PARM_DECL is encountered, it will be
52190075Sobrien	 automatically replaced by the VAR_DECL.  */
52290075Sobrien      splay_tree_insert (id->decl_map,
52390075Sobrien			 (splay_tree_key) p,
52490075Sobrien			 (splay_tree_value) var);
52590075Sobrien
52690075Sobrien      /* Declare this new variable.  */
52790075Sobrien      init_stmt = build_stmt (DECL_STMT, var);
52890075Sobrien      TREE_CHAIN (init_stmt) = init_stmts;
52990075Sobrien      init_stmts = init_stmt;
53090075Sobrien
53190075Sobrien      /* Initialize this VAR_DECL from the equivalent argument.  If
53290075Sobrien	 the argument is an object, created via a constructor or copy,
53390075Sobrien	 this will not result in an extra copy: the TARGET_EXPR
53490075Sobrien	 representing the argument will be bound to VAR, and the
53590075Sobrien	 object will be constructed in VAR.  */
53690075Sobrien      if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
53790075Sobrien	DECL_INITIAL (var) = value;
53890075Sobrien      else
53990075Sobrien	{
54090075Sobrien	  /* Even if P was TREE_READONLY, the new VAR should not be.
54190075Sobrien	     In the original code, we would have constructed a
54290075Sobrien	     temporary, and then the function body would have never
54390075Sobrien	     changed the value of P.  However, now, we will be
54490075Sobrien	     constructing VAR directly.  The constructor body may
54590075Sobrien	     change its value multiple times as it is being
54690075Sobrien	     constructed.  Therefore, it must not be TREE_READONLY;
54790075Sobrien	     the back-end assumes that TREE_READONLY variable is
54890075Sobrien	     assigned to only once.  */
54990075Sobrien	  TREE_READONLY (var) = 0;
55090075Sobrien
55190075Sobrien	  /* Build a run-time initialization.  */
55290075Sobrien	  init_stmt = build_stmt (EXPR_STMT,
55390075Sobrien				  build (INIT_EXPR, TREE_TYPE (p),
55490075Sobrien					 var, value));
55590075Sobrien	  /* Add this initialization to the list.  Note that we want the
55690075Sobrien	     declaration *after* the initialization because we are going
55790075Sobrien	     to reverse all the initialization statements below.  */
55890075Sobrien	  TREE_CHAIN (init_stmt) = init_stmts;
55990075Sobrien	  init_stmts = init_stmt;
56090075Sobrien	}
56190075Sobrien    }
56290075Sobrien
56390075Sobrien  /* Evaluate trailing arguments.  */
56490075Sobrien  for (; a; a = TREE_CHAIN (a))
56590075Sobrien    {
56690075Sobrien      tree init_stmt;
56790075Sobrien      tree value;
56890075Sobrien
56990075Sobrien      /* Find the initializer.  */
57090075Sobrien      value = a ? TREE_VALUE (a) : NULL_TREE;
57190075Sobrien
57290075Sobrien      if (! value || ! TREE_SIDE_EFFECTS (value))
57390075Sobrien	continue;
57490075Sobrien
57590075Sobrien      init_stmt = build_stmt (EXPR_STMT, value);
57690075Sobrien      TREE_CHAIN (init_stmt) = init_stmts;
57790075Sobrien      init_stmts = init_stmt;
57890075Sobrien    }
57990075Sobrien
58090075Sobrien  /* The initialization statements have been built up in reverse
58190075Sobrien     order.  Straighten them out now.  */
58290075Sobrien  return nreverse (init_stmts);
58390075Sobrien}
58490075Sobrien
58590075Sobrien/* Declare a return variable to replace the RESULT_DECL for the
58690075Sobrien   function we are calling.  An appropriate DECL_STMT is returned.
58790075Sobrien   The USE_STMT is filled in to contain a use of the declaration to
58890075Sobrien   indicate the return value of the function.  */
58990075Sobrien
59090075Sobrienstatic tree
59190075Sobriendeclare_return_variable (id, use_stmt)
59290075Sobrien     struct inline_data *id;
59390075Sobrien     tree *use_stmt;
59490075Sobrien{
59590075Sobrien  tree fn = VARRAY_TOP_TREE (id->fns);
59690075Sobrien  tree result = DECL_RESULT (fn);
59790075Sobrien  tree var;
59890075Sobrien  int need_return_decl = 1;
59990075Sobrien
60090075Sobrien  /* We don't need to do anything for functions that don't return
60190075Sobrien     anything.  */
60290075Sobrien  if (!result || VOID_TYPE_P (TREE_TYPE (result)))
60390075Sobrien    {
60490075Sobrien      *use_stmt = NULL_TREE;
60590075Sobrien      return NULL_TREE;
60690075Sobrien    }
60790075Sobrien
60890075Sobrien  var = ((*lang_hooks.tree_inlining.copy_res_decl_for_inlining)
60990075Sobrien	 (result, fn, VARRAY_TREE (id->fns, 0), id->decl_map,
61090075Sobrien	  &need_return_decl, &id->target_exprs));
61190075Sobrien
61290075Sobrien  /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
61390075Sobrien     way, when the RESULT_DECL is encountered, it will be
61490075Sobrien     automatically replaced by the VAR_DECL.  */
61590075Sobrien  splay_tree_insert (id->decl_map,
61690075Sobrien		     (splay_tree_key) result,
61790075Sobrien		     (splay_tree_value) var);
61890075Sobrien
61990075Sobrien  /* Build the USE_STMT.  If the return type of the function was
62090075Sobrien     promoted, convert it back to the expected type.  */
62190075Sobrien  if (TREE_TYPE (var) == TREE_TYPE (TREE_TYPE (fn)))
62290075Sobrien    *use_stmt = build_stmt (EXPR_STMT, var);
62390075Sobrien  else
62490075Sobrien    *use_stmt = build_stmt (EXPR_STMT,
62590075Sobrien			    build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)),
62690075Sobrien				    var));
62790075Sobrien
62890075Sobrien  TREE_ADDRESSABLE (*use_stmt) = 1;
62990075Sobrien
63090075Sobrien  /* Build the declaration statement if FN does not return an
63190075Sobrien     aggregate.  */
63290075Sobrien  if (need_return_decl)
63390075Sobrien    return build_stmt (DECL_STMT, var);
63490075Sobrien  /* If FN does return an aggregate, there's no need to declare the
63590075Sobrien     return variable; we're using a variable in our caller's frame.  */
63690075Sobrien  else
63790075Sobrien    return NULL_TREE;
63890075Sobrien}
63990075Sobrien
64090075Sobrien/* Returns non-zero if a function can be inlined as a tree.  */
64190075Sobrien
64290075Sobrienint
64390075Sobrientree_inlinable_function_p (fn)
64490075Sobrien     tree fn;
64590075Sobrien{
64690075Sobrien  return inlinable_function_p (fn, NULL);
64790075Sobrien}
64890075Sobrien
64990075Sobrien/* Returns non-zero if FN is a function that can be inlined into the
65090075Sobrien   inlining context ID_.  If ID_ is NULL, check whether the function
65190075Sobrien   can be inlined at all.  */
65290075Sobrien
65390075Sobrienstatic int
65490075Sobrieninlinable_function_p (fn, id)
65590075Sobrien     tree fn;
65690075Sobrien     inline_data *id;
65790075Sobrien{
65890075Sobrien  int inlinable;
65990075Sobrien
66090075Sobrien  /* If we've already decided this function shouldn't be inlined,
66190075Sobrien     there's no need to check again.  */
66290075Sobrien  if (DECL_UNINLINABLE (fn))
66390075Sobrien    return 0;
66490075Sobrien
66590075Sobrien  /* Assume it is not inlinable.  */
66690075Sobrien  inlinable = 0;
66790075Sobrien
66890075Sobrien  /* If we're not inlining things, then nothing is inlinable.  */
66990075Sobrien  if (! flag_inline_trees)
67090075Sobrien    ;
67190075Sobrien  /* If we're not inlining all functions and the function was not
67290075Sobrien     declared `inline', we don't inline it.  Don't think of
67390075Sobrien     disregarding DECL_INLINE when flag_inline_trees == 2; it's the
67490075Sobrien     front-end that must set DECL_INLINE in this case, because
67590075Sobrien     dwarf2out loses if a function is inlined that doesn't have
67690075Sobrien     DECL_INLINE set.  */
67790075Sobrien  else if (! DECL_INLINE (fn))
67890075Sobrien    ;
67990075Sobrien  /* We can't inline functions that are too big.  Only allow a single
68090075Sobrien     function to eat up half of our budget.  Make special allowance
68190075Sobrien     for extern inline functions, though.  */
68290075Sobrien  else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
68390075Sobrien	   && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2)
68490075Sobrien    ;
68590075Sobrien  /* All is well.  We can inline this function.  Traditionally, GCC
68690075Sobrien     has refused to inline functions using alloca, or functions whose
68790075Sobrien     values are returned in a PARALLEL, and a few other such obscure
68890075Sobrien     conditions.  We are not equally constrained at the tree level.  */
68990075Sobrien  else
69090075Sobrien    inlinable = 1;
69190075Sobrien
69290075Sobrien  /* Squirrel away the result so that we don't have to check again.  */
69390075Sobrien  DECL_UNINLINABLE (fn) = ! inlinable;
69490075Sobrien
69590075Sobrien  /* Even if this function is not itself too big to inline, it might
69690075Sobrien     be that we've done so much inlining already that we don't want to
69790075Sobrien     risk too much inlining any more and thus halve the acceptable
69890075Sobrien     size.  */
69990075Sobrien  if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
70090075Sobrien      && ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT
70190075Sobrien	  > MAX_INLINE_INSNS)
70290075Sobrien      && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4)
70390075Sobrien    inlinable = 0;
70490075Sobrien
70590075Sobrien  if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
70690075Sobrien    inlinable = 0;
70790075Sobrien
70890075Sobrien  /* If we don't have the function body available, we can't inline
70990075Sobrien     it.  */
71090075Sobrien  if (! DECL_SAVED_TREE (fn))
71190075Sobrien    inlinable = 0;
71290075Sobrien
71390075Sobrien  /* Check again, language hooks may have modified it.  */
71490075Sobrien  if (! inlinable || DECL_UNINLINABLE (fn))
71590075Sobrien    return 0;
71690075Sobrien
71790075Sobrien  /* Don't do recursive inlining, either.  We don't record this in
71890075Sobrien     DECL_UNINLINABLE; we may be able to inline this function later.  */
71990075Sobrien  if (id)
72090075Sobrien    {
72190075Sobrien      size_t i;
72290075Sobrien
72390075Sobrien      for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
72490075Sobrien	if (VARRAY_TREE (id->fns, i) == fn)
72590075Sobrien	  return 0;
72690075Sobrien
72790075Sobrien      if (DECL_INLINED_FNS (fn))
72890075Sobrien	{
72990075Sobrien	  int j;
73090075Sobrien	  tree inlined_fns = DECL_INLINED_FNS (fn);
73190075Sobrien
73290075Sobrien	  for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
73390075Sobrien	    if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
73490075Sobrien	      return 0;
73590075Sobrien	}
73690075Sobrien    }
73790075Sobrien
73890075Sobrien  /* Return the result.  */
73990075Sobrien  return inlinable;
74090075Sobrien}
74190075Sobrien
74290075Sobrien/* If *TP is a CALL_EXPR, replace it with its inline expansion.  */
74390075Sobrien
74490075Sobrienstatic tree
74590075Sobrienexpand_call_inline (tp, walk_subtrees, data)
74690075Sobrien     tree *tp;
74790075Sobrien     int *walk_subtrees;
74890075Sobrien     void *data;
74990075Sobrien{
75090075Sobrien  inline_data *id;
75190075Sobrien  tree t;
75290075Sobrien  tree expr;
75390075Sobrien  tree chain;
75490075Sobrien  tree fn;
75590075Sobrien  tree scope_stmt;
75690075Sobrien  tree use_stmt;
75790075Sobrien  tree arg_inits;
75890075Sobrien  tree *inlined_body;
75990075Sobrien  splay_tree st;
76090075Sobrien
76190075Sobrien  /* See what we've got.  */
76290075Sobrien  id = (inline_data *) data;
76390075Sobrien  t = *tp;
76490075Sobrien
76590075Sobrien  /* Recurse, but letting recursive invocations know that we are
76690075Sobrien     inside the body of a TARGET_EXPR.  */
76790075Sobrien  if (TREE_CODE (*tp) == TARGET_EXPR)
76890075Sobrien    {
76990075Sobrien      int i, len = first_rtl_op (TARGET_EXPR);
77090075Sobrien
77190075Sobrien      /* We're walking our own subtrees.  */
77290075Sobrien      *walk_subtrees = 0;
77390075Sobrien
77490075Sobrien      /* Push *TP on the stack of pending TARGET_EXPRs.  */
77590075Sobrien      VARRAY_PUSH_TREE (id->target_exprs, *tp);
77690075Sobrien
77790075Sobrien      /* Actually walk over them.  This loop is the body of
77890075Sobrien	 walk_trees, omitting the case where the TARGET_EXPR
77990075Sobrien	 itself is handled.  */
78090075Sobrien      for (i = 0; i < len; ++i)
78190075Sobrien	{
78290075Sobrien	  if (i == 2)
78390075Sobrien	    ++id->in_target_cleanup_p;
78490075Sobrien	  walk_tree (&TREE_OPERAND (*tp, i), expand_call_inline, data,
78590075Sobrien		     id->tree_pruner);
78690075Sobrien	  if (i == 2)
78790075Sobrien	    --id->in_target_cleanup_p;
78890075Sobrien	}
78990075Sobrien
79090075Sobrien      /* We're done with this TARGET_EXPR now.  */
79190075Sobrien      VARRAY_POP (id->target_exprs);
79290075Sobrien
79390075Sobrien      return NULL_TREE;
79490075Sobrien    }
79590075Sobrien
79690075Sobrien  if (TYPE_P (t))
79790075Sobrien    /* Because types were not copied in copy_body, CALL_EXPRs beneath
79890075Sobrien       them should not be expanded.  This can happen if the type is a
79990075Sobrien       dynamic array type, for example.  */
80090075Sobrien    *walk_subtrees = 0;
80190075Sobrien
80290075Sobrien  /* From here on, we're only interested in CALL_EXPRs.  */
80390075Sobrien  if (TREE_CODE (t) != CALL_EXPR)
80490075Sobrien    return NULL_TREE;
80590075Sobrien
80690075Sobrien  /* First, see if we can figure out what function is being called.
80790075Sobrien     If we cannot, then there is no hope of inlining the function.  */
80890075Sobrien  fn = get_callee_fndecl (t);
80990075Sobrien  if (!fn)
81090075Sobrien    return NULL_TREE;
81190075Sobrien
81290075Sobrien  /* If fn is a declaration of a function in a nested scope that was
81390075Sobrien     globally declared inline, we don't set its DECL_INITIAL.
81490075Sobrien     However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the
81590075Sobrien     C++ front-end uses it for cdtors to refer to their internal
81690075Sobrien     declarations, that are not real functions.  Fortunately those
81790075Sobrien     don't have trees to be saved, so we can tell by checking their
81890075Sobrien     DECL_SAVED_TREE.  */
81990075Sobrien  if (! DECL_INITIAL (fn)
82090075Sobrien      && DECL_ABSTRACT_ORIGIN (fn)
82190075Sobrien      && DECL_SAVED_TREE (DECL_ABSTRACT_ORIGIN (fn)))
82290075Sobrien    fn = DECL_ABSTRACT_ORIGIN (fn);
82390075Sobrien
82490075Sobrien  /* Don't try to inline functions that are not well-suited to
82590075Sobrien     inlining.  */
82690075Sobrien  if (!inlinable_function_p (fn, id))
82790075Sobrien    return NULL_TREE;
82890075Sobrien
82990075Sobrien  if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
83090075Sobrien    return NULL_TREE;
83190075Sobrien
83290075Sobrien  /* Set the current filename and line number to the function we are
83390075Sobrien     inlining so that when we create new _STMT nodes here they get
83490075Sobrien     line numbers corresponding to the function we are calling.  We
83590075Sobrien     wrap the whole inlined body in an EXPR_WITH_FILE_AND_LINE as well
83690075Sobrien     because individual statements don't record the filename.  */
83790075Sobrien  push_srcloc (fn->decl.filename, fn->decl.linenum);
83890075Sobrien
83990075Sobrien  /* Build a statement-expression containing code to initialize the
84090075Sobrien     arguments, the actual inline expansion of the body, and a label
84190075Sobrien     for the return statements within the function to jump to.  The
84290075Sobrien     type of the statement expression is the return type of the
84390075Sobrien     function call.  */
84490075Sobrien  expr = build1 (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE);
84590075Sobrien
84690075Sobrien  /* Local declarations will be replaced by their equivalents in this
84790075Sobrien     map.  */
84890075Sobrien  st = id->decl_map;
84990075Sobrien  id->decl_map = splay_tree_new (splay_tree_compare_pointers,
85090075Sobrien				 NULL, NULL);
85190075Sobrien
85290075Sobrien  /* Initialize the parameters.  */
85390075Sobrien  arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn);
85490075Sobrien  /* Expand any inlined calls in the initializers.  Do this before we
85590075Sobrien     push FN on the stack of functions we are inlining; we want to
85690075Sobrien     inline calls to FN that appear in the initializers for the
85790075Sobrien     parameters.  */
85890075Sobrien  expand_calls_inline (&arg_inits, id);
85990075Sobrien  /* And add them to the tree.  */
86090075Sobrien  STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits);
86190075Sobrien
86290075Sobrien  /* Record the function we are about to inline so that we can avoid
86390075Sobrien     recursing into it.  */
86490075Sobrien  VARRAY_PUSH_TREE (id->fns, fn);
86590075Sobrien
86690075Sobrien  /* Record the function we are about to inline if optimize_function
86790075Sobrien     has not been called on it yet and we don't have it in the list.  */
86890075Sobrien  if (! DECL_INLINED_FNS (fn))
86990075Sobrien    {
87090075Sobrien      int i;
87190075Sobrien
87290075Sobrien      for (i = VARRAY_ACTIVE_SIZE (id->inlined_fns) - 1; i >= 0; i--)
87390075Sobrien	if (VARRAY_TREE (id->inlined_fns, i) == fn)
87490075Sobrien	  break;
87590075Sobrien      if (i < 0)
87690075Sobrien	VARRAY_PUSH_TREE (id->inlined_fns, fn);
87790075Sobrien    }
87890075Sobrien
87990075Sobrien  /* Return statements in the function body will be replaced by jumps
88090075Sobrien     to the RET_LABEL.  */
88190075Sobrien  id->ret_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
88290075Sobrien  DECL_CONTEXT (id->ret_label) = VARRAY_TREE (id->fns, 0);
88390075Sobrien
88490075Sobrien  if (! DECL_INITIAL (fn)
88590075Sobrien      || TREE_CODE (DECL_INITIAL (fn)) != BLOCK)
88690075Sobrien    abort ();
88790075Sobrien
88890075Sobrien  /* Create a block to put the parameters in.  We have to do this
88990075Sobrien     after the parameters have been remapped because remapping
89090075Sobrien     parameters is different from remapping ordinary variables.  */
89190075Sobrien  scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
89290075Sobrien  SCOPE_BEGIN_P (scope_stmt) = 1;
89390075Sobrien  SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
89490075Sobrien  remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
89590075Sobrien  TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr);
89690075Sobrien  STMT_EXPR_STMT (expr) = scope_stmt;
89790075Sobrien
89890075Sobrien  /* Tell the debugging backends that this block represents the
89990075Sobrien     outermost scope of the inlined function.  */
90090075Sobrien  if (SCOPE_STMT_BLOCK (scope_stmt))
90190075Sobrien    BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
90290075Sobrien
90390075Sobrien  /* Declare the return variable for the function.  */
90490075Sobrien  STMT_EXPR_STMT (expr)
90590075Sobrien    = chainon (STMT_EXPR_STMT (expr),
90690075Sobrien	       declare_return_variable (id, &use_stmt));
90790075Sobrien
90890075Sobrien  /* After we've initialized the parameters, we insert the body of the
90990075Sobrien     function itself.  */
91090075Sobrien  inlined_body = &STMT_EXPR_STMT (expr);
91190075Sobrien  while (*inlined_body)
91290075Sobrien    inlined_body = &TREE_CHAIN (*inlined_body);
91390075Sobrien  *inlined_body = copy_body (id);
91490075Sobrien
91590075Sobrien  /* Close the block for the parameters.  */
91690075Sobrien  scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
91790075Sobrien  SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
91890075Sobrien  remap_block (scope_stmt, NULL_TREE, id);
91990075Sobrien  STMT_EXPR_STMT (expr)
92090075Sobrien    = chainon (STMT_EXPR_STMT (expr), scope_stmt);
92190075Sobrien
92290075Sobrien  /* After the body of the function comes the RET_LABEL.  This must come
92390075Sobrien     before we evaluate the returned value below, because that evalulation
92490075Sobrien     may cause RTL to be generated.  */
92590075Sobrien  STMT_EXPR_STMT (expr)
92690075Sobrien    = chainon (STMT_EXPR_STMT (expr),
92790075Sobrien	       build_stmt (LABEL_STMT, id->ret_label));
92890075Sobrien
92990075Sobrien  /* Finally, mention the returned value so that the value of the
93090075Sobrien     statement-expression is the returned value of the function.  */
93190075Sobrien  STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt);
93290075Sobrien
93390075Sobrien  /* Clean up.  */
93490075Sobrien  splay_tree_delete (id->decl_map);
93590075Sobrien  id->decl_map = st;
93690075Sobrien
93790075Sobrien  /* The new expression has side-effects if the old one did.  */
93890075Sobrien  TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (t);
93990075Sobrien
94090075Sobrien  /* Replace the call by the inlined body.  Wrap it in an
94190075Sobrien     EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes
94290075Sobrien     pointing to the right place.  */
94390075Sobrien  chain = TREE_CHAIN (*tp);
94490075Sobrien  *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
94590075Sobrien			/*col=*/0);
94690075Sobrien  EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
94790075Sobrien  TREE_CHAIN (*tp) = chain;
94890075Sobrien  pop_srcloc ();
94990075Sobrien
95090075Sobrien  /* If the value of the new expression is ignored, that's OK.  We
95190075Sobrien     don't warn about this for CALL_EXPRs, so we shouldn't warn about
95290075Sobrien     the equivalent inlined version either.  */
95390075Sobrien  TREE_USED (*tp) = 1;
95490075Sobrien
95590075Sobrien  /* Our function now has more statements than it did before.  */
95690075Sobrien  DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn);
95790075Sobrien  id->inlined_stmts += DECL_NUM_STMTS (fn);
95890075Sobrien
95990075Sobrien  /* Recurse into the body of the just inlined function.  */
96090075Sobrien  expand_calls_inline (inlined_body, id);
96190075Sobrien  VARRAY_POP (id->fns);
96290075Sobrien
96390075Sobrien  /* If we've returned to the top level, clear out the record of how
96490075Sobrien     much inlining has been done.  */
96590075Sobrien  if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn)
96690075Sobrien    id->inlined_stmts = 0;
96790075Sobrien
96890075Sobrien  /* Don't walk into subtrees.  We've already handled them above.  */
96990075Sobrien  *walk_subtrees = 0;
97090075Sobrien
97190075Sobrien  (*lang_hooks.tree_inlining.end_inlining) (fn);
97290075Sobrien
97390075Sobrien  /* Keep iterating.  */
97490075Sobrien  return NULL_TREE;
97590075Sobrien}
97690075Sobrien
97790075Sobrien/* Walk over the entire tree *TP, replacing CALL_EXPRs with inline
97890075Sobrien   expansions as appropriate.  */
97990075Sobrien
98090075Sobrienstatic void
98190075Sobrienexpand_calls_inline (tp, id)
98290075Sobrien     tree *tp;
98390075Sobrien     inline_data *id;
98490075Sobrien{
98590075Sobrien  /* Search through *TP, replacing all calls to inline functions by
98690075Sobrien     appropriate equivalents.  Use walk_tree in no-duplicates mode
98790075Sobrien     to avoid exponential time complexity.  (We can't just use
98890075Sobrien     walk_tree_without_duplicates, because of the special TARGET_EXPR
98990075Sobrien     handling in expand_calls.  The hash table is set up in
99090075Sobrien     optimize_function.  */
99190075Sobrien  walk_tree (tp, expand_call_inline, id, id->tree_pruner);
99290075Sobrien}
99390075Sobrien
99490075Sobrien/* Expand calls to inline functions in the body of FN.  */
99590075Sobrien
99690075Sobrienvoid
99790075Sobrienoptimize_inline_calls (fn)
99890075Sobrien     tree fn;
99990075Sobrien{
100090075Sobrien  inline_data id;
100190075Sobrien  tree prev_fn;
100290075Sobrien
100390075Sobrien  /* Clear out ID.  */
100490075Sobrien  memset (&id, 0, sizeof (id));
100590075Sobrien
100690075Sobrien  /* Don't allow recursion into FN.  */
100790075Sobrien  VARRAY_TREE_INIT (id.fns, 32, "fns");
100890075Sobrien  VARRAY_PUSH_TREE (id.fns, fn);
100990075Sobrien  /* Or any functions that aren't finished yet.  */
101090075Sobrien  prev_fn = NULL_TREE;
101190075Sobrien  if (current_function_decl)
101290075Sobrien    {
101390075Sobrien      VARRAY_PUSH_TREE (id.fns, current_function_decl);
101490075Sobrien      prev_fn = current_function_decl;
101590075Sobrien    }
101690075Sobrien
101790075Sobrien  prev_fn = ((*lang_hooks.tree_inlining.add_pending_fn_decls)
101890075Sobrien	     (&id.fns, prev_fn));
101990075Sobrien
102090075Sobrien  /* Create the stack of TARGET_EXPRs.  */
102190075Sobrien  VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs");
102290075Sobrien
102390075Sobrien  /* Create the list of functions this call will inline.  */
102490075Sobrien  VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns");
102590075Sobrien
102690075Sobrien  /* Keep track of the low-water mark, i.e., the point where the first
102790075Sobrien     real inlining is represented in ID.FNS.  */
102890075Sobrien  id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns);
102990075Sobrien
103090075Sobrien  /* Replace all calls to inline functions with the bodies of those
103190075Sobrien     functions.  */
103290075Sobrien  id.tree_pruner = htab_create (37, htab_hash_pointer,
103390075Sobrien				htab_eq_pointer, NULL);
103490075Sobrien  expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
103590075Sobrien
103690075Sobrien  /* Clean up.  */
103790075Sobrien  htab_delete (id.tree_pruner);
103890075Sobrien  VARRAY_FREE (id.fns);
103990075Sobrien  VARRAY_FREE (id.target_exprs);
104090075Sobrien  if (DECL_LANG_SPECIFIC (fn))
104190075Sobrien    {
104290075Sobrien      tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns));
104390075Sobrien
104490075Sobrien      memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0),
104590075Sobrien	      VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree));
104690075Sobrien      DECL_INLINED_FNS (fn) = ifn;
104790075Sobrien    }
104890075Sobrien  VARRAY_FREE (id.inlined_fns);
104990075Sobrien}
105090075Sobrien
105190075Sobrien/* FN is a function that has a complete body, and CLONE is a function
105290075Sobrien   whose body is to be set to a copy of FN, mapping argument
105390075Sobrien   declarations according to the ARG_MAP splay_tree.  */
105490075Sobrien
105590075Sobrienvoid
105690075Sobrienclone_body (clone, fn, arg_map)
105790075Sobrien     tree clone, fn;
105890075Sobrien     void *arg_map;
105990075Sobrien{
106090075Sobrien  inline_data id;
106190075Sobrien
106290075Sobrien  /* Clone the body, as if we were making an inline call.  But, remap
106390075Sobrien     the parameters in the callee to the parameters of caller.  If
106490075Sobrien     there's an in-charge parameter, map it to an appropriate
106590075Sobrien     constant.  */
106690075Sobrien  memset (&id, 0, sizeof (id));
106790075Sobrien  VARRAY_TREE_INIT (id.fns, 2, "fns");
106890075Sobrien  VARRAY_PUSH_TREE (id.fns, clone);
106990075Sobrien  VARRAY_PUSH_TREE (id.fns, fn);
107090075Sobrien  id.decl_map = (splay_tree)arg_map;
107190075Sobrien
107290075Sobrien  /* Cloning is treated slightly differently from inlining.  Set
107390075Sobrien     CLONING_P so that it's clear which operation we're performing.  */
107490075Sobrien  id.cloning_p = true;
107590075Sobrien
107690075Sobrien  /* Actually copy the body.  */
107790075Sobrien  TREE_CHAIN (DECL_SAVED_TREE (clone)) = copy_body (&id);
107890075Sobrien
107990075Sobrien  /* Clean up.  */
108090075Sobrien  VARRAY_FREE (id.fns);
108190075Sobrien}
108290075Sobrien
108390075Sobrien/* Apply FUNC to all the sub-trees of TP in a pre-order traversal.
108490075Sobrien   FUNC is called with the DATA and the address of each sub-tree.  If
108590075Sobrien   FUNC returns a non-NULL value, the traversal is aborted, and the
108690075Sobrien   value returned by FUNC is returned.  If HTAB is non-NULL it is used
108790075Sobrien   to record the nodes visited, and to avoid visiting a node more than
108890075Sobrien   once.  */
108990075Sobrien
109090075Sobrientree
109190075Sobrienwalk_tree (tp, func, data, htab_)
109290075Sobrien     tree *tp;
109390075Sobrien     walk_tree_fn func;
109490075Sobrien     void *data;
109590075Sobrien     void *htab_;
109690075Sobrien{
109790075Sobrien  htab_t htab = (htab_t) htab_;
109890075Sobrien  enum tree_code code;
109990075Sobrien  int walk_subtrees;
110090075Sobrien  tree result;
110190075Sobrien
110290075Sobrien#define WALK_SUBTREE(NODE)				\
110390075Sobrien  do							\
110490075Sobrien    {							\
110590075Sobrien      result = walk_tree (&(NODE), func, data, htab);	\
110690075Sobrien      if (result)					\
110790075Sobrien	return result;					\
110890075Sobrien    }							\
110990075Sobrien  while (0)
111090075Sobrien
111190075Sobrien#define WALK_SUBTREE_TAIL(NODE)				\
111290075Sobrien  do							\
111390075Sobrien    {							\
111490075Sobrien       tp = & (NODE);					\
111590075Sobrien       goto tail_recurse;				\
111690075Sobrien    }							\
111790075Sobrien  while (0)
111890075Sobrien
111990075Sobrien tail_recurse:
112090075Sobrien  /* Skip empty subtrees.  */
112190075Sobrien  if (!*tp)
112290075Sobrien    return NULL_TREE;
112390075Sobrien
112490075Sobrien  if (htab)
112590075Sobrien    {
112690075Sobrien      void **slot;
112790075Sobrien
112890075Sobrien      /* Don't walk the same tree twice, if the user has requested
112990075Sobrien         that we avoid doing so.  */
113090075Sobrien      if (htab_find (htab, *tp))
113190075Sobrien	return NULL_TREE;
113290075Sobrien      /* If we haven't already seen this node, add it to the table.  */
113390075Sobrien      slot = htab_find_slot (htab, *tp, INSERT);
113490075Sobrien      *slot = *tp;
113590075Sobrien    }
113690075Sobrien
113790075Sobrien  /* Call the function.  */
113890075Sobrien  walk_subtrees = 1;
113990075Sobrien  result = (*func) (tp, &walk_subtrees, data);
114090075Sobrien
114190075Sobrien  /* If we found something, return it.  */
114290075Sobrien  if (result)
114390075Sobrien    return result;
114490075Sobrien
114590075Sobrien  code = TREE_CODE (*tp);
114690075Sobrien
114790075Sobrien  /* Even if we didn't, FUNC may have decided that there was nothing
114890075Sobrien     interesting below this point in the tree.  */
114990075Sobrien  if (!walk_subtrees)
115090075Sobrien    {
115190075Sobrien      if (statement_code_p (code) || code == TREE_LIST
115290075Sobrien	  || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
115390075Sobrien	/* But we still need to check our siblings.  */
115490075Sobrien	WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
115590075Sobrien      else
115690075Sobrien	return NULL_TREE;
115790075Sobrien    }
115890075Sobrien
115990075Sobrien  /* Handle common cases up front.  */
116090075Sobrien  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
116190075Sobrien      || TREE_CODE_CLASS (code) == 'r'
116290075Sobrien      || TREE_CODE_CLASS (code) == 's')
116390075Sobrien    {
116490075Sobrien      int i, len;
116590075Sobrien
116690075Sobrien      /* Set lineno here so we get the right instantiation context
116790075Sobrien	 if we call instantiate_decl from inlinable_function_p.  */
116890075Sobrien      if (statement_code_p (code) && !STMT_LINENO_FOR_FN_P (*tp))
116990075Sobrien	lineno = STMT_LINENO (*tp);
117090075Sobrien
117190075Sobrien      /* Walk over all the sub-trees of this operand.  */
117290075Sobrien      len = first_rtl_op (code);
117390075Sobrien      /* TARGET_EXPRs are peculiar: operands 1 and 3 can be the same.
117490075Sobrien	 But, we only want to walk once.  */
117590075Sobrien      if (code == TARGET_EXPR
117690075Sobrien	  && TREE_OPERAND (*tp, 3) == TREE_OPERAND (*tp, 1))
117790075Sobrien	--len;
117890075Sobrien      /* Go through the subtrees.  We need to do this in forward order so
117990075Sobrien         that the scope of a FOR_EXPR is handled properly.  */
118090075Sobrien      for (i = 0; i < len; ++i)
118190075Sobrien	WALK_SUBTREE (TREE_OPERAND (*tp, i));
118290075Sobrien
118390075Sobrien      /* For statements, we also walk the chain so that we cover the
118490075Sobrien	 entire statement tree.  */
118590075Sobrien      if (statement_code_p (code))
118690075Sobrien	{
118790075Sobrien	  if (code == DECL_STMT
118890075Sobrien	      && DECL_STMT_DECL (*tp)
118990075Sobrien	      && DECL_P (DECL_STMT_DECL (*tp)))
119090075Sobrien	    {
119190075Sobrien	      /* Walk the DECL_INITIAL and DECL_SIZE.  We don't want to walk
119290075Sobrien		 into declarations that are just mentioned, rather than
119390075Sobrien		 declared; they don't really belong to this part of the tree.
119490075Sobrien		 And, we can see cycles: the initializer for a declaration can
119590075Sobrien		 refer to the declaration itself.  */
119690075Sobrien	      WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp)));
119790075Sobrien	      WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp)));
119890075Sobrien	      WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
119990075Sobrien	    }
120090075Sobrien
120190075Sobrien	  /* This can be tail-recursion optimized if we write it this way.  */
120290075Sobrien	  WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
120390075Sobrien	}
120490075Sobrien
120590075Sobrien      /* We didn't find what we were looking for.  */
120690075Sobrien      return NULL_TREE;
120790075Sobrien    }
120890075Sobrien  else if (TREE_CODE_CLASS (code) == 'd')
120990075Sobrien    {
121090075Sobrien      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
121190075Sobrien    }
121290075Sobrien
121390075Sobrien  result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
121490075Sobrien						      data, htab);
121590075Sobrien  if (result || ! walk_subtrees)
121690075Sobrien    return result;
121790075Sobrien
121890075Sobrien  /* Not one of the easy cases.  We must explicitly go through the
121990075Sobrien     children.  */
122090075Sobrien  switch (code)
122190075Sobrien    {
122290075Sobrien    case ERROR_MARK:
122390075Sobrien    case IDENTIFIER_NODE:
122490075Sobrien    case INTEGER_CST:
122590075Sobrien    case REAL_CST:
122690075Sobrien    case STRING_CST:
122790075Sobrien    case REAL_TYPE:
122890075Sobrien    case COMPLEX_TYPE:
122990075Sobrien    case VECTOR_TYPE:
123090075Sobrien    case VOID_TYPE:
123190075Sobrien    case BOOLEAN_TYPE:
123290075Sobrien    case UNION_TYPE:
123390075Sobrien    case ENUMERAL_TYPE:
123490075Sobrien    case BLOCK:
123590075Sobrien    case RECORD_TYPE:
123690075Sobrien      /* None of thse have subtrees other than those already walked
123790075Sobrien         above.  */
123890075Sobrien      break;
123990075Sobrien
124090075Sobrien    case POINTER_TYPE:
124190075Sobrien    case REFERENCE_TYPE:
124290075Sobrien      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
124390075Sobrien      break;
124490075Sobrien
124590075Sobrien    case TREE_LIST:
124690075Sobrien      WALK_SUBTREE (TREE_VALUE (*tp));
124790075Sobrien      WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
124890075Sobrien      break;
124990075Sobrien
125090075Sobrien    case TREE_VEC:
125190075Sobrien      {
125290075Sobrien	int len = TREE_VEC_LENGTH (*tp);
125390075Sobrien
125490075Sobrien	if (len == 0)
125590075Sobrien	  break;
125690075Sobrien
125790075Sobrien	/* Walk all elements but the first.  */
125890075Sobrien	while (--len)
125990075Sobrien	  WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
126090075Sobrien
126190075Sobrien	/* Now walk the first one as a tail call.  */
126290075Sobrien	WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
126390075Sobrien      }
126490075Sobrien
126590075Sobrien    case COMPLEX_CST:
126690075Sobrien      WALK_SUBTREE (TREE_REALPART (*tp));
126790075Sobrien      WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
126890075Sobrien
126990075Sobrien    case CONSTRUCTOR:
127090075Sobrien      WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
127190075Sobrien
127290075Sobrien    case METHOD_TYPE:
127390075Sobrien      WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
127490075Sobrien      /* Fall through.  */
127590075Sobrien
127690075Sobrien    case FUNCTION_TYPE:
127790075Sobrien      WALK_SUBTREE (TREE_TYPE (*tp));
127890075Sobrien      {
127990075Sobrien	tree arg = TYPE_ARG_TYPES (*tp);
128090075Sobrien
128190075Sobrien	/* We never want to walk into default arguments.  */
128290075Sobrien	for (; arg; arg = TREE_CHAIN (arg))
128390075Sobrien	  WALK_SUBTREE (TREE_VALUE (arg));
128490075Sobrien      }
128590075Sobrien      break;
128690075Sobrien
128790075Sobrien    case ARRAY_TYPE:
128890075Sobrien      WALK_SUBTREE (TREE_TYPE (*tp));
128990075Sobrien      WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
129090075Sobrien
129190075Sobrien    case INTEGER_TYPE:
129290075Sobrien      WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
129390075Sobrien      WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
129490075Sobrien
129590075Sobrien    case OFFSET_TYPE:
129690075Sobrien      WALK_SUBTREE (TREE_TYPE (*tp));
129790075Sobrien      WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
129890075Sobrien
129990075Sobrien    default:
130090075Sobrien      abort ();
130190075Sobrien    }
130290075Sobrien
130390075Sobrien  /* We didn't find what we were looking for.  */
130490075Sobrien  return NULL_TREE;
130590075Sobrien
130690075Sobrien#undef WALK_SUBTREE
130790075Sobrien}
130890075Sobrien
130990075Sobrien/* Like walk_tree, but does not walk duplicate nodes more than
131090075Sobrien   once.  */
131190075Sobrien
131290075Sobrientree
131390075Sobrienwalk_tree_without_duplicates (tp, func, data)
131490075Sobrien     tree *tp;
131590075Sobrien     walk_tree_fn func;
131690075Sobrien     void *data;
131790075Sobrien{
131890075Sobrien  tree result;
131990075Sobrien  htab_t htab;
132090075Sobrien
132190075Sobrien  htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
132290075Sobrien  result = walk_tree (tp, func, data, htab);
132390075Sobrien  htab_delete (htab);
132490075Sobrien  return result;
132590075Sobrien}
132690075Sobrien
132790075Sobrien/* Passed to walk_tree.  Copies the node pointed to, if appropriate.  */
132890075Sobrien
132990075Sobrientree
133090075Sobriencopy_tree_r (tp, walk_subtrees, data)
133190075Sobrien     tree *tp;
133290075Sobrien     int *walk_subtrees;
133390075Sobrien     void *data ATTRIBUTE_UNUSED;
133490075Sobrien{
133590075Sobrien  enum tree_code code = TREE_CODE (*tp);
133690075Sobrien
133790075Sobrien  /* We make copies of most nodes.  */
133890075Sobrien  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
133990075Sobrien      || TREE_CODE_CLASS (code) == 'r'
134090075Sobrien      || TREE_CODE_CLASS (code) == 'c'
134190075Sobrien      || TREE_CODE_CLASS (code) == 's'
134290075Sobrien      || code == TREE_LIST
134390075Sobrien      || code == TREE_VEC
134490075Sobrien      || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp))
134590075Sobrien    {
134690075Sobrien      /* Because the chain gets clobbered when we make a copy, we save it
134790075Sobrien	 here.  */
134890075Sobrien      tree chain = TREE_CHAIN (*tp);
134990075Sobrien
135090075Sobrien      /* Copy the node.  */
135190075Sobrien      *tp = copy_node (*tp);
135290075Sobrien
135390075Sobrien      /* Now, restore the chain, if appropriate.  That will cause
135490075Sobrien	 walk_tree to walk into the chain as well.  */
135590075Sobrien      if (code == PARM_DECL || code == TREE_LIST
135690075Sobrien	  || (*lang_hooks.tree_inlining.tree_chain_matters_p) (*tp)
135790075Sobrien	  || statement_code_p (code))
135890075Sobrien	TREE_CHAIN (*tp) = chain;
135990075Sobrien
136090075Sobrien      /* For now, we don't update BLOCKs when we make copies.  So, we
136190075Sobrien	 have to nullify all scope-statements.  */
136290075Sobrien      if (TREE_CODE (*tp) == SCOPE_STMT)
136390075Sobrien	SCOPE_STMT_BLOCK (*tp) = NULL_TREE;
136490075Sobrien    }
136590075Sobrien  else if (TREE_CODE_CLASS (code) == 't')
136690075Sobrien    /* There's no need to copy types, or anything beneath them.  */
136790075Sobrien    *walk_subtrees = 0;
136890075Sobrien
136990075Sobrien  return NULL_TREE;
137090075Sobrien}
137190075Sobrien
137290075Sobrien/* The SAVE_EXPR pointed to by TP is being copied.  If ST contains
137390075Sobrien   information indicating to what new SAVE_EXPR this one should be
137490075Sobrien   mapped, use that one.  Otherwise, create a new node and enter it in
137590075Sobrien   ST.  FN is the function into which the copy will be placed.  */
137690075Sobrien
137790075Sobrienvoid
137890075Sobrienremap_save_expr (tp, st_, fn, walk_subtrees)
137990075Sobrien     tree *tp;
138090075Sobrien     void *st_;
138190075Sobrien     tree fn;
138290075Sobrien     int *walk_subtrees;
138390075Sobrien{
138490075Sobrien  splay_tree st = (splay_tree) st_;
138590075Sobrien  splay_tree_node n;
138690075Sobrien
138790075Sobrien  /* See if we already encountered this SAVE_EXPR.  */
138890075Sobrien  n = splay_tree_lookup (st, (splay_tree_key) *tp);
138990075Sobrien
139090075Sobrien  /* If we didn't already remap this SAVE_EXPR, do so now.  */
139190075Sobrien  if (!n)
139290075Sobrien    {
139390075Sobrien      tree t = copy_node (*tp);
139490075Sobrien
139590075Sobrien      /* The SAVE_EXPR is now part of the function into which we
139690075Sobrien	 are inlining this body.  */
139790075Sobrien      SAVE_EXPR_CONTEXT (t) = fn;
139890075Sobrien      /* And we haven't evaluated it yet.  */
139990075Sobrien      SAVE_EXPR_RTL (t) = NULL_RTX;
140090075Sobrien      /* Remember this SAVE_EXPR.  */
140190075Sobrien      n = splay_tree_insert (st,
140290075Sobrien			     (splay_tree_key) *tp,
140390075Sobrien			     (splay_tree_value) t);
140490075Sobrien      /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
140590075Sobrien      splay_tree_insert (st, (splay_tree_key) t,
140690075Sobrien			 (splay_tree_value) error_mark_node);
140790075Sobrien    }
140890075Sobrien  else
140990075Sobrien    /* We've already walked into this SAVE_EXPR, so we needn't do it
141090075Sobrien       again.  */
141190075Sobrien    *walk_subtrees = 0;
141290075Sobrien
141390075Sobrien  /* Replace this SAVE_EXPR with the copy.  */
141490075Sobrien  *tp = (tree) n->value;
141590075Sobrien}
1416