xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-inline.c (revision e4b17023d31ea40e02fa06b141db27753ecc6934)
1*e4b17023SJohn Marino /* Tree inlining.
2*e4b17023SJohn Marino    Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
3*e4b17023SJohn Marino    2012 Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Alexandre Oliva <aoliva@redhat.com>
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11*e4b17023SJohn Marino any later version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*e4b17023SJohn Marino GNU General Public License for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "diagnostic-core.h"
27*e4b17023SJohn Marino #include "tree.h"
28*e4b17023SJohn Marino #include "tree-inline.h"
29*e4b17023SJohn Marino #include "flags.h"
30*e4b17023SJohn Marino #include "params.h"
31*e4b17023SJohn Marino #include "input.h"
32*e4b17023SJohn Marino #include "insn-config.h"
33*e4b17023SJohn Marino #include "hashtab.h"
34*e4b17023SJohn Marino #include "langhooks.h"
35*e4b17023SJohn Marino #include "basic-block.h"
36*e4b17023SJohn Marino #include "tree-iterator.h"
37*e4b17023SJohn Marino #include "cgraph.h"
38*e4b17023SJohn Marino #include "intl.h"
39*e4b17023SJohn Marino #include "tree-mudflap.h"
40*e4b17023SJohn Marino #include "tree-flow.h"
41*e4b17023SJohn Marino #include "function.h"
42*e4b17023SJohn Marino #include "tree-flow.h"
43*e4b17023SJohn Marino #include "tree-pretty-print.h"
44*e4b17023SJohn Marino #include "except.h"
45*e4b17023SJohn Marino #include "debug.h"
46*e4b17023SJohn Marino #include "pointer-set.h"
47*e4b17023SJohn Marino #include "ipa-prop.h"
48*e4b17023SJohn Marino #include "value-prof.h"
49*e4b17023SJohn Marino #include "tree-pass.h"
50*e4b17023SJohn Marino #include "target.h"
51*e4b17023SJohn Marino #include "integrate.h"
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino #include "rtl.h"	/* FIXME: For asm_str_count.  */
54*e4b17023SJohn Marino 
55*e4b17023SJohn Marino /* I'm not real happy about this, but we need to handle gimple and
56*e4b17023SJohn Marino    non-gimple trees.  */
57*e4b17023SJohn Marino #include "gimple.h"
58*e4b17023SJohn Marino 
59*e4b17023SJohn Marino /* Inlining, Cloning, Versioning, Parallelization
60*e4b17023SJohn Marino 
61*e4b17023SJohn Marino    Inlining: a function body is duplicated, but the PARM_DECLs are
62*e4b17023SJohn Marino    remapped into VAR_DECLs, and non-void RETURN_EXPRs become
63*e4b17023SJohn Marino    MODIFY_EXPRs that store to a dedicated returned-value variable.
64*e4b17023SJohn Marino    The duplicated eh_region info of the copy will later be appended
65*e4b17023SJohn Marino    to the info for the caller; the eh_region info in copied throwing
66*e4b17023SJohn Marino    statements and RESX statements are adjusted accordingly.
67*e4b17023SJohn Marino 
68*e4b17023SJohn Marino    Cloning: (only in C++) We have one body for a con/de/structor, and
69*e4b17023SJohn Marino    multiple function decls, each with a unique parameter list.
70*e4b17023SJohn Marino    Duplicate the body, using the given splay tree; some parameters
71*e4b17023SJohn Marino    will become constants (like 0 or 1).
72*e4b17023SJohn Marino 
73*e4b17023SJohn Marino    Versioning: a function body is duplicated and the result is a new
74*e4b17023SJohn Marino    function rather than into blocks of an existing function as with
75*e4b17023SJohn Marino    inlining.  Some parameters will become constants.
76*e4b17023SJohn Marino 
77*e4b17023SJohn Marino    Parallelization: a region of a function is duplicated resulting in
78*e4b17023SJohn Marino    a new function.  Variables may be replaced with complex expressions
79*e4b17023SJohn Marino    to enable shared variable semantics.
80*e4b17023SJohn Marino 
81*e4b17023SJohn Marino    All of these will simultaneously lookup any callgraph edges.  If
82*e4b17023SJohn Marino    we're going to inline the duplicated function body, and the given
83*e4b17023SJohn Marino    function has some cloned callgraph nodes (one for each place this
84*e4b17023SJohn Marino    function will be inlined) those callgraph edges will be duplicated.
85*e4b17023SJohn Marino    If we're cloning the body, those callgraph edges will be
86*e4b17023SJohn Marino    updated to point into the new body.  (Note that the original
87*e4b17023SJohn Marino    callgraph node and edge list will not be altered.)
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino    See the CALL_EXPR handling case in copy_tree_body_r ().  */
90*e4b17023SJohn Marino 
91*e4b17023SJohn Marino /* To Do:
92*e4b17023SJohn Marino 
93*e4b17023SJohn Marino    o In order to make inlining-on-trees work, we pessimized
94*e4b17023SJohn Marino      function-local static constants.  In particular, they are now
95*e4b17023SJohn Marino      always output, even when not addressed.  Fix this by treating
96*e4b17023SJohn Marino      function-local static constants just like global static
97*e4b17023SJohn Marino      constants; the back-end already knows not to output them if they
98*e4b17023SJohn Marino      are not needed.
99*e4b17023SJohn Marino 
100*e4b17023SJohn Marino    o Provide heuristics to clamp inlining of recursive template
101*e4b17023SJohn Marino      calls?  */
102*e4b17023SJohn Marino 
103*e4b17023SJohn Marino 
104*e4b17023SJohn Marino /* Weights that estimate_num_insns uses to estimate the size of the
105*e4b17023SJohn Marino    produced code.  */
106*e4b17023SJohn Marino 
107*e4b17023SJohn Marino eni_weights eni_size_weights;
108*e4b17023SJohn Marino 
109*e4b17023SJohn Marino /* Weights that estimate_num_insns uses to estimate the time necessary
110*e4b17023SJohn Marino    to execute the produced code.  */
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino eni_weights eni_time_weights;
113*e4b17023SJohn Marino 
114*e4b17023SJohn Marino /* Prototypes.  */
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
117*e4b17023SJohn Marino static void remap_block (tree *, copy_body_data *);
118*e4b17023SJohn Marino static void copy_bind_expr (tree *, int *, copy_body_data *);
119*e4b17023SJohn Marino static tree mark_local_for_remap_r (tree *, int *, void *);
120*e4b17023SJohn Marino static void unsave_expr_1 (tree);
121*e4b17023SJohn Marino static tree unsave_r (tree *, int *, void *);
122*e4b17023SJohn Marino static void declare_inline_vars (tree, tree);
123*e4b17023SJohn Marino static void remap_save_expr (tree *, void *, int *);
124*e4b17023SJohn Marino static void prepend_lexical_block (tree current_block, tree new_block);
125*e4b17023SJohn Marino static tree copy_decl_to_var (tree, copy_body_data *);
126*e4b17023SJohn Marino static tree copy_result_decl_to_var (tree, copy_body_data *);
127*e4b17023SJohn Marino static tree copy_decl_maybe_to_var (tree, copy_body_data *);
128*e4b17023SJohn Marino static gimple remap_gimple_stmt (gimple, copy_body_data *);
129*e4b17023SJohn Marino static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id);
130*e4b17023SJohn Marino 
131*e4b17023SJohn Marino /* Insert a tree->tree mapping for ID.  Despite the name suggests
132*e4b17023SJohn Marino    that the trees should be variables, it is used for more than that.  */
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino void
135*e4b17023SJohn Marino insert_decl_map (copy_body_data *id, tree key, tree value)
136*e4b17023SJohn Marino {
137*e4b17023SJohn Marino   *pointer_map_insert (id->decl_map, key) = value;
138*e4b17023SJohn Marino 
139*e4b17023SJohn Marino   /* Always insert an identity map as well.  If we see this same new
140*e4b17023SJohn Marino      node again, we won't want to duplicate it a second time.  */
141*e4b17023SJohn Marino   if (key != value)
142*e4b17023SJohn Marino     *pointer_map_insert (id->decl_map, value) = value;
143*e4b17023SJohn Marino }
144*e4b17023SJohn Marino 
145*e4b17023SJohn Marino /* Insert a tree->tree mapping for ID.  This is only used for
146*e4b17023SJohn Marino    variables.  */
147*e4b17023SJohn Marino 
148*e4b17023SJohn Marino static void
149*e4b17023SJohn Marino insert_debug_decl_map (copy_body_data *id, tree key, tree value)
150*e4b17023SJohn Marino {
151*e4b17023SJohn Marino   if (!gimple_in_ssa_p (id->src_cfun))
152*e4b17023SJohn Marino     return;
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
155*e4b17023SJohn Marino     return;
156*e4b17023SJohn Marino 
157*e4b17023SJohn Marino   if (!target_for_debug_bind (key))
158*e4b17023SJohn Marino     return;
159*e4b17023SJohn Marino 
160*e4b17023SJohn Marino   gcc_assert (TREE_CODE (key) == PARM_DECL);
161*e4b17023SJohn Marino   gcc_assert (TREE_CODE (value) == VAR_DECL);
162*e4b17023SJohn Marino 
163*e4b17023SJohn Marino   if (!id->debug_map)
164*e4b17023SJohn Marino     id->debug_map = pointer_map_create ();
165*e4b17023SJohn Marino 
166*e4b17023SJohn Marino   *pointer_map_insert (id->debug_map, key) = value;
167*e4b17023SJohn Marino }
168*e4b17023SJohn Marino 
169*e4b17023SJohn Marino /* If nonzero, we're remapping the contents of inlined debug
170*e4b17023SJohn Marino    statements.  If negative, an error has occurred, such as a
171*e4b17023SJohn Marino    reference to a variable that isn't available in the inlined
172*e4b17023SJohn Marino    context.  */
173*e4b17023SJohn Marino static int processing_debug_stmt = 0;
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino /* Construct new SSA name for old NAME. ID is the inline context.  */
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino static tree
178*e4b17023SJohn Marino remap_ssa_name (tree name, copy_body_data *id)
179*e4b17023SJohn Marino {
180*e4b17023SJohn Marino   tree new_tree;
181*e4b17023SJohn Marino   tree *n;
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   gcc_assert (TREE_CODE (name) == SSA_NAME);
184*e4b17023SJohn Marino 
185*e4b17023SJohn Marino   n = (tree *) pointer_map_contains (id->decl_map, name);
186*e4b17023SJohn Marino   if (n)
187*e4b17023SJohn Marino     return unshare_expr (*n);
188*e4b17023SJohn Marino 
189*e4b17023SJohn Marino   if (processing_debug_stmt)
190*e4b17023SJohn Marino     {
191*e4b17023SJohn Marino       if (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL
192*e4b17023SJohn Marino 	  && SSA_NAME_IS_DEFAULT_DEF (name)
193*e4b17023SJohn Marino 	  && id->entry_bb == NULL
194*e4b17023SJohn Marino 	  && single_succ_p (ENTRY_BLOCK_PTR))
195*e4b17023SJohn Marino 	{
196*e4b17023SJohn Marino 	  tree vexpr = make_node (DEBUG_EXPR_DECL);
197*e4b17023SJohn Marino 	  gimple def_temp;
198*e4b17023SJohn Marino 	  gimple_stmt_iterator gsi;
199*e4b17023SJohn Marino 	  tree val = SSA_NAME_VAR (name);
200*e4b17023SJohn Marino 
201*e4b17023SJohn Marino 	  n = (tree *) pointer_map_contains (id->decl_map, val);
202*e4b17023SJohn Marino 	  if (n != NULL)
203*e4b17023SJohn Marino 	    val = *n;
204*e4b17023SJohn Marino 	  if (TREE_CODE (val) != PARM_DECL)
205*e4b17023SJohn Marino 	    {
206*e4b17023SJohn Marino 	      processing_debug_stmt = -1;
207*e4b17023SJohn Marino 	      return name;
208*e4b17023SJohn Marino 	    }
209*e4b17023SJohn Marino 	  def_temp = gimple_build_debug_source_bind (vexpr, val, NULL);
210*e4b17023SJohn Marino 	  DECL_ARTIFICIAL (vexpr) = 1;
211*e4b17023SJohn Marino 	  TREE_TYPE (vexpr) = TREE_TYPE (name);
212*e4b17023SJohn Marino 	  DECL_MODE (vexpr) = DECL_MODE (SSA_NAME_VAR (name));
213*e4b17023SJohn Marino 	  gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
214*e4b17023SJohn Marino 	  gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
215*e4b17023SJohn Marino 	  return vexpr;
216*e4b17023SJohn Marino 	}
217*e4b17023SJohn Marino 
218*e4b17023SJohn Marino       processing_debug_stmt = -1;
219*e4b17023SJohn Marino       return name;
220*e4b17023SJohn Marino     }
221*e4b17023SJohn Marino 
222*e4b17023SJohn Marino   /* Do not set DEF_STMT yet as statement is not copied yet. We do that
223*e4b17023SJohn Marino      in copy_bb.  */
224*e4b17023SJohn Marino   new_tree = remap_decl (SSA_NAME_VAR (name), id);
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   /* We might've substituted constant or another SSA_NAME for
227*e4b17023SJohn Marino      the variable.
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino      Replace the SSA name representing RESULT_DECL by variable during
230*e4b17023SJohn Marino      inlining:  this saves us from need to introduce PHI node in a case
231*e4b17023SJohn Marino      return value is just partly initialized.  */
232*e4b17023SJohn Marino   if ((TREE_CODE (new_tree) == VAR_DECL || TREE_CODE (new_tree) == PARM_DECL)
233*e4b17023SJohn Marino       && (TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL
234*e4b17023SJohn Marino 	  || !id->transform_return_to_modify))
235*e4b17023SJohn Marino     {
236*e4b17023SJohn Marino       struct ptr_info_def *pi;
237*e4b17023SJohn Marino       new_tree = make_ssa_name (new_tree, NULL);
238*e4b17023SJohn Marino       insert_decl_map (id, name, new_tree);
239*e4b17023SJohn Marino       SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_tree)
240*e4b17023SJohn Marino 	= SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name);
241*e4b17023SJohn Marino       TREE_TYPE (new_tree) = TREE_TYPE (SSA_NAME_VAR (new_tree));
242*e4b17023SJohn Marino       /* At least IPA points-to info can be directly transferred.  */
243*e4b17023SJohn Marino       if (id->src_cfun->gimple_df
244*e4b17023SJohn Marino 	  && id->src_cfun->gimple_df->ipa_pta
245*e4b17023SJohn Marino 	  && (pi = SSA_NAME_PTR_INFO (name))
246*e4b17023SJohn Marino 	  && !pi->pt.anything)
247*e4b17023SJohn Marino 	{
248*e4b17023SJohn Marino 	  struct ptr_info_def *new_pi = get_ptr_info (new_tree);
249*e4b17023SJohn Marino 	  new_pi->pt = pi->pt;
250*e4b17023SJohn Marino 	}
251*e4b17023SJohn Marino       if (gimple_nop_p (SSA_NAME_DEF_STMT (name)))
252*e4b17023SJohn Marino 	{
253*e4b17023SJohn Marino 	  /* By inlining function having uninitialized variable, we might
254*e4b17023SJohn Marino 	     extend the lifetime (variable might get reused).  This cause
255*e4b17023SJohn Marino 	     ICE in the case we end up extending lifetime of SSA name across
256*e4b17023SJohn Marino 	     abnormal edge, but also increase register pressure.
257*e4b17023SJohn Marino 
258*e4b17023SJohn Marino 	     We simply initialize all uninitialized vars by 0 except
259*e4b17023SJohn Marino 	     for case we are inlining to very first BB.  We can avoid
260*e4b17023SJohn Marino 	     this for all BBs that are not inside strongly connected
261*e4b17023SJohn Marino 	     regions of the CFG, but this is expensive to test.  */
262*e4b17023SJohn Marino 	  if (id->entry_bb
263*e4b17023SJohn Marino 	      && is_gimple_reg (SSA_NAME_VAR (name))
264*e4b17023SJohn Marino 	      && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name)
265*e4b17023SJohn Marino 	      && TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL
266*e4b17023SJohn Marino 	      && (id->entry_bb != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest
267*e4b17023SJohn Marino 		  || EDGE_COUNT (id->entry_bb->preds) != 1))
268*e4b17023SJohn Marino 	    {
269*e4b17023SJohn Marino 	      gimple_stmt_iterator gsi = gsi_last_bb (id->entry_bb);
270*e4b17023SJohn Marino 	      gimple init_stmt;
271*e4b17023SJohn Marino 	      tree zero = build_zero_cst (TREE_TYPE (new_tree));
272*e4b17023SJohn Marino 
273*e4b17023SJohn Marino 	      init_stmt = gimple_build_assign (new_tree, zero);
274*e4b17023SJohn Marino 	      gsi_insert_after (&gsi, init_stmt, GSI_NEW_STMT);
275*e4b17023SJohn Marino 	      SSA_NAME_IS_DEFAULT_DEF (new_tree) = 0;
276*e4b17023SJohn Marino 	    }
277*e4b17023SJohn Marino 	  else
278*e4b17023SJohn Marino 	    {
279*e4b17023SJohn Marino 	      SSA_NAME_DEF_STMT (new_tree) = gimple_build_nop ();
280*e4b17023SJohn Marino 	      if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name))
281*e4b17023SJohn Marino 		  == name)
282*e4b17023SJohn Marino 	        set_default_def (SSA_NAME_VAR (new_tree), new_tree);
283*e4b17023SJohn Marino 	    }
284*e4b17023SJohn Marino 	}
285*e4b17023SJohn Marino     }
286*e4b17023SJohn Marino   else
287*e4b17023SJohn Marino     insert_decl_map (id, name, new_tree);
288*e4b17023SJohn Marino   return new_tree;
289*e4b17023SJohn Marino }
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino /* Remap DECL during the copying of the BLOCK tree for the function.  */
292*e4b17023SJohn Marino 
293*e4b17023SJohn Marino tree
294*e4b17023SJohn Marino remap_decl (tree decl, copy_body_data *id)
295*e4b17023SJohn Marino {
296*e4b17023SJohn Marino   tree *n;
297*e4b17023SJohn Marino 
298*e4b17023SJohn Marino   /* We only remap local variables in the current function.  */
299*e4b17023SJohn Marino 
300*e4b17023SJohn Marino   /* See if we have remapped this declaration.  */
301*e4b17023SJohn Marino 
302*e4b17023SJohn Marino   n = (tree *) pointer_map_contains (id->decl_map, decl);
303*e4b17023SJohn Marino 
304*e4b17023SJohn Marino   if (!n && processing_debug_stmt)
305*e4b17023SJohn Marino     {
306*e4b17023SJohn Marino       processing_debug_stmt = -1;
307*e4b17023SJohn Marino       return decl;
308*e4b17023SJohn Marino     }
309*e4b17023SJohn Marino 
310*e4b17023SJohn Marino   /* If we didn't already have an equivalent for this declaration,
311*e4b17023SJohn Marino      create one now.  */
312*e4b17023SJohn Marino   if (!n)
313*e4b17023SJohn Marino     {
314*e4b17023SJohn Marino       /* Make a copy of the variable or label.  */
315*e4b17023SJohn Marino       tree t = id->copy_decl (decl, id);
316*e4b17023SJohn Marino 
317*e4b17023SJohn Marino       /* Remember it, so that if we encounter this local entity again
318*e4b17023SJohn Marino 	 we can reuse this copy.  Do this early because remap_type may
319*e4b17023SJohn Marino 	 need this decl for TYPE_STUB_DECL.  */
320*e4b17023SJohn Marino       insert_decl_map (id, decl, t);
321*e4b17023SJohn Marino 
322*e4b17023SJohn Marino       if (!DECL_P (t))
323*e4b17023SJohn Marino 	return t;
324*e4b17023SJohn Marino 
325*e4b17023SJohn Marino       /* Remap types, if necessary.  */
326*e4b17023SJohn Marino       TREE_TYPE (t) = remap_type (TREE_TYPE (t), id);
327*e4b17023SJohn Marino       if (TREE_CODE (t) == TYPE_DECL)
328*e4b17023SJohn Marino         DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id);
329*e4b17023SJohn Marino 
330*e4b17023SJohn Marino       /* Remap sizes as necessary.  */
331*e4b17023SJohn Marino       walk_tree (&DECL_SIZE (t), copy_tree_body_r, id, NULL);
332*e4b17023SJohn Marino       walk_tree (&DECL_SIZE_UNIT (t), copy_tree_body_r, id, NULL);
333*e4b17023SJohn Marino 
334*e4b17023SJohn Marino       /* If fields, do likewise for offset and qualifier.  */
335*e4b17023SJohn Marino       if (TREE_CODE (t) == FIELD_DECL)
336*e4b17023SJohn Marino 	{
337*e4b17023SJohn Marino 	  walk_tree (&DECL_FIELD_OFFSET (t), copy_tree_body_r, id, NULL);
338*e4b17023SJohn Marino 	  if (TREE_CODE (DECL_CONTEXT (t)) == QUAL_UNION_TYPE)
339*e4b17023SJohn Marino 	    walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
340*e4b17023SJohn Marino 	}
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino       if ((TREE_CODE (t) == VAR_DECL
343*e4b17023SJohn Marino 	   || TREE_CODE (t) == RESULT_DECL
344*e4b17023SJohn Marino 	   || TREE_CODE (t) == PARM_DECL)
345*e4b17023SJohn Marino 	  && id->src_fn && DECL_STRUCT_FUNCTION (id->src_fn)
346*e4b17023SJohn Marino 	  && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
347*e4b17023SJohn Marino 	  /* We don't want to mark as referenced VAR_DECLs that were
348*e4b17023SJohn Marino 	     not marked as such in the src function.  */
349*e4b17023SJohn Marino 	  && (TREE_CODE (decl) != VAR_DECL
350*e4b17023SJohn Marino 	      || referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
351*e4b17023SJohn Marino 					DECL_UID (decl))))
352*e4b17023SJohn Marino 	add_referenced_var (t);
353*e4b17023SJohn Marino       return t;
354*e4b17023SJohn Marino     }
355*e4b17023SJohn Marino 
356*e4b17023SJohn Marino   if (id->do_not_unshare)
357*e4b17023SJohn Marino     return *n;
358*e4b17023SJohn Marino   else
359*e4b17023SJohn Marino     return unshare_expr (*n);
360*e4b17023SJohn Marino }
361*e4b17023SJohn Marino 
362*e4b17023SJohn Marino static tree
363*e4b17023SJohn Marino remap_type_1 (tree type, copy_body_data *id)
364*e4b17023SJohn Marino {
365*e4b17023SJohn Marino   tree new_tree, t;
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino   /* We do need a copy.  build and register it now.  If this is a pointer or
368*e4b17023SJohn Marino      reference type, remap the designated type and make a new pointer or
369*e4b17023SJohn Marino      reference type.  */
370*e4b17023SJohn Marino   if (TREE_CODE (type) == POINTER_TYPE)
371*e4b17023SJohn Marino     {
372*e4b17023SJohn Marino       new_tree = build_pointer_type_for_mode (remap_type (TREE_TYPE (type), id),
373*e4b17023SJohn Marino 					 TYPE_MODE (type),
374*e4b17023SJohn Marino 					 TYPE_REF_CAN_ALIAS_ALL (type));
375*e4b17023SJohn Marino       if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type))
376*e4b17023SJohn Marino 	new_tree = build_type_attribute_qual_variant (new_tree,
377*e4b17023SJohn Marino 						      TYPE_ATTRIBUTES (type),
378*e4b17023SJohn Marino 						      TYPE_QUALS (type));
379*e4b17023SJohn Marino       insert_decl_map (id, type, new_tree);
380*e4b17023SJohn Marino       return new_tree;
381*e4b17023SJohn Marino     }
382*e4b17023SJohn Marino   else if (TREE_CODE (type) == REFERENCE_TYPE)
383*e4b17023SJohn Marino     {
384*e4b17023SJohn Marino       new_tree = build_reference_type_for_mode (remap_type (TREE_TYPE (type), id),
385*e4b17023SJohn Marino 					    TYPE_MODE (type),
386*e4b17023SJohn Marino 					    TYPE_REF_CAN_ALIAS_ALL (type));
387*e4b17023SJohn Marino       if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type))
388*e4b17023SJohn Marino 	new_tree = build_type_attribute_qual_variant (new_tree,
389*e4b17023SJohn Marino 						      TYPE_ATTRIBUTES (type),
390*e4b17023SJohn Marino 						      TYPE_QUALS (type));
391*e4b17023SJohn Marino       insert_decl_map (id, type, new_tree);
392*e4b17023SJohn Marino       return new_tree;
393*e4b17023SJohn Marino     }
394*e4b17023SJohn Marino   else
395*e4b17023SJohn Marino     new_tree = copy_node (type);
396*e4b17023SJohn Marino 
397*e4b17023SJohn Marino   insert_decl_map (id, type, new_tree);
398*e4b17023SJohn Marino 
399*e4b17023SJohn Marino   /* This is a new type, not a copy of an old type.  Need to reassociate
400*e4b17023SJohn Marino      variants.  We can handle everything except the main variant lazily.  */
401*e4b17023SJohn Marino   t = TYPE_MAIN_VARIANT (type);
402*e4b17023SJohn Marino   if (type != t)
403*e4b17023SJohn Marino     {
404*e4b17023SJohn Marino       t = remap_type (t, id);
405*e4b17023SJohn Marino       TYPE_MAIN_VARIANT (new_tree) = t;
406*e4b17023SJohn Marino       TYPE_NEXT_VARIANT (new_tree) = TYPE_NEXT_VARIANT (t);
407*e4b17023SJohn Marino       TYPE_NEXT_VARIANT (t) = new_tree;
408*e4b17023SJohn Marino     }
409*e4b17023SJohn Marino   else
410*e4b17023SJohn Marino     {
411*e4b17023SJohn Marino       TYPE_MAIN_VARIANT (new_tree) = new_tree;
412*e4b17023SJohn Marino       TYPE_NEXT_VARIANT (new_tree) = NULL;
413*e4b17023SJohn Marino     }
414*e4b17023SJohn Marino 
415*e4b17023SJohn Marino   if (TYPE_STUB_DECL (type))
416*e4b17023SJohn Marino     TYPE_STUB_DECL (new_tree) = remap_decl (TYPE_STUB_DECL (type), id);
417*e4b17023SJohn Marino 
418*e4b17023SJohn Marino   /* Lazily create pointer and reference types.  */
419*e4b17023SJohn Marino   TYPE_POINTER_TO (new_tree) = NULL;
420*e4b17023SJohn Marino   TYPE_REFERENCE_TO (new_tree) = NULL;
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino   switch (TREE_CODE (new_tree))
423*e4b17023SJohn Marino     {
424*e4b17023SJohn Marino     case INTEGER_TYPE:
425*e4b17023SJohn Marino     case REAL_TYPE:
426*e4b17023SJohn Marino     case FIXED_POINT_TYPE:
427*e4b17023SJohn Marino     case ENUMERAL_TYPE:
428*e4b17023SJohn Marino     case BOOLEAN_TYPE:
429*e4b17023SJohn Marino       t = TYPE_MIN_VALUE (new_tree);
430*e4b17023SJohn Marino       if (t && TREE_CODE (t) != INTEGER_CST)
431*e4b17023SJohn Marino         walk_tree (&TYPE_MIN_VALUE (new_tree), copy_tree_body_r, id, NULL);
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino       t = TYPE_MAX_VALUE (new_tree);
434*e4b17023SJohn Marino       if (t && TREE_CODE (t) != INTEGER_CST)
435*e4b17023SJohn Marino         walk_tree (&TYPE_MAX_VALUE (new_tree), copy_tree_body_r, id, NULL);
436*e4b17023SJohn Marino       return new_tree;
437*e4b17023SJohn Marino 
438*e4b17023SJohn Marino     case FUNCTION_TYPE:
439*e4b17023SJohn Marino       TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id);
440*e4b17023SJohn Marino       walk_tree (&TYPE_ARG_TYPES (new_tree), copy_tree_body_r, id, NULL);
441*e4b17023SJohn Marino       return new_tree;
442*e4b17023SJohn Marino 
443*e4b17023SJohn Marino     case ARRAY_TYPE:
444*e4b17023SJohn Marino       TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id);
445*e4b17023SJohn Marino       TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id);
446*e4b17023SJohn Marino       break;
447*e4b17023SJohn Marino 
448*e4b17023SJohn Marino     case RECORD_TYPE:
449*e4b17023SJohn Marino     case UNION_TYPE:
450*e4b17023SJohn Marino     case QUAL_UNION_TYPE:
451*e4b17023SJohn Marino       {
452*e4b17023SJohn Marino 	tree f, nf = NULL;
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino 	for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f))
455*e4b17023SJohn Marino 	  {
456*e4b17023SJohn Marino 	    t = remap_decl (f, id);
457*e4b17023SJohn Marino 	    DECL_CONTEXT (t) = new_tree;
458*e4b17023SJohn Marino 	    DECL_CHAIN (t) = nf;
459*e4b17023SJohn Marino 	    nf = t;
460*e4b17023SJohn Marino 	  }
461*e4b17023SJohn Marino 	TYPE_FIELDS (new_tree) = nreverse (nf);
462*e4b17023SJohn Marino       }
463*e4b17023SJohn Marino       break;
464*e4b17023SJohn Marino 
465*e4b17023SJohn Marino     case OFFSET_TYPE:
466*e4b17023SJohn Marino     default:
467*e4b17023SJohn Marino       /* Shouldn't have been thought variable sized.  */
468*e4b17023SJohn Marino       gcc_unreachable ();
469*e4b17023SJohn Marino     }
470*e4b17023SJohn Marino 
471*e4b17023SJohn Marino   walk_tree (&TYPE_SIZE (new_tree), copy_tree_body_r, id, NULL);
472*e4b17023SJohn Marino   walk_tree (&TYPE_SIZE_UNIT (new_tree), copy_tree_body_r, id, NULL);
473*e4b17023SJohn Marino 
474*e4b17023SJohn Marino   return new_tree;
475*e4b17023SJohn Marino }
476*e4b17023SJohn Marino 
477*e4b17023SJohn Marino tree
478*e4b17023SJohn Marino remap_type (tree type, copy_body_data *id)
479*e4b17023SJohn Marino {
480*e4b17023SJohn Marino   tree *node;
481*e4b17023SJohn Marino   tree tmp;
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino   if (type == NULL)
484*e4b17023SJohn Marino     return type;
485*e4b17023SJohn Marino 
486*e4b17023SJohn Marino   /* See if we have remapped this type.  */
487*e4b17023SJohn Marino   node = (tree *) pointer_map_contains (id->decl_map, type);
488*e4b17023SJohn Marino   if (node)
489*e4b17023SJohn Marino     return *node;
490*e4b17023SJohn Marino 
491*e4b17023SJohn Marino   /* The type only needs remapping if it's variably modified.  */
492*e4b17023SJohn Marino   if (! variably_modified_type_p (type, id->src_fn))
493*e4b17023SJohn Marino     {
494*e4b17023SJohn Marino       insert_decl_map (id, type, type);
495*e4b17023SJohn Marino       return type;
496*e4b17023SJohn Marino     }
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino   id->remapping_type_depth++;
499*e4b17023SJohn Marino   tmp = remap_type_1 (type, id);
500*e4b17023SJohn Marino   id->remapping_type_depth--;
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino   return tmp;
503*e4b17023SJohn Marino }
504*e4b17023SJohn Marino 
505*e4b17023SJohn Marino /* Return previously remapped type of TYPE in ID.  Return NULL if TYPE
506*e4b17023SJohn Marino    is NULL or TYPE has not been remapped before.  */
507*e4b17023SJohn Marino 
508*e4b17023SJohn Marino static tree
509*e4b17023SJohn Marino remapped_type (tree type, copy_body_data *id)
510*e4b17023SJohn Marino {
511*e4b17023SJohn Marino   tree *node;
512*e4b17023SJohn Marino 
513*e4b17023SJohn Marino   if (type == NULL)
514*e4b17023SJohn Marino     return type;
515*e4b17023SJohn Marino 
516*e4b17023SJohn Marino   /* See if we have remapped this type.  */
517*e4b17023SJohn Marino   node = (tree *) pointer_map_contains (id->decl_map, type);
518*e4b17023SJohn Marino   if (node)
519*e4b17023SJohn Marino     return *node;
520*e4b17023SJohn Marino   else
521*e4b17023SJohn Marino     return NULL;
522*e4b17023SJohn Marino }
523*e4b17023SJohn Marino 
524*e4b17023SJohn Marino   /* The type only needs remapping if it's variably modified.  */
525*e4b17023SJohn Marino /* Decide if DECL can be put into BLOCK_NONLOCAL_VARs.  */
526*e4b17023SJohn Marino 
527*e4b17023SJohn Marino static bool
528*e4b17023SJohn Marino can_be_nonlocal (tree decl, copy_body_data *id)
529*e4b17023SJohn Marino {
530*e4b17023SJohn Marino   /* We can not duplicate function decls.  */
531*e4b17023SJohn Marino   if (TREE_CODE (decl) == FUNCTION_DECL)
532*e4b17023SJohn Marino     return true;
533*e4b17023SJohn Marino 
534*e4b17023SJohn Marino   /* Local static vars must be non-local or we get multiple declaration
535*e4b17023SJohn Marino      problems.  */
536*e4b17023SJohn Marino   if (TREE_CODE (decl) == VAR_DECL
537*e4b17023SJohn Marino       && !auto_var_in_fn_p (decl, id->src_fn))
538*e4b17023SJohn Marino     return true;
539*e4b17023SJohn Marino 
540*e4b17023SJohn Marino   /* At the moment dwarf2out can handle only these types of nodes.  We
541*e4b17023SJohn Marino      can support more later.  */
542*e4b17023SJohn Marino   if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL)
543*e4b17023SJohn Marino     return false;
544*e4b17023SJohn Marino 
545*e4b17023SJohn Marino   /* We must use global type.  We call remapped_type instead of
546*e4b17023SJohn Marino      remap_type since we don't want to remap this type here if it
547*e4b17023SJohn Marino      hasn't been remapped before.  */
548*e4b17023SJohn Marino   if (TREE_TYPE (decl) != remapped_type (TREE_TYPE (decl), id))
549*e4b17023SJohn Marino     return false;
550*e4b17023SJohn Marino 
551*e4b17023SJohn Marino   /* Wihtout SSA we can't tell if variable is used.  */
552*e4b17023SJohn Marino   if (!gimple_in_ssa_p (cfun))
553*e4b17023SJohn Marino     return false;
554*e4b17023SJohn Marino 
555*e4b17023SJohn Marino   /* Live variables must be copied so we can attach DECL_RTL.  */
556*e4b17023SJohn Marino   if (var_ann (decl))
557*e4b17023SJohn Marino     return false;
558*e4b17023SJohn Marino 
559*e4b17023SJohn Marino   return true;
560*e4b17023SJohn Marino }
561*e4b17023SJohn Marino 
562*e4b17023SJohn Marino static tree
563*e4b17023SJohn Marino remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
564*e4b17023SJohn Marino {
565*e4b17023SJohn Marino   tree old_var;
566*e4b17023SJohn Marino   tree new_decls = NULL_TREE;
567*e4b17023SJohn Marino 
568*e4b17023SJohn Marino   /* Remap its variables.  */
569*e4b17023SJohn Marino   for (old_var = decls; old_var; old_var = DECL_CHAIN (old_var))
570*e4b17023SJohn Marino     {
571*e4b17023SJohn Marino       tree new_var;
572*e4b17023SJohn Marino 
573*e4b17023SJohn Marino       if (can_be_nonlocal (old_var, id))
574*e4b17023SJohn Marino 	{
575*e4b17023SJohn Marino 	  if (TREE_CODE (old_var) == VAR_DECL
576*e4b17023SJohn Marino 	      && ! DECL_EXTERNAL (old_var)
577*e4b17023SJohn Marino 	      && (var_ann (old_var) || !gimple_in_ssa_p (cfun)))
578*e4b17023SJohn Marino 	    add_local_decl (cfun, old_var);
579*e4b17023SJohn Marino 	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
580*e4b17023SJohn Marino 	      && !DECL_IGNORED_P (old_var)
581*e4b17023SJohn Marino 	      && nonlocalized_list)
582*e4b17023SJohn Marino 	    VEC_safe_push (tree, gc, *nonlocalized_list, old_var);
583*e4b17023SJohn Marino 	  continue;
584*e4b17023SJohn Marino 	}
585*e4b17023SJohn Marino 
586*e4b17023SJohn Marino       /* Remap the variable.  */
587*e4b17023SJohn Marino       new_var = remap_decl (old_var, id);
588*e4b17023SJohn Marino 
589*e4b17023SJohn Marino       /* If we didn't remap this variable, we can't mess with its
590*e4b17023SJohn Marino 	 TREE_CHAIN.  If we remapped this variable to the return slot, it's
591*e4b17023SJohn Marino 	 already declared somewhere else, so don't declare it here.  */
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino       if (new_var == id->retvar)
594*e4b17023SJohn Marino 	;
595*e4b17023SJohn Marino       else if (!new_var)
596*e4b17023SJohn Marino         {
597*e4b17023SJohn Marino 	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
598*e4b17023SJohn Marino 	      && !DECL_IGNORED_P (old_var)
599*e4b17023SJohn Marino 	      && nonlocalized_list)
600*e4b17023SJohn Marino 	    VEC_safe_push (tree, gc, *nonlocalized_list, old_var);
601*e4b17023SJohn Marino 	}
602*e4b17023SJohn Marino       else
603*e4b17023SJohn Marino 	{
604*e4b17023SJohn Marino 	  gcc_assert (DECL_P (new_var));
605*e4b17023SJohn Marino 	  DECL_CHAIN (new_var) = new_decls;
606*e4b17023SJohn Marino 	  new_decls = new_var;
607*e4b17023SJohn Marino 
608*e4b17023SJohn Marino 	  /* Also copy value-expressions.  */
609*e4b17023SJohn Marino 	  if (TREE_CODE (new_var) == VAR_DECL
610*e4b17023SJohn Marino 	      && DECL_HAS_VALUE_EXPR_P (new_var))
611*e4b17023SJohn Marino 	    {
612*e4b17023SJohn Marino 	      tree tem = DECL_VALUE_EXPR (new_var);
613*e4b17023SJohn Marino 	      bool old_regimplify = id->regimplify;
614*e4b17023SJohn Marino 	      id->remapping_type_depth++;
615*e4b17023SJohn Marino 	      walk_tree (&tem, copy_tree_body_r, id, NULL);
616*e4b17023SJohn Marino 	      id->remapping_type_depth--;
617*e4b17023SJohn Marino 	      id->regimplify = old_regimplify;
618*e4b17023SJohn Marino 	      SET_DECL_VALUE_EXPR (new_var, tem);
619*e4b17023SJohn Marino 	    }
620*e4b17023SJohn Marino 	}
621*e4b17023SJohn Marino     }
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino   return nreverse (new_decls);
624*e4b17023SJohn Marino }
625*e4b17023SJohn Marino 
626*e4b17023SJohn Marino /* Copy the BLOCK to contain remapped versions of the variables
627*e4b17023SJohn Marino    therein.  And hook the new block into the block-tree.  */
628*e4b17023SJohn Marino 
629*e4b17023SJohn Marino static void
630*e4b17023SJohn Marino remap_block (tree *block, copy_body_data *id)
631*e4b17023SJohn Marino {
632*e4b17023SJohn Marino   tree old_block;
633*e4b17023SJohn Marino   tree new_block;
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino   /* Make the new block.  */
636*e4b17023SJohn Marino   old_block = *block;
637*e4b17023SJohn Marino   new_block = make_node (BLOCK);
638*e4b17023SJohn Marino   TREE_USED (new_block) = TREE_USED (old_block);
639*e4b17023SJohn Marino   BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
640*e4b17023SJohn Marino   BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
641*e4b17023SJohn Marino   BLOCK_NONLOCALIZED_VARS (new_block)
642*e4b17023SJohn Marino     = VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block));
643*e4b17023SJohn Marino   *block = new_block;
644*e4b17023SJohn Marino 
645*e4b17023SJohn Marino   /* Remap its variables.  */
646*e4b17023SJohn Marino   BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block),
647*e4b17023SJohn Marino   					&BLOCK_NONLOCALIZED_VARS (new_block),
648*e4b17023SJohn Marino 					id);
649*e4b17023SJohn Marino 
650*e4b17023SJohn Marino   if (id->transform_lang_insert_block)
651*e4b17023SJohn Marino     id->transform_lang_insert_block (new_block);
652*e4b17023SJohn Marino 
653*e4b17023SJohn Marino   /* Remember the remapped block.  */
654*e4b17023SJohn Marino   insert_decl_map (id, old_block, new_block);
655*e4b17023SJohn Marino }
656*e4b17023SJohn Marino 
657*e4b17023SJohn Marino /* Copy the whole block tree and root it in id->block.  */
658*e4b17023SJohn Marino static tree
659*e4b17023SJohn Marino remap_blocks (tree block, copy_body_data *id)
660*e4b17023SJohn Marino {
661*e4b17023SJohn Marino   tree t;
662*e4b17023SJohn Marino   tree new_tree = block;
663*e4b17023SJohn Marino 
664*e4b17023SJohn Marino   if (!block)
665*e4b17023SJohn Marino     return NULL;
666*e4b17023SJohn Marino 
667*e4b17023SJohn Marino   remap_block (&new_tree, id);
668*e4b17023SJohn Marino   gcc_assert (new_tree != block);
669*e4b17023SJohn Marino   for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
670*e4b17023SJohn Marino     prepend_lexical_block (new_tree, remap_blocks (t, id));
671*e4b17023SJohn Marino   /* Blocks are in arbitrary order, but make things slightly prettier and do
672*e4b17023SJohn Marino      not swap order when producing a copy.  */
673*e4b17023SJohn Marino   BLOCK_SUBBLOCKS (new_tree) = blocks_nreverse (BLOCK_SUBBLOCKS (new_tree));
674*e4b17023SJohn Marino   return new_tree;
675*e4b17023SJohn Marino }
676*e4b17023SJohn Marino 
677*e4b17023SJohn Marino static void
678*e4b17023SJohn Marino copy_statement_list (tree *tp)
679*e4b17023SJohn Marino {
680*e4b17023SJohn Marino   tree_stmt_iterator oi, ni;
681*e4b17023SJohn Marino   tree new_tree;
682*e4b17023SJohn Marino 
683*e4b17023SJohn Marino   new_tree = alloc_stmt_list ();
684*e4b17023SJohn Marino   ni = tsi_start (new_tree);
685*e4b17023SJohn Marino   oi = tsi_start (*tp);
686*e4b17023SJohn Marino   TREE_TYPE (new_tree) = TREE_TYPE (*tp);
687*e4b17023SJohn Marino   *tp = new_tree;
688*e4b17023SJohn Marino 
689*e4b17023SJohn Marino   for (; !tsi_end_p (oi); tsi_next (&oi))
690*e4b17023SJohn Marino     {
691*e4b17023SJohn Marino       tree stmt = tsi_stmt (oi);
692*e4b17023SJohn Marino       if (TREE_CODE (stmt) == STATEMENT_LIST)
693*e4b17023SJohn Marino 	/* This copy is not redundant; tsi_link_after will smash this
694*e4b17023SJohn Marino 	   STATEMENT_LIST into the end of the one we're building, and we
695*e4b17023SJohn Marino 	   don't want to do that with the original.  */
696*e4b17023SJohn Marino 	copy_statement_list (&stmt);
697*e4b17023SJohn Marino       tsi_link_after (&ni, stmt, TSI_CONTINUE_LINKING);
698*e4b17023SJohn Marino     }
699*e4b17023SJohn Marino }
700*e4b17023SJohn Marino 
701*e4b17023SJohn Marino static void
702*e4b17023SJohn Marino copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id)
703*e4b17023SJohn Marino {
704*e4b17023SJohn Marino   tree block = BIND_EXPR_BLOCK (*tp);
705*e4b17023SJohn Marino   /* Copy (and replace) the statement.  */
706*e4b17023SJohn Marino   copy_tree_r (tp, walk_subtrees, NULL);
707*e4b17023SJohn Marino   if (block)
708*e4b17023SJohn Marino     {
709*e4b17023SJohn Marino       remap_block (&block, id);
710*e4b17023SJohn Marino       BIND_EXPR_BLOCK (*tp) = block;
711*e4b17023SJohn Marino     }
712*e4b17023SJohn Marino 
713*e4b17023SJohn Marino   if (BIND_EXPR_VARS (*tp))
714*e4b17023SJohn Marino     /* This will remap a lot of the same decls again, but this should be
715*e4b17023SJohn Marino        harmless.  */
716*e4b17023SJohn Marino     BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id);
717*e4b17023SJohn Marino }
718*e4b17023SJohn Marino 
719*e4b17023SJohn Marino 
720*e4b17023SJohn Marino /* Create a new gimple_seq by remapping all the statements in BODY
721*e4b17023SJohn Marino    using the inlining information in ID.  */
722*e4b17023SJohn Marino 
723*e4b17023SJohn Marino static gimple_seq
724*e4b17023SJohn Marino remap_gimple_seq (gimple_seq body, copy_body_data *id)
725*e4b17023SJohn Marino {
726*e4b17023SJohn Marino   gimple_stmt_iterator si;
727*e4b17023SJohn Marino   gimple_seq new_body = NULL;
728*e4b17023SJohn Marino 
729*e4b17023SJohn Marino   for (si = gsi_start (body); !gsi_end_p (si); gsi_next (&si))
730*e4b17023SJohn Marino     {
731*e4b17023SJohn Marino       gimple new_stmt = remap_gimple_stmt (gsi_stmt (si), id);
732*e4b17023SJohn Marino       gimple_seq_add_stmt (&new_body, new_stmt);
733*e4b17023SJohn Marino     }
734*e4b17023SJohn Marino 
735*e4b17023SJohn Marino   return new_body;
736*e4b17023SJohn Marino }
737*e4b17023SJohn Marino 
738*e4b17023SJohn Marino 
739*e4b17023SJohn Marino /* Copy a GIMPLE_BIND statement STMT, remapping all the symbols in its
740*e4b17023SJohn Marino    block using the mapping information in ID.  */
741*e4b17023SJohn Marino 
742*e4b17023SJohn Marino static gimple
743*e4b17023SJohn Marino copy_gimple_bind (gimple stmt, copy_body_data *id)
744*e4b17023SJohn Marino {
745*e4b17023SJohn Marino   gimple new_bind;
746*e4b17023SJohn Marino   tree new_block, new_vars;
747*e4b17023SJohn Marino   gimple_seq body, new_body;
748*e4b17023SJohn Marino 
749*e4b17023SJohn Marino   /* Copy the statement.  Note that we purposely don't use copy_stmt
750*e4b17023SJohn Marino      here because we need to remap statements as we copy.  */
751*e4b17023SJohn Marino   body = gimple_bind_body (stmt);
752*e4b17023SJohn Marino   new_body = remap_gimple_seq (body, id);
753*e4b17023SJohn Marino 
754*e4b17023SJohn Marino   new_block = gimple_bind_block (stmt);
755*e4b17023SJohn Marino   if (new_block)
756*e4b17023SJohn Marino     remap_block (&new_block, id);
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino   /* This will remap a lot of the same decls again, but this should be
759*e4b17023SJohn Marino      harmless.  */
760*e4b17023SJohn Marino   new_vars = gimple_bind_vars (stmt);
761*e4b17023SJohn Marino   if (new_vars)
762*e4b17023SJohn Marino     new_vars = remap_decls (new_vars, NULL, id);
763*e4b17023SJohn Marino 
764*e4b17023SJohn Marino   new_bind = gimple_build_bind (new_vars, new_body, new_block);
765*e4b17023SJohn Marino 
766*e4b17023SJohn Marino   return new_bind;
767*e4b17023SJohn Marino }
768*e4b17023SJohn Marino 
769*e4b17023SJohn Marino 
770*e4b17023SJohn Marino /* Remap the GIMPLE operand pointed to by *TP.  DATA is really a
771*e4b17023SJohn Marino    'struct walk_stmt_info *'.  DATA->INFO is a 'copy_body_data *'.
772*e4b17023SJohn Marino    WALK_SUBTREES is used to indicate walk_gimple_op whether to keep
773*e4b17023SJohn Marino    recursing into the children nodes of *TP.  */
774*e4b17023SJohn Marino 
775*e4b17023SJohn Marino static tree
776*e4b17023SJohn Marino remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
777*e4b17023SJohn Marino {
778*e4b17023SJohn Marino   struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data;
779*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) wi_p->info;
780*e4b17023SJohn Marino   tree fn = id->src_fn;
781*e4b17023SJohn Marino 
782*e4b17023SJohn Marino   if (TREE_CODE (*tp) == SSA_NAME)
783*e4b17023SJohn Marino     {
784*e4b17023SJohn Marino       *tp = remap_ssa_name (*tp, id);
785*e4b17023SJohn Marino       *walk_subtrees = 0;
786*e4b17023SJohn Marino       return NULL;
787*e4b17023SJohn Marino     }
788*e4b17023SJohn Marino   else if (auto_var_in_fn_p (*tp, fn))
789*e4b17023SJohn Marino     {
790*e4b17023SJohn Marino       /* Local variables and labels need to be replaced by equivalent
791*e4b17023SJohn Marino 	 variables.  We don't want to copy static variables; there's
792*e4b17023SJohn Marino 	 only one of those, no matter how many times we inline the
793*e4b17023SJohn Marino 	 containing function.  Similarly for globals from an outer
794*e4b17023SJohn Marino 	 function.  */
795*e4b17023SJohn Marino       tree new_decl;
796*e4b17023SJohn Marino 
797*e4b17023SJohn Marino       /* Remap the declaration.  */
798*e4b17023SJohn Marino       new_decl = remap_decl (*tp, id);
799*e4b17023SJohn Marino       gcc_assert (new_decl);
800*e4b17023SJohn Marino       /* Replace this variable with the copy.  */
801*e4b17023SJohn Marino       STRIP_TYPE_NOPS (new_decl);
802*e4b17023SJohn Marino       /* ???  The C++ frontend uses void * pointer zero to initialize
803*e4b17023SJohn Marino          any other type.  This confuses the middle-end type verification.
804*e4b17023SJohn Marino 	 As cloned bodies do not go through gimplification again the fixup
805*e4b17023SJohn Marino 	 there doesn't trigger.  */
806*e4b17023SJohn Marino       if (TREE_CODE (new_decl) == INTEGER_CST
807*e4b17023SJohn Marino 	  && !useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (new_decl)))
808*e4b17023SJohn Marino 	new_decl = fold_convert (TREE_TYPE (*tp), new_decl);
809*e4b17023SJohn Marino       *tp = new_decl;
810*e4b17023SJohn Marino       *walk_subtrees = 0;
811*e4b17023SJohn Marino     }
812*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == STATEMENT_LIST)
813*e4b17023SJohn Marino     gcc_unreachable ();
814*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == SAVE_EXPR)
815*e4b17023SJohn Marino     gcc_unreachable ();
816*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == LABEL_DECL
817*e4b17023SJohn Marino 	   && (!DECL_CONTEXT (*tp)
818*e4b17023SJohn Marino 	       || decl_function_context (*tp) == id->src_fn))
819*e4b17023SJohn Marino     /* These may need to be remapped for EH handling.  */
820*e4b17023SJohn Marino     *tp = remap_decl (*tp, id);
821*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == FIELD_DECL)
822*e4b17023SJohn Marino     {
823*e4b17023SJohn Marino       /* If the enclosing record type is variably_modified_type_p, the field
824*e4b17023SJohn Marino 	 has already been remapped.  Otherwise, it need not be.  */
825*e4b17023SJohn Marino       tree *n = (tree *) pointer_map_contains (id->decl_map, *tp);
826*e4b17023SJohn Marino       if (n)
827*e4b17023SJohn Marino 	*tp = *n;
828*e4b17023SJohn Marino       *walk_subtrees = 0;
829*e4b17023SJohn Marino     }
830*e4b17023SJohn Marino   else if (TYPE_P (*tp))
831*e4b17023SJohn Marino     /* Types may need remapping as well.  */
832*e4b17023SJohn Marino     *tp = remap_type (*tp, id);
833*e4b17023SJohn Marino   else if (CONSTANT_CLASS_P (*tp))
834*e4b17023SJohn Marino     {
835*e4b17023SJohn Marino       /* If this is a constant, we have to copy the node iff the type
836*e4b17023SJohn Marino 	 will be remapped.  copy_tree_r will not copy a constant.  */
837*e4b17023SJohn Marino       tree new_type = remap_type (TREE_TYPE (*tp), id);
838*e4b17023SJohn Marino 
839*e4b17023SJohn Marino       if (new_type == TREE_TYPE (*tp))
840*e4b17023SJohn Marino 	*walk_subtrees = 0;
841*e4b17023SJohn Marino 
842*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == INTEGER_CST)
843*e4b17023SJohn Marino 	*tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp),
844*e4b17023SJohn Marino 				  TREE_INT_CST_HIGH (*tp));
845*e4b17023SJohn Marino       else
846*e4b17023SJohn Marino 	{
847*e4b17023SJohn Marino 	  *tp = copy_node (*tp);
848*e4b17023SJohn Marino 	  TREE_TYPE (*tp) = new_type;
849*e4b17023SJohn Marino 	}
850*e4b17023SJohn Marino     }
851*e4b17023SJohn Marino   else
852*e4b17023SJohn Marino     {
853*e4b17023SJohn Marino       /* Otherwise, just copy the node.  Note that copy_tree_r already
854*e4b17023SJohn Marino 	 knows not to copy VAR_DECLs, etc., so this is safe.  */
855*e4b17023SJohn Marino 
856*e4b17023SJohn Marino       /* We should never have TREE_BLOCK set on non-statements.  */
857*e4b17023SJohn Marino       if (EXPR_P (*tp))
858*e4b17023SJohn Marino 	gcc_assert (!TREE_BLOCK (*tp));
859*e4b17023SJohn Marino 
860*e4b17023SJohn Marino       if (TREE_CODE (*tp) == MEM_REF)
861*e4b17023SJohn Marino 	{
862*e4b17023SJohn Marino 	  tree ptr = TREE_OPERAND (*tp, 0);
863*e4b17023SJohn Marino 	  tree type = remap_type (TREE_TYPE (*tp), id);
864*e4b17023SJohn Marino 	  tree old = *tp;
865*e4b17023SJohn Marino 
866*e4b17023SJohn Marino 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
867*e4b17023SJohn Marino 	     that can happen when a pointer argument is an ADDR_EXPR.
868*e4b17023SJohn Marino 	     Recurse here manually to allow that.  */
869*e4b17023SJohn Marino 	  walk_tree (&ptr, remap_gimple_op_r, data, NULL);
870*e4b17023SJohn Marino 	  *tp = fold_build2 (MEM_REF, type,
871*e4b17023SJohn Marino 			     ptr, TREE_OPERAND (*tp, 1));
872*e4b17023SJohn Marino 	  TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
873*e4b17023SJohn Marino 	  TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
874*e4b17023SJohn Marino 	  TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
875*e4b17023SJohn Marino 	  TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
876*e4b17023SJohn Marino 	  *walk_subtrees = 0;
877*e4b17023SJohn Marino 	  return NULL;
878*e4b17023SJohn Marino 	}
879*e4b17023SJohn Marino 
880*e4b17023SJohn Marino       /* Here is the "usual case".  Copy this tree node, and then
881*e4b17023SJohn Marino 	 tweak some special cases.  */
882*e4b17023SJohn Marino       copy_tree_r (tp, walk_subtrees, NULL);
883*e4b17023SJohn Marino 
884*e4b17023SJohn Marino       if (TREE_CODE (*tp) != OMP_CLAUSE)
885*e4b17023SJohn Marino 	TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
886*e4b17023SJohn Marino 
887*e4b17023SJohn Marino       /* Global variables we haven't seen yet need to go into referenced
888*e4b17023SJohn Marino 	 vars.  If not referenced from types only.  */
889*e4b17023SJohn Marino       if (gimple_in_ssa_p (cfun)
890*e4b17023SJohn Marino 	  && TREE_CODE (*tp) == VAR_DECL
891*e4b17023SJohn Marino 	  && id->remapping_type_depth == 0
892*e4b17023SJohn Marino 	  && !processing_debug_stmt)
893*e4b17023SJohn Marino 	add_referenced_var (*tp);
894*e4b17023SJohn Marino 
895*e4b17023SJohn Marino       if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
896*e4b17023SJohn Marino 	{
897*e4b17023SJohn Marino 	  /* The copied TARGET_EXPR has never been expanded, even if the
898*e4b17023SJohn Marino 	     original node was expanded already.  */
899*e4b17023SJohn Marino 	  TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
900*e4b17023SJohn Marino 	  TREE_OPERAND (*tp, 3) = NULL_TREE;
901*e4b17023SJohn Marino 	}
902*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == ADDR_EXPR)
903*e4b17023SJohn Marino 	{
904*e4b17023SJohn Marino 	  /* Variable substitution need not be simple.  In particular,
905*e4b17023SJohn Marino 	     the MEM_REF substitution above.  Make sure that
906*e4b17023SJohn Marino 	     TREE_CONSTANT and friends are up-to-date.  But make sure
907*e4b17023SJohn Marino 	     to not improperly set TREE_BLOCK on some sub-expressions.  */
908*e4b17023SJohn Marino 	  int invariant = is_gimple_min_invariant (*tp);
909*e4b17023SJohn Marino 	  tree block = id->block;
910*e4b17023SJohn Marino 	  id->block = NULL_TREE;
911*e4b17023SJohn Marino 	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
912*e4b17023SJohn Marino 	  id->block = block;
913*e4b17023SJohn Marino 	  recompute_tree_invariant_for_addr_expr (*tp);
914*e4b17023SJohn Marino 
915*e4b17023SJohn Marino 	  /* If this used to be invariant, but is not any longer,
916*e4b17023SJohn Marino 	     then regimplification is probably needed.  */
917*e4b17023SJohn Marino 	  if (invariant && !is_gimple_min_invariant (*tp))
918*e4b17023SJohn Marino 	    id->regimplify = true;
919*e4b17023SJohn Marino 
920*e4b17023SJohn Marino 	  *walk_subtrees = 0;
921*e4b17023SJohn Marino 	}
922*e4b17023SJohn Marino     }
923*e4b17023SJohn Marino 
924*e4b17023SJohn Marino   /* Keep iterating.  */
925*e4b17023SJohn Marino   return NULL_TREE;
926*e4b17023SJohn Marino }
927*e4b17023SJohn Marino 
928*e4b17023SJohn Marino 
929*e4b17023SJohn Marino /* Called from copy_body_id via walk_tree.  DATA is really a
930*e4b17023SJohn Marino    `copy_body_data *'.  */
931*e4b17023SJohn Marino 
932*e4b17023SJohn Marino tree
933*e4b17023SJohn Marino copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
934*e4b17023SJohn Marino {
935*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) data;
936*e4b17023SJohn Marino   tree fn = id->src_fn;
937*e4b17023SJohn Marino   tree new_block;
938*e4b17023SJohn Marino 
939*e4b17023SJohn Marino   /* Begin by recognizing trees that we'll completely rewrite for the
940*e4b17023SJohn Marino      inlining context.  Our output for these trees is completely
941*e4b17023SJohn Marino      different from out input (e.g. RETURN_EXPR is deleted, and morphs
942*e4b17023SJohn Marino      into an edge).  Further down, we'll handle trees that get
943*e4b17023SJohn Marino      duplicated and/or tweaked.  */
944*e4b17023SJohn Marino 
945*e4b17023SJohn Marino   /* When requested, RETURN_EXPRs should be transformed to just the
946*e4b17023SJohn Marino      contained MODIFY_EXPR.  The branch semantics of the return will
947*e4b17023SJohn Marino      be handled elsewhere by manipulating the CFG rather than a statement.  */
948*e4b17023SJohn Marino   if (TREE_CODE (*tp) == RETURN_EXPR && id->transform_return_to_modify)
949*e4b17023SJohn Marino     {
950*e4b17023SJohn Marino       tree assignment = TREE_OPERAND (*tp, 0);
951*e4b17023SJohn Marino 
952*e4b17023SJohn Marino       /* If we're returning something, just turn that into an
953*e4b17023SJohn Marino 	 assignment into the equivalent of the original RESULT_DECL.
954*e4b17023SJohn Marino 	 If the "assignment" is just the result decl, the result
955*e4b17023SJohn Marino 	 decl has already been set (e.g. a recent "foo (&result_decl,
956*e4b17023SJohn Marino 	 ...)"); just toss the entire RETURN_EXPR.  */
957*e4b17023SJohn Marino       if (assignment && TREE_CODE (assignment) == MODIFY_EXPR)
958*e4b17023SJohn Marino 	{
959*e4b17023SJohn Marino 	  /* Replace the RETURN_EXPR with (a copy of) the
960*e4b17023SJohn Marino 	     MODIFY_EXPR hanging underneath.  */
961*e4b17023SJohn Marino 	  *tp = copy_node (assignment);
962*e4b17023SJohn Marino 	}
963*e4b17023SJohn Marino       else /* Else the RETURN_EXPR returns no value.  */
964*e4b17023SJohn Marino 	{
965*e4b17023SJohn Marino 	  *tp = NULL;
966*e4b17023SJohn Marino 	  return (tree) (void *)1;
967*e4b17023SJohn Marino 	}
968*e4b17023SJohn Marino     }
969*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == SSA_NAME)
970*e4b17023SJohn Marino     {
971*e4b17023SJohn Marino       *tp = remap_ssa_name (*tp, id);
972*e4b17023SJohn Marino       *walk_subtrees = 0;
973*e4b17023SJohn Marino       return NULL;
974*e4b17023SJohn Marino     }
975*e4b17023SJohn Marino 
976*e4b17023SJohn Marino   /* Local variables and labels need to be replaced by equivalent
977*e4b17023SJohn Marino      variables.  We don't want to copy static variables; there's only
978*e4b17023SJohn Marino      one of those, no matter how many times we inline the containing
979*e4b17023SJohn Marino      function.  Similarly for globals from an outer function.  */
980*e4b17023SJohn Marino   else if (auto_var_in_fn_p (*tp, fn))
981*e4b17023SJohn Marino     {
982*e4b17023SJohn Marino       tree new_decl;
983*e4b17023SJohn Marino 
984*e4b17023SJohn Marino       /* Remap the declaration.  */
985*e4b17023SJohn Marino       new_decl = remap_decl (*tp, id);
986*e4b17023SJohn Marino       gcc_assert (new_decl);
987*e4b17023SJohn Marino       /* Replace this variable with the copy.  */
988*e4b17023SJohn Marino       STRIP_TYPE_NOPS (new_decl);
989*e4b17023SJohn Marino       *tp = new_decl;
990*e4b17023SJohn Marino       *walk_subtrees = 0;
991*e4b17023SJohn Marino     }
992*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == STATEMENT_LIST)
993*e4b17023SJohn Marino     copy_statement_list (tp);
994*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == SAVE_EXPR
995*e4b17023SJohn Marino 	   || TREE_CODE (*tp) == TARGET_EXPR)
996*e4b17023SJohn Marino     remap_save_expr (tp, id->decl_map, walk_subtrees);
997*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == LABEL_DECL
998*e4b17023SJohn Marino 	   && (! DECL_CONTEXT (*tp)
999*e4b17023SJohn Marino 	       || decl_function_context (*tp) == id->src_fn))
1000*e4b17023SJohn Marino     /* These may need to be remapped for EH handling.  */
1001*e4b17023SJohn Marino     *tp = remap_decl (*tp, id);
1002*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == BIND_EXPR)
1003*e4b17023SJohn Marino     copy_bind_expr (tp, walk_subtrees, id);
1004*e4b17023SJohn Marino   /* Types may need remapping as well.  */
1005*e4b17023SJohn Marino   else if (TYPE_P (*tp))
1006*e4b17023SJohn Marino     *tp = remap_type (*tp, id);
1007*e4b17023SJohn Marino 
1008*e4b17023SJohn Marino   /* If this is a constant, we have to copy the node iff the type will be
1009*e4b17023SJohn Marino      remapped.  copy_tree_r will not copy a constant.  */
1010*e4b17023SJohn Marino   else if (CONSTANT_CLASS_P (*tp))
1011*e4b17023SJohn Marino     {
1012*e4b17023SJohn Marino       tree new_type = remap_type (TREE_TYPE (*tp), id);
1013*e4b17023SJohn Marino 
1014*e4b17023SJohn Marino       if (new_type == TREE_TYPE (*tp))
1015*e4b17023SJohn Marino 	*walk_subtrees = 0;
1016*e4b17023SJohn Marino 
1017*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == INTEGER_CST)
1018*e4b17023SJohn Marino 	*tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp),
1019*e4b17023SJohn Marino 				  TREE_INT_CST_HIGH (*tp));
1020*e4b17023SJohn Marino       else
1021*e4b17023SJohn Marino 	{
1022*e4b17023SJohn Marino 	  *tp = copy_node (*tp);
1023*e4b17023SJohn Marino 	  TREE_TYPE (*tp) = new_type;
1024*e4b17023SJohn Marino 	}
1025*e4b17023SJohn Marino     }
1026*e4b17023SJohn Marino 
1027*e4b17023SJohn Marino   /* Otherwise, just copy the node.  Note that copy_tree_r already
1028*e4b17023SJohn Marino      knows not to copy VAR_DECLs, etc., so this is safe.  */
1029*e4b17023SJohn Marino   else
1030*e4b17023SJohn Marino     {
1031*e4b17023SJohn Marino       /* Here we handle trees that are not completely rewritten.
1032*e4b17023SJohn Marino 	 First we detect some inlining-induced bogosities for
1033*e4b17023SJohn Marino 	 discarding.  */
1034*e4b17023SJohn Marino       if (TREE_CODE (*tp) == MODIFY_EXPR
1035*e4b17023SJohn Marino 	  && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
1036*e4b17023SJohn Marino 	  && (auto_var_in_fn_p (TREE_OPERAND (*tp, 0), fn)))
1037*e4b17023SJohn Marino 	{
1038*e4b17023SJohn Marino 	  /* Some assignments VAR = VAR; don't generate any rtl code
1039*e4b17023SJohn Marino 	     and thus don't count as variable modification.  Avoid
1040*e4b17023SJohn Marino 	     keeping bogosities like 0 = 0.  */
1041*e4b17023SJohn Marino 	  tree decl = TREE_OPERAND (*tp, 0), value;
1042*e4b17023SJohn Marino 	  tree *n;
1043*e4b17023SJohn Marino 
1044*e4b17023SJohn Marino 	  n = (tree *) pointer_map_contains (id->decl_map, decl);
1045*e4b17023SJohn Marino 	  if (n)
1046*e4b17023SJohn Marino 	    {
1047*e4b17023SJohn Marino 	      value = *n;
1048*e4b17023SJohn Marino 	      STRIP_TYPE_NOPS (value);
1049*e4b17023SJohn Marino 	      if (TREE_CONSTANT (value) || TREE_READONLY (value))
1050*e4b17023SJohn Marino 		{
1051*e4b17023SJohn Marino 		  *tp = build_empty_stmt (EXPR_LOCATION (*tp));
1052*e4b17023SJohn Marino 		  return copy_tree_body_r (tp, walk_subtrees, data);
1053*e4b17023SJohn Marino 		}
1054*e4b17023SJohn Marino 	    }
1055*e4b17023SJohn Marino 	}
1056*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == INDIRECT_REF)
1057*e4b17023SJohn Marino 	{
1058*e4b17023SJohn Marino 	  /* Get rid of *& from inline substitutions that can happen when a
1059*e4b17023SJohn Marino 	     pointer argument is an ADDR_EXPR.  */
1060*e4b17023SJohn Marino 	  tree decl = TREE_OPERAND (*tp, 0);
1061*e4b17023SJohn Marino 	  tree *n;
1062*e4b17023SJohn Marino 
1063*e4b17023SJohn Marino 	  n = (tree *) pointer_map_contains (id->decl_map, decl);
1064*e4b17023SJohn Marino 	  if (n)
1065*e4b17023SJohn Marino 	    {
1066*e4b17023SJohn Marino 	      tree new_tree;
1067*e4b17023SJohn Marino 	      tree old;
1068*e4b17023SJohn Marino 	      /* If we happen to get an ADDR_EXPR in n->value, strip
1069*e4b17023SJohn Marino 	         it manually here as we'll eventually get ADDR_EXPRs
1070*e4b17023SJohn Marino 		 which lie about their types pointed to.  In this case
1071*e4b17023SJohn Marino 		 build_fold_indirect_ref wouldn't strip the INDIRECT_REF,
1072*e4b17023SJohn Marino 		 but we absolutely rely on that.  As fold_indirect_ref
1073*e4b17023SJohn Marino 	         does other useful transformations, try that first, though.  */
1074*e4b17023SJohn Marino 	      tree type = TREE_TYPE (TREE_TYPE (*n));
1075*e4b17023SJohn Marino 	      if (id->do_not_unshare)
1076*e4b17023SJohn Marino 		new_tree = *n;
1077*e4b17023SJohn Marino 	      else
1078*e4b17023SJohn Marino 		new_tree = unshare_expr (*n);
1079*e4b17023SJohn Marino 	      old = *tp;
1080*e4b17023SJohn Marino 	      *tp = gimple_fold_indirect_ref (new_tree);
1081*e4b17023SJohn Marino 	      if (! *tp)
1082*e4b17023SJohn Marino 	        {
1083*e4b17023SJohn Marino 		  if (TREE_CODE (new_tree) == ADDR_EXPR)
1084*e4b17023SJohn Marino 		    {
1085*e4b17023SJohn Marino 		      *tp = fold_indirect_ref_1 (EXPR_LOCATION (new_tree),
1086*e4b17023SJohn Marino 						 type, new_tree);
1087*e4b17023SJohn Marino 		      /* ???  We should either assert here or build
1088*e4b17023SJohn Marino 			 a VIEW_CONVERT_EXPR instead of blindly leaking
1089*e4b17023SJohn Marino 			 incompatible types to our IL.  */
1090*e4b17023SJohn Marino 		      if (! *tp)
1091*e4b17023SJohn Marino 			*tp = TREE_OPERAND (new_tree, 0);
1092*e4b17023SJohn Marino 		    }
1093*e4b17023SJohn Marino 	          else
1094*e4b17023SJohn Marino 		    {
1095*e4b17023SJohn Marino 	              *tp = build1 (INDIRECT_REF, type, new_tree);
1096*e4b17023SJohn Marino 		      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
1097*e4b17023SJohn Marino 		      TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
1098*e4b17023SJohn Marino 		      TREE_READONLY (*tp) = TREE_READONLY (old);
1099*e4b17023SJohn Marino 		      TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
1100*e4b17023SJohn Marino 		    }
1101*e4b17023SJohn Marino 		}
1102*e4b17023SJohn Marino 	      *walk_subtrees = 0;
1103*e4b17023SJohn Marino 	      return NULL;
1104*e4b17023SJohn Marino 	    }
1105*e4b17023SJohn Marino 	}
1106*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == MEM_REF)
1107*e4b17023SJohn Marino 	{
1108*e4b17023SJohn Marino 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
1109*e4b17023SJohn Marino 	     that can happen when a pointer argument is an ADDR_EXPR.  */
1110*e4b17023SJohn Marino 	  tree decl = TREE_OPERAND (*tp, 0);
1111*e4b17023SJohn Marino 	  tree *n;
1112*e4b17023SJohn Marino 
1113*e4b17023SJohn Marino 	  n = (tree *) pointer_map_contains (id->decl_map, decl);
1114*e4b17023SJohn Marino 	  if (n)
1115*e4b17023SJohn Marino 	    {
1116*e4b17023SJohn Marino 	      tree old = *tp;
1117*e4b17023SJohn Marino 	      *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
1118*e4b17023SJohn Marino 				 unshare_expr (*n), TREE_OPERAND (*tp, 1));
1119*e4b17023SJohn Marino 	      TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
1120*e4b17023SJohn Marino 	      TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
1121*e4b17023SJohn Marino 	      *walk_subtrees = 0;
1122*e4b17023SJohn Marino 	      return NULL;
1123*e4b17023SJohn Marino 	    }
1124*e4b17023SJohn Marino 	}
1125*e4b17023SJohn Marino 
1126*e4b17023SJohn Marino       /* Here is the "usual case".  Copy this tree node, and then
1127*e4b17023SJohn Marino 	 tweak some special cases.  */
1128*e4b17023SJohn Marino       copy_tree_r (tp, walk_subtrees, NULL);
1129*e4b17023SJohn Marino 
1130*e4b17023SJohn Marino       /* Global variables we haven't seen yet needs to go into referenced
1131*e4b17023SJohn Marino 	 vars.  If not referenced from types or debug stmts only.  */
1132*e4b17023SJohn Marino       if (gimple_in_ssa_p (cfun)
1133*e4b17023SJohn Marino 	  && TREE_CODE (*tp) == VAR_DECL
1134*e4b17023SJohn Marino 	  && id->remapping_type_depth == 0
1135*e4b17023SJohn Marino 	  && !processing_debug_stmt)
1136*e4b17023SJohn Marino 	add_referenced_var (*tp);
1137*e4b17023SJohn Marino 
1138*e4b17023SJohn Marino       /* If EXPR has block defined, map it to newly constructed block.
1139*e4b17023SJohn Marino          When inlining we want EXPRs without block appear in the block
1140*e4b17023SJohn Marino 	 of function call if we are not remapping a type.  */
1141*e4b17023SJohn Marino       if (EXPR_P (*tp))
1142*e4b17023SJohn Marino 	{
1143*e4b17023SJohn Marino 	  new_block = id->remapping_type_depth == 0 ? id->block : NULL;
1144*e4b17023SJohn Marino 	  if (TREE_BLOCK (*tp))
1145*e4b17023SJohn Marino 	    {
1146*e4b17023SJohn Marino 	      tree *n;
1147*e4b17023SJohn Marino 	      n = (tree *) pointer_map_contains (id->decl_map,
1148*e4b17023SJohn Marino 						 TREE_BLOCK (*tp));
1149*e4b17023SJohn Marino 	      gcc_assert (n || id->remapping_type_depth != 0);
1150*e4b17023SJohn Marino 	      if (n)
1151*e4b17023SJohn Marino 		new_block = *n;
1152*e4b17023SJohn Marino 	    }
1153*e4b17023SJohn Marino 	  TREE_BLOCK (*tp) = new_block;
1154*e4b17023SJohn Marino 	}
1155*e4b17023SJohn Marino 
1156*e4b17023SJohn Marino       if (TREE_CODE (*tp) != OMP_CLAUSE)
1157*e4b17023SJohn Marino 	TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id);
1158*e4b17023SJohn Marino 
1159*e4b17023SJohn Marino       /* The copied TARGET_EXPR has never been expanded, even if the
1160*e4b17023SJohn Marino 	 original node was expanded already.  */
1161*e4b17023SJohn Marino       if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
1162*e4b17023SJohn Marino 	{
1163*e4b17023SJohn Marino 	  TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
1164*e4b17023SJohn Marino 	  TREE_OPERAND (*tp, 3) = NULL_TREE;
1165*e4b17023SJohn Marino 	}
1166*e4b17023SJohn Marino 
1167*e4b17023SJohn Marino       /* Variable substitution need not be simple.  In particular, the
1168*e4b17023SJohn Marino 	 INDIRECT_REF substitution above.  Make sure that TREE_CONSTANT
1169*e4b17023SJohn Marino 	 and friends are up-to-date.  */
1170*e4b17023SJohn Marino       else if (TREE_CODE (*tp) == ADDR_EXPR)
1171*e4b17023SJohn Marino 	{
1172*e4b17023SJohn Marino 	  int invariant = is_gimple_min_invariant (*tp);
1173*e4b17023SJohn Marino 	  walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL);
1174*e4b17023SJohn Marino 
1175*e4b17023SJohn Marino 	  /* Handle the case where we substituted an INDIRECT_REF
1176*e4b17023SJohn Marino 	     into the operand of the ADDR_EXPR.  */
1177*e4b17023SJohn Marino 	  if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
1178*e4b17023SJohn Marino 	    *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
1179*e4b17023SJohn Marino 	  else
1180*e4b17023SJohn Marino 	    recompute_tree_invariant_for_addr_expr (*tp);
1181*e4b17023SJohn Marino 
1182*e4b17023SJohn Marino 	  /* If this used to be invariant, but is not any longer,
1183*e4b17023SJohn Marino 	     then regimplification is probably needed.  */
1184*e4b17023SJohn Marino 	  if (invariant && !is_gimple_min_invariant (*tp))
1185*e4b17023SJohn Marino 	    id->regimplify = true;
1186*e4b17023SJohn Marino 
1187*e4b17023SJohn Marino 	  *walk_subtrees = 0;
1188*e4b17023SJohn Marino 	}
1189*e4b17023SJohn Marino     }
1190*e4b17023SJohn Marino 
1191*e4b17023SJohn Marino   /* Keep iterating.  */
1192*e4b17023SJohn Marino   return NULL_TREE;
1193*e4b17023SJohn Marino }
1194*e4b17023SJohn Marino 
1195*e4b17023SJohn Marino /* Helper for remap_gimple_stmt.  Given an EH region number for the
1196*e4b17023SJohn Marino    source function, map that to the duplicate EH region number in
1197*e4b17023SJohn Marino    the destination function.  */
1198*e4b17023SJohn Marino 
1199*e4b17023SJohn Marino static int
1200*e4b17023SJohn Marino remap_eh_region_nr (int old_nr, copy_body_data *id)
1201*e4b17023SJohn Marino {
1202*e4b17023SJohn Marino   eh_region old_r, new_r;
1203*e4b17023SJohn Marino   void **slot;
1204*e4b17023SJohn Marino 
1205*e4b17023SJohn Marino   old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr);
1206*e4b17023SJohn Marino   slot = pointer_map_contains (id->eh_map, old_r);
1207*e4b17023SJohn Marino   new_r = (eh_region) *slot;
1208*e4b17023SJohn Marino 
1209*e4b17023SJohn Marino   return new_r->index;
1210*e4b17023SJohn Marino }
1211*e4b17023SJohn Marino 
1212*e4b17023SJohn Marino /* Similar, but operate on INTEGER_CSTs.  */
1213*e4b17023SJohn Marino 
1214*e4b17023SJohn Marino static tree
1215*e4b17023SJohn Marino remap_eh_region_tree_nr (tree old_t_nr, copy_body_data *id)
1216*e4b17023SJohn Marino {
1217*e4b17023SJohn Marino   int old_nr, new_nr;
1218*e4b17023SJohn Marino 
1219*e4b17023SJohn Marino   old_nr = tree_low_cst (old_t_nr, 0);
1220*e4b17023SJohn Marino   new_nr = remap_eh_region_nr (old_nr, id);
1221*e4b17023SJohn Marino 
1222*e4b17023SJohn Marino   return build_int_cst (integer_type_node, new_nr);
1223*e4b17023SJohn Marino }
1224*e4b17023SJohn Marino 
1225*e4b17023SJohn Marino /* Helper for copy_bb.  Remap statement STMT using the inlining
1226*e4b17023SJohn Marino    information in ID.  Return the new statement copy.  */
1227*e4b17023SJohn Marino 
1228*e4b17023SJohn Marino static gimple
1229*e4b17023SJohn Marino remap_gimple_stmt (gimple stmt, copy_body_data *id)
1230*e4b17023SJohn Marino {
1231*e4b17023SJohn Marino   gimple copy = NULL;
1232*e4b17023SJohn Marino   struct walk_stmt_info wi;
1233*e4b17023SJohn Marino   tree new_block;
1234*e4b17023SJohn Marino   bool skip_first = false;
1235*e4b17023SJohn Marino 
1236*e4b17023SJohn Marino   /* Begin by recognizing trees that we'll completely rewrite for the
1237*e4b17023SJohn Marino      inlining context.  Our output for these trees is completely
1238*e4b17023SJohn Marino      different from out input (e.g. RETURN_EXPR is deleted, and morphs
1239*e4b17023SJohn Marino      into an edge).  Further down, we'll handle trees that get
1240*e4b17023SJohn Marino      duplicated and/or tweaked.  */
1241*e4b17023SJohn Marino 
1242*e4b17023SJohn Marino   /* When requested, GIMPLE_RETURNs should be transformed to just the
1243*e4b17023SJohn Marino      contained GIMPLE_ASSIGN.  The branch semantics of the return will
1244*e4b17023SJohn Marino      be handled elsewhere by manipulating the CFG rather than the
1245*e4b17023SJohn Marino      statement.  */
1246*e4b17023SJohn Marino   if (gimple_code (stmt) == GIMPLE_RETURN && id->transform_return_to_modify)
1247*e4b17023SJohn Marino     {
1248*e4b17023SJohn Marino       tree retval = gimple_return_retval (stmt);
1249*e4b17023SJohn Marino 
1250*e4b17023SJohn Marino       /* If we're returning something, just turn that into an
1251*e4b17023SJohn Marino 	 assignment into the equivalent of the original RESULT_DECL.
1252*e4b17023SJohn Marino 	 If RETVAL is just the result decl, the result decl has
1253*e4b17023SJohn Marino 	 already been set (e.g. a recent "foo (&result_decl, ...)");
1254*e4b17023SJohn Marino 	 just toss the entire GIMPLE_RETURN.  */
1255*e4b17023SJohn Marino       if (retval
1256*e4b17023SJohn Marino 	  && (TREE_CODE (retval) != RESULT_DECL
1257*e4b17023SJohn Marino 	      && (TREE_CODE (retval) != SSA_NAME
1258*e4b17023SJohn Marino 		  || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL)))
1259*e4b17023SJohn Marino         {
1260*e4b17023SJohn Marino 	  copy = gimple_build_assign (id->retvar, retval);
1261*e4b17023SJohn Marino 	  /* id->retvar is already substituted.  Skip it on later remapping.  */
1262*e4b17023SJohn Marino 	  skip_first = true;
1263*e4b17023SJohn Marino 	}
1264*e4b17023SJohn Marino       else
1265*e4b17023SJohn Marino 	return gimple_build_nop ();
1266*e4b17023SJohn Marino     }
1267*e4b17023SJohn Marino   else if (gimple_has_substatements (stmt))
1268*e4b17023SJohn Marino     {
1269*e4b17023SJohn Marino       gimple_seq s1, s2;
1270*e4b17023SJohn Marino 
1271*e4b17023SJohn Marino       /* When cloning bodies from the C++ front end, we will be handed bodies
1272*e4b17023SJohn Marino 	 in High GIMPLE form.  Handle here all the High GIMPLE statements that
1273*e4b17023SJohn Marino 	 have embedded statements.  */
1274*e4b17023SJohn Marino       switch (gimple_code (stmt))
1275*e4b17023SJohn Marino 	{
1276*e4b17023SJohn Marino 	case GIMPLE_BIND:
1277*e4b17023SJohn Marino 	  copy = copy_gimple_bind (stmt, id);
1278*e4b17023SJohn Marino 	  break;
1279*e4b17023SJohn Marino 
1280*e4b17023SJohn Marino 	case GIMPLE_CATCH:
1281*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_catch_handler (stmt), id);
1282*e4b17023SJohn Marino 	  copy = gimple_build_catch (gimple_catch_types (stmt), s1);
1283*e4b17023SJohn Marino 	  break;
1284*e4b17023SJohn Marino 
1285*e4b17023SJohn Marino 	case GIMPLE_EH_FILTER:
1286*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_eh_filter_failure (stmt), id);
1287*e4b17023SJohn Marino 	  copy = gimple_build_eh_filter (gimple_eh_filter_types (stmt), s1);
1288*e4b17023SJohn Marino 	  break;
1289*e4b17023SJohn Marino 
1290*e4b17023SJohn Marino 	case GIMPLE_TRY:
1291*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_try_eval (stmt), id);
1292*e4b17023SJohn Marino 	  s2 = remap_gimple_seq (gimple_try_cleanup (stmt), id);
1293*e4b17023SJohn Marino 	  copy = gimple_build_try (s1, s2, gimple_try_kind (stmt));
1294*e4b17023SJohn Marino 	  break;
1295*e4b17023SJohn Marino 
1296*e4b17023SJohn Marino 	case GIMPLE_WITH_CLEANUP_EXPR:
1297*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_wce_cleanup (stmt), id);
1298*e4b17023SJohn Marino 	  copy = gimple_build_wce (s1);
1299*e4b17023SJohn Marino 	  break;
1300*e4b17023SJohn Marino 
1301*e4b17023SJohn Marino 	case GIMPLE_OMP_PARALLEL:
1302*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1303*e4b17023SJohn Marino 	  copy = gimple_build_omp_parallel
1304*e4b17023SJohn Marino 	           (s1,
1305*e4b17023SJohn Marino 		    gimple_omp_parallel_clauses (stmt),
1306*e4b17023SJohn Marino 		    gimple_omp_parallel_child_fn (stmt),
1307*e4b17023SJohn Marino 		    gimple_omp_parallel_data_arg (stmt));
1308*e4b17023SJohn Marino 	  break;
1309*e4b17023SJohn Marino 
1310*e4b17023SJohn Marino 	case GIMPLE_OMP_TASK:
1311*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1312*e4b17023SJohn Marino 	  copy = gimple_build_omp_task
1313*e4b17023SJohn Marino 	           (s1,
1314*e4b17023SJohn Marino 		    gimple_omp_task_clauses (stmt),
1315*e4b17023SJohn Marino 		    gimple_omp_task_child_fn (stmt),
1316*e4b17023SJohn Marino 		    gimple_omp_task_data_arg (stmt),
1317*e4b17023SJohn Marino 		    gimple_omp_task_copy_fn (stmt),
1318*e4b17023SJohn Marino 		    gimple_omp_task_arg_size (stmt),
1319*e4b17023SJohn Marino 		    gimple_omp_task_arg_align (stmt));
1320*e4b17023SJohn Marino 	  break;
1321*e4b17023SJohn Marino 
1322*e4b17023SJohn Marino 	case GIMPLE_OMP_FOR:
1323*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1324*e4b17023SJohn Marino 	  s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id);
1325*e4b17023SJohn Marino 	  copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt),
1326*e4b17023SJohn Marino 				       gimple_omp_for_collapse (stmt), s2);
1327*e4b17023SJohn Marino 	  {
1328*e4b17023SJohn Marino 	    size_t i;
1329*e4b17023SJohn Marino 	    for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1330*e4b17023SJohn Marino 	      {
1331*e4b17023SJohn Marino 		gimple_omp_for_set_index (copy, i,
1332*e4b17023SJohn Marino 					  gimple_omp_for_index (stmt, i));
1333*e4b17023SJohn Marino 		gimple_omp_for_set_initial (copy, i,
1334*e4b17023SJohn Marino 					    gimple_omp_for_initial (stmt, i));
1335*e4b17023SJohn Marino 		gimple_omp_for_set_final (copy, i,
1336*e4b17023SJohn Marino 					  gimple_omp_for_final (stmt, i));
1337*e4b17023SJohn Marino 		gimple_omp_for_set_incr (copy, i,
1338*e4b17023SJohn Marino 					 gimple_omp_for_incr (stmt, i));
1339*e4b17023SJohn Marino 		gimple_omp_for_set_cond (copy, i,
1340*e4b17023SJohn Marino 					 gimple_omp_for_cond (stmt, i));
1341*e4b17023SJohn Marino 	      }
1342*e4b17023SJohn Marino 	  }
1343*e4b17023SJohn Marino 	  break;
1344*e4b17023SJohn Marino 
1345*e4b17023SJohn Marino 	case GIMPLE_OMP_MASTER:
1346*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1347*e4b17023SJohn Marino 	  copy = gimple_build_omp_master (s1);
1348*e4b17023SJohn Marino 	  break;
1349*e4b17023SJohn Marino 
1350*e4b17023SJohn Marino 	case GIMPLE_OMP_ORDERED:
1351*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1352*e4b17023SJohn Marino 	  copy = gimple_build_omp_ordered (s1);
1353*e4b17023SJohn Marino 	  break;
1354*e4b17023SJohn Marino 
1355*e4b17023SJohn Marino 	case GIMPLE_OMP_SECTION:
1356*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1357*e4b17023SJohn Marino 	  copy = gimple_build_omp_section (s1);
1358*e4b17023SJohn Marino 	  break;
1359*e4b17023SJohn Marino 
1360*e4b17023SJohn Marino 	case GIMPLE_OMP_SECTIONS:
1361*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1362*e4b17023SJohn Marino 	  copy = gimple_build_omp_sections
1363*e4b17023SJohn Marino 	           (s1, gimple_omp_sections_clauses (stmt));
1364*e4b17023SJohn Marino 	  break;
1365*e4b17023SJohn Marino 
1366*e4b17023SJohn Marino 	case GIMPLE_OMP_SINGLE:
1367*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1368*e4b17023SJohn Marino 	  copy = gimple_build_omp_single
1369*e4b17023SJohn Marino 	           (s1, gimple_omp_single_clauses (stmt));
1370*e4b17023SJohn Marino 	  break;
1371*e4b17023SJohn Marino 
1372*e4b17023SJohn Marino 	case GIMPLE_OMP_CRITICAL:
1373*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
1374*e4b17023SJohn Marino 	  copy
1375*e4b17023SJohn Marino 	    = gimple_build_omp_critical (s1, gimple_omp_critical_name (stmt));
1376*e4b17023SJohn Marino 	  break;
1377*e4b17023SJohn Marino 
1378*e4b17023SJohn Marino 	case GIMPLE_TRANSACTION:
1379*e4b17023SJohn Marino 	  s1 = remap_gimple_seq (gimple_transaction_body (stmt), id);
1380*e4b17023SJohn Marino 	  copy = gimple_build_transaction (s1, gimple_transaction_label (stmt));
1381*e4b17023SJohn Marino 	  gimple_transaction_set_subcode (copy, gimple_transaction_subcode (stmt));
1382*e4b17023SJohn Marino 	  break;
1383*e4b17023SJohn Marino 
1384*e4b17023SJohn Marino 	default:
1385*e4b17023SJohn Marino 	  gcc_unreachable ();
1386*e4b17023SJohn Marino 	}
1387*e4b17023SJohn Marino     }
1388*e4b17023SJohn Marino   else
1389*e4b17023SJohn Marino     {
1390*e4b17023SJohn Marino       if (gimple_assign_copy_p (stmt)
1391*e4b17023SJohn Marino 	  && gimple_assign_lhs (stmt) == gimple_assign_rhs1 (stmt)
1392*e4b17023SJohn Marino 	  && auto_var_in_fn_p (gimple_assign_lhs (stmt), id->src_fn))
1393*e4b17023SJohn Marino 	{
1394*e4b17023SJohn Marino 	  /* Here we handle statements that are not completely rewritten.
1395*e4b17023SJohn Marino 	     First we detect some inlining-induced bogosities for
1396*e4b17023SJohn Marino 	     discarding.  */
1397*e4b17023SJohn Marino 
1398*e4b17023SJohn Marino 	  /* Some assignments VAR = VAR; don't generate any rtl code
1399*e4b17023SJohn Marino 	     and thus don't count as variable modification.  Avoid
1400*e4b17023SJohn Marino 	     keeping bogosities like 0 = 0.  */
1401*e4b17023SJohn Marino 	  tree decl = gimple_assign_lhs (stmt), value;
1402*e4b17023SJohn Marino 	  tree *n;
1403*e4b17023SJohn Marino 
1404*e4b17023SJohn Marino 	  n = (tree *) pointer_map_contains (id->decl_map, decl);
1405*e4b17023SJohn Marino 	  if (n)
1406*e4b17023SJohn Marino 	    {
1407*e4b17023SJohn Marino 	      value = *n;
1408*e4b17023SJohn Marino 	      STRIP_TYPE_NOPS (value);
1409*e4b17023SJohn Marino 	      if (TREE_CONSTANT (value) || TREE_READONLY (value))
1410*e4b17023SJohn Marino 		return gimple_build_nop ();
1411*e4b17023SJohn Marino 	    }
1412*e4b17023SJohn Marino 	}
1413*e4b17023SJohn Marino 
1414*e4b17023SJohn Marino       if (gimple_debug_bind_p (stmt))
1415*e4b17023SJohn Marino 	{
1416*e4b17023SJohn Marino 	  copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
1417*e4b17023SJohn Marino 					  gimple_debug_bind_get_value (stmt),
1418*e4b17023SJohn Marino 					  stmt);
1419*e4b17023SJohn Marino 	  VEC_safe_push (gimple, heap, id->debug_stmts, copy);
1420*e4b17023SJohn Marino 	  return copy;
1421*e4b17023SJohn Marino 	}
1422*e4b17023SJohn Marino       if (gimple_debug_source_bind_p (stmt))
1423*e4b17023SJohn Marino 	{
1424*e4b17023SJohn Marino 	  copy = gimple_build_debug_source_bind
1425*e4b17023SJohn Marino 		   (gimple_debug_source_bind_get_var (stmt),
1426*e4b17023SJohn Marino 		    gimple_debug_source_bind_get_value (stmt), stmt);
1427*e4b17023SJohn Marino 	  VEC_safe_push (gimple, heap, id->debug_stmts, copy);
1428*e4b17023SJohn Marino 	  return copy;
1429*e4b17023SJohn Marino 	}
1430*e4b17023SJohn Marino 
1431*e4b17023SJohn Marino       /* Create a new deep copy of the statement.  */
1432*e4b17023SJohn Marino       copy = gimple_copy (stmt);
1433*e4b17023SJohn Marino 
1434*e4b17023SJohn Marino       /* Remap the region numbers for __builtin_eh_{pointer,filter},
1435*e4b17023SJohn Marino 	 RESX and EH_DISPATCH.  */
1436*e4b17023SJohn Marino       if (id->eh_map)
1437*e4b17023SJohn Marino 	switch (gimple_code (copy))
1438*e4b17023SJohn Marino 	  {
1439*e4b17023SJohn Marino 	  case GIMPLE_CALL:
1440*e4b17023SJohn Marino 	    {
1441*e4b17023SJohn Marino 	      tree r, fndecl = gimple_call_fndecl (copy);
1442*e4b17023SJohn Marino 	      if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
1443*e4b17023SJohn Marino 		switch (DECL_FUNCTION_CODE (fndecl))
1444*e4b17023SJohn Marino 		  {
1445*e4b17023SJohn Marino 		  case BUILT_IN_EH_COPY_VALUES:
1446*e4b17023SJohn Marino 		    r = gimple_call_arg (copy, 1);
1447*e4b17023SJohn Marino 		    r = remap_eh_region_tree_nr (r, id);
1448*e4b17023SJohn Marino 		    gimple_call_set_arg (copy, 1, r);
1449*e4b17023SJohn Marino 		    /* FALLTHRU */
1450*e4b17023SJohn Marino 
1451*e4b17023SJohn Marino 		  case BUILT_IN_EH_POINTER:
1452*e4b17023SJohn Marino 		  case BUILT_IN_EH_FILTER:
1453*e4b17023SJohn Marino 		    r = gimple_call_arg (copy, 0);
1454*e4b17023SJohn Marino 		    r = remap_eh_region_tree_nr (r, id);
1455*e4b17023SJohn Marino 		    gimple_call_set_arg (copy, 0, r);
1456*e4b17023SJohn Marino 		    break;
1457*e4b17023SJohn Marino 
1458*e4b17023SJohn Marino 		  default:
1459*e4b17023SJohn Marino 		    break;
1460*e4b17023SJohn Marino 		  }
1461*e4b17023SJohn Marino 
1462*e4b17023SJohn Marino 	      /* Reset alias info if we didn't apply measures to
1463*e4b17023SJohn Marino 		 keep it valid over inlining by setting DECL_PT_UID.  */
1464*e4b17023SJohn Marino 	      if (!id->src_cfun->gimple_df
1465*e4b17023SJohn Marino 		  || !id->src_cfun->gimple_df->ipa_pta)
1466*e4b17023SJohn Marino 		gimple_call_reset_alias_info (copy);
1467*e4b17023SJohn Marino 	    }
1468*e4b17023SJohn Marino 	    break;
1469*e4b17023SJohn Marino 
1470*e4b17023SJohn Marino 	  case GIMPLE_RESX:
1471*e4b17023SJohn Marino 	    {
1472*e4b17023SJohn Marino 	      int r = gimple_resx_region (copy);
1473*e4b17023SJohn Marino 	      r = remap_eh_region_nr (r, id);
1474*e4b17023SJohn Marino 	      gimple_resx_set_region (copy, r);
1475*e4b17023SJohn Marino 	    }
1476*e4b17023SJohn Marino 	    break;
1477*e4b17023SJohn Marino 
1478*e4b17023SJohn Marino 	  case GIMPLE_EH_DISPATCH:
1479*e4b17023SJohn Marino 	    {
1480*e4b17023SJohn Marino 	      int r = gimple_eh_dispatch_region (copy);
1481*e4b17023SJohn Marino 	      r = remap_eh_region_nr (r, id);
1482*e4b17023SJohn Marino 	      gimple_eh_dispatch_set_region (copy, r);
1483*e4b17023SJohn Marino 	    }
1484*e4b17023SJohn Marino 	    break;
1485*e4b17023SJohn Marino 
1486*e4b17023SJohn Marino 	  default:
1487*e4b17023SJohn Marino 	    break;
1488*e4b17023SJohn Marino 	  }
1489*e4b17023SJohn Marino     }
1490*e4b17023SJohn Marino 
1491*e4b17023SJohn Marino   /* If STMT has a block defined, map it to the newly constructed
1492*e4b17023SJohn Marino      block.  When inlining we want statements without a block to
1493*e4b17023SJohn Marino      appear in the block of the function call.  */
1494*e4b17023SJohn Marino   new_block = id->block;
1495*e4b17023SJohn Marino   if (gimple_block (copy))
1496*e4b17023SJohn Marino     {
1497*e4b17023SJohn Marino       tree *n;
1498*e4b17023SJohn Marino       n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy));
1499*e4b17023SJohn Marino       gcc_assert (n);
1500*e4b17023SJohn Marino       new_block = *n;
1501*e4b17023SJohn Marino     }
1502*e4b17023SJohn Marino 
1503*e4b17023SJohn Marino   gimple_set_block (copy, new_block);
1504*e4b17023SJohn Marino 
1505*e4b17023SJohn Marino   if (gimple_debug_bind_p (copy) || gimple_debug_source_bind_p (copy))
1506*e4b17023SJohn Marino     return copy;
1507*e4b17023SJohn Marino 
1508*e4b17023SJohn Marino   /* Remap all the operands in COPY.  */
1509*e4b17023SJohn Marino   memset (&wi, 0, sizeof (wi));
1510*e4b17023SJohn Marino   wi.info = id;
1511*e4b17023SJohn Marino   if (skip_first)
1512*e4b17023SJohn Marino     walk_tree (gimple_op_ptr (copy, 1), remap_gimple_op_r, &wi, NULL);
1513*e4b17023SJohn Marino   else
1514*e4b17023SJohn Marino     walk_gimple_op (copy, remap_gimple_op_r, &wi);
1515*e4b17023SJohn Marino 
1516*e4b17023SJohn Marino   /* Clear the copied virtual operands.  We are not remapping them here
1517*e4b17023SJohn Marino      but are going to recreate them from scratch.  */
1518*e4b17023SJohn Marino   if (gimple_has_mem_ops (copy))
1519*e4b17023SJohn Marino     {
1520*e4b17023SJohn Marino       gimple_set_vdef (copy, NULL_TREE);
1521*e4b17023SJohn Marino       gimple_set_vuse (copy, NULL_TREE);
1522*e4b17023SJohn Marino     }
1523*e4b17023SJohn Marino 
1524*e4b17023SJohn Marino   return copy;
1525*e4b17023SJohn Marino }
1526*e4b17023SJohn Marino 
1527*e4b17023SJohn Marino 
1528*e4b17023SJohn Marino /* Copy basic block, scale profile accordingly.  Edges will be taken care of
1529*e4b17023SJohn Marino    later  */
1530*e4b17023SJohn Marino 
1531*e4b17023SJohn Marino static basic_block
1532*e4b17023SJohn Marino copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
1533*e4b17023SJohn Marino          gcov_type count_scale)
1534*e4b17023SJohn Marino {
1535*e4b17023SJohn Marino   gimple_stmt_iterator gsi, copy_gsi, seq_gsi;
1536*e4b17023SJohn Marino   basic_block copy_basic_block;
1537*e4b17023SJohn Marino   tree decl;
1538*e4b17023SJohn Marino   gcov_type freq;
1539*e4b17023SJohn Marino   basic_block prev;
1540*e4b17023SJohn Marino 
1541*e4b17023SJohn Marino   /* Search for previous copied basic block.  */
1542*e4b17023SJohn Marino   prev = bb->prev_bb;
1543*e4b17023SJohn Marino   while (!prev->aux)
1544*e4b17023SJohn Marino     prev = prev->prev_bb;
1545*e4b17023SJohn Marino 
1546*e4b17023SJohn Marino   /* create_basic_block() will append every new block to
1547*e4b17023SJohn Marino      basic_block_info automatically.  */
1548*e4b17023SJohn Marino   copy_basic_block = create_basic_block (NULL, (void *) 0,
1549*e4b17023SJohn Marino                                          (basic_block) prev->aux);
1550*e4b17023SJohn Marino   copy_basic_block->count = bb->count * count_scale / REG_BR_PROB_BASE;
1551*e4b17023SJohn Marino 
1552*e4b17023SJohn Marino   /* We are going to rebuild frequencies from scratch.  These values
1553*e4b17023SJohn Marino      have just small importance to drive canonicalize_loop_headers.  */
1554*e4b17023SJohn Marino   freq = ((gcov_type)bb->frequency * frequency_scale / REG_BR_PROB_BASE);
1555*e4b17023SJohn Marino 
1556*e4b17023SJohn Marino   /* We recompute frequencies after inlining, so this is quite safe.  */
1557*e4b17023SJohn Marino   if (freq > BB_FREQ_MAX)
1558*e4b17023SJohn Marino     freq = BB_FREQ_MAX;
1559*e4b17023SJohn Marino   copy_basic_block->frequency = freq;
1560*e4b17023SJohn Marino 
1561*e4b17023SJohn Marino   copy_gsi = gsi_start_bb (copy_basic_block);
1562*e4b17023SJohn Marino 
1563*e4b17023SJohn Marino   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1564*e4b17023SJohn Marino     {
1565*e4b17023SJohn Marino       gimple stmt = gsi_stmt (gsi);
1566*e4b17023SJohn Marino       gimple orig_stmt = stmt;
1567*e4b17023SJohn Marino 
1568*e4b17023SJohn Marino       id->regimplify = false;
1569*e4b17023SJohn Marino       stmt = remap_gimple_stmt (stmt, id);
1570*e4b17023SJohn Marino       if (gimple_nop_p (stmt))
1571*e4b17023SJohn Marino 	continue;
1572*e4b17023SJohn Marino 
1573*e4b17023SJohn Marino       gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
1574*e4b17023SJohn Marino       seq_gsi = copy_gsi;
1575*e4b17023SJohn Marino 
1576*e4b17023SJohn Marino       /* With return slot optimization we can end up with
1577*e4b17023SJohn Marino 	 non-gimple (foo *)&this->m, fix that here.  */
1578*e4b17023SJohn Marino       if (is_gimple_assign (stmt)
1579*e4b17023SJohn Marino 	  && gimple_assign_rhs_code (stmt) == NOP_EXPR
1580*e4b17023SJohn Marino 	  && !is_gimple_val (gimple_assign_rhs1 (stmt)))
1581*e4b17023SJohn Marino 	{
1582*e4b17023SJohn Marino 	  tree new_rhs;
1583*e4b17023SJohn Marino 	  new_rhs = force_gimple_operand_gsi (&seq_gsi,
1584*e4b17023SJohn Marino 					      gimple_assign_rhs1 (stmt),
1585*e4b17023SJohn Marino 					      true, NULL, false,
1586*e4b17023SJohn Marino 					      GSI_CONTINUE_LINKING);
1587*e4b17023SJohn Marino 	  gimple_assign_set_rhs1 (stmt, new_rhs);
1588*e4b17023SJohn Marino 	  id->regimplify = false;
1589*e4b17023SJohn Marino 	}
1590*e4b17023SJohn Marino 
1591*e4b17023SJohn Marino       gsi_insert_after (&seq_gsi, stmt, GSI_NEW_STMT);
1592*e4b17023SJohn Marino 
1593*e4b17023SJohn Marino       if (id->regimplify)
1594*e4b17023SJohn Marino 	gimple_regimplify_operands (stmt, &seq_gsi);
1595*e4b17023SJohn Marino 
1596*e4b17023SJohn Marino       /* If copy_basic_block has been empty at the start of this iteration,
1597*e4b17023SJohn Marino 	 call gsi_start_bb again to get at the newly added statements.  */
1598*e4b17023SJohn Marino       if (gsi_end_p (copy_gsi))
1599*e4b17023SJohn Marino 	copy_gsi = gsi_start_bb (copy_basic_block);
1600*e4b17023SJohn Marino       else
1601*e4b17023SJohn Marino 	gsi_next (&copy_gsi);
1602*e4b17023SJohn Marino 
1603*e4b17023SJohn Marino       /* Process the new statement.  The call to gimple_regimplify_operands
1604*e4b17023SJohn Marino 	 possibly turned the statement into multiple statements, we
1605*e4b17023SJohn Marino 	 need to process all of them.  */
1606*e4b17023SJohn Marino       do
1607*e4b17023SJohn Marino 	{
1608*e4b17023SJohn Marino 	  tree fn;
1609*e4b17023SJohn Marino 
1610*e4b17023SJohn Marino 	  stmt = gsi_stmt (copy_gsi);
1611*e4b17023SJohn Marino 	  if (is_gimple_call (stmt)
1612*e4b17023SJohn Marino 	      && gimple_call_va_arg_pack_p (stmt)
1613*e4b17023SJohn Marino 	      && id->gimple_call)
1614*e4b17023SJohn Marino 	    {
1615*e4b17023SJohn Marino 	      /* __builtin_va_arg_pack () should be replaced by
1616*e4b17023SJohn Marino 		 all arguments corresponding to ... in the caller.  */
1617*e4b17023SJohn Marino 	      tree p;
1618*e4b17023SJohn Marino 	      gimple new_call;
1619*e4b17023SJohn Marino 	      VEC(tree, heap) *argarray;
1620*e4b17023SJohn Marino 	      size_t nargs = gimple_call_num_args (id->gimple_call);
1621*e4b17023SJohn Marino 	      size_t n;
1622*e4b17023SJohn Marino 
1623*e4b17023SJohn Marino 	      for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
1624*e4b17023SJohn Marino 		nargs--;
1625*e4b17023SJohn Marino 
1626*e4b17023SJohn Marino 	      /* Create the new array of arguments.  */
1627*e4b17023SJohn Marino 	      n = nargs + gimple_call_num_args (stmt);
1628*e4b17023SJohn Marino 	      argarray = VEC_alloc (tree, heap, n);
1629*e4b17023SJohn Marino 	      VEC_safe_grow (tree, heap, argarray, n);
1630*e4b17023SJohn Marino 
1631*e4b17023SJohn Marino 	      /* Copy all the arguments before '...'  */
1632*e4b17023SJohn Marino 	      memcpy (VEC_address (tree, argarray),
1633*e4b17023SJohn Marino 		      gimple_call_arg_ptr (stmt, 0),
1634*e4b17023SJohn Marino 		      gimple_call_num_args (stmt) * sizeof (tree));
1635*e4b17023SJohn Marino 
1636*e4b17023SJohn Marino 	      /* Append the arguments passed in '...'  */
1637*e4b17023SJohn Marino 	      memcpy (VEC_address(tree, argarray) + gimple_call_num_args (stmt),
1638*e4b17023SJohn Marino 		      gimple_call_arg_ptr (id->gimple_call, 0)
1639*e4b17023SJohn Marino 			+ (gimple_call_num_args (id->gimple_call) - nargs),
1640*e4b17023SJohn Marino 		      nargs * sizeof (tree));
1641*e4b17023SJohn Marino 
1642*e4b17023SJohn Marino 	      new_call = gimple_build_call_vec (gimple_call_fn (stmt),
1643*e4b17023SJohn Marino 						argarray);
1644*e4b17023SJohn Marino 
1645*e4b17023SJohn Marino 	      VEC_free (tree, heap, argarray);
1646*e4b17023SJohn Marino 
1647*e4b17023SJohn Marino 	      /* Copy all GIMPLE_CALL flags, location and block, except
1648*e4b17023SJohn Marino 		 GF_CALL_VA_ARG_PACK.  */
1649*e4b17023SJohn Marino 	      gimple_call_copy_flags (new_call, stmt);
1650*e4b17023SJohn Marino 	      gimple_call_set_va_arg_pack (new_call, false);
1651*e4b17023SJohn Marino 	      gimple_set_location (new_call, gimple_location (stmt));
1652*e4b17023SJohn Marino 	      gimple_set_block (new_call, gimple_block (stmt));
1653*e4b17023SJohn Marino 	      gimple_call_set_lhs (new_call, gimple_call_lhs (stmt));
1654*e4b17023SJohn Marino 
1655*e4b17023SJohn Marino 	      gsi_replace (&copy_gsi, new_call, false);
1656*e4b17023SJohn Marino 	      stmt = new_call;
1657*e4b17023SJohn Marino 	    }
1658*e4b17023SJohn Marino 	  else if (is_gimple_call (stmt)
1659*e4b17023SJohn Marino 		   && id->gimple_call
1660*e4b17023SJohn Marino 		   && (decl = gimple_call_fndecl (stmt))
1661*e4b17023SJohn Marino 		   && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
1662*e4b17023SJohn Marino 		   && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
1663*e4b17023SJohn Marino 	    {
1664*e4b17023SJohn Marino 	      /* __builtin_va_arg_pack_len () should be replaced by
1665*e4b17023SJohn Marino 		 the number of anonymous arguments.  */
1666*e4b17023SJohn Marino 	      size_t nargs = gimple_call_num_args (id->gimple_call);
1667*e4b17023SJohn Marino 	      tree count, p;
1668*e4b17023SJohn Marino 	      gimple new_stmt;
1669*e4b17023SJohn Marino 
1670*e4b17023SJohn Marino 	      for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p))
1671*e4b17023SJohn Marino 		nargs--;
1672*e4b17023SJohn Marino 
1673*e4b17023SJohn Marino 	      count = build_int_cst (integer_type_node, nargs);
1674*e4b17023SJohn Marino 	      new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count);
1675*e4b17023SJohn Marino 	      gsi_replace (&copy_gsi, new_stmt, false);
1676*e4b17023SJohn Marino 	      stmt = new_stmt;
1677*e4b17023SJohn Marino 	    }
1678*e4b17023SJohn Marino 
1679*e4b17023SJohn Marino 	  /* Statements produced by inlining can be unfolded, especially
1680*e4b17023SJohn Marino 	     when we constant propagated some operands.  We can't fold
1681*e4b17023SJohn Marino 	     them right now for two reasons:
1682*e4b17023SJohn Marino 	     1) folding require SSA_NAME_DEF_STMTs to be correct
1683*e4b17023SJohn Marino 	     2) we can't change function calls to builtins.
1684*e4b17023SJohn Marino 	     So we just mark statement for later folding.  We mark
1685*e4b17023SJohn Marino 	     all new statements, instead just statements that has changed
1686*e4b17023SJohn Marino 	     by some nontrivial substitution so even statements made
1687*e4b17023SJohn Marino 	     foldable indirectly are updated.  If this turns out to be
1688*e4b17023SJohn Marino 	     expensive, copy_body can be told to watch for nontrivial
1689*e4b17023SJohn Marino 	     changes.  */
1690*e4b17023SJohn Marino 	  if (id->statements_to_fold)
1691*e4b17023SJohn Marino 	    pointer_set_insert (id->statements_to_fold, stmt);
1692*e4b17023SJohn Marino 
1693*e4b17023SJohn Marino 	  /* We're duplicating a CALL_EXPR.  Find any corresponding
1694*e4b17023SJohn Marino 	     callgraph edges and update or duplicate them.  */
1695*e4b17023SJohn Marino 	  if (is_gimple_call (stmt))
1696*e4b17023SJohn Marino 	    {
1697*e4b17023SJohn Marino 	      struct cgraph_edge *edge;
1698*e4b17023SJohn Marino 	      int flags;
1699*e4b17023SJohn Marino 
1700*e4b17023SJohn Marino 	      switch (id->transform_call_graph_edges)
1701*e4b17023SJohn Marino 		{
1702*e4b17023SJohn Marino 		case CB_CGE_DUPLICATE:
1703*e4b17023SJohn Marino 		  edge = cgraph_edge (id->src_node, orig_stmt);
1704*e4b17023SJohn Marino 		  if (edge)
1705*e4b17023SJohn Marino 		    {
1706*e4b17023SJohn Marino 		      int edge_freq = edge->frequency;
1707*e4b17023SJohn Marino 		      edge = cgraph_clone_edge (edge, id->dst_node, stmt,
1708*e4b17023SJohn Marino 					        gimple_uid (stmt),
1709*e4b17023SJohn Marino 					        REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
1710*e4b17023SJohn Marino 					        true);
1711*e4b17023SJohn Marino 		      /* We could also just rescale the frequency, but
1712*e4b17023SJohn Marino 		         doing so would introduce roundoff errors and make
1713*e4b17023SJohn Marino 			 verifier unhappy.  */
1714*e4b17023SJohn Marino 		      edge->frequency
1715*e4b17023SJohn Marino 		        = compute_call_stmt_bb_frequency (id->dst_node->decl,
1716*e4b17023SJohn Marino 							  copy_basic_block);
1717*e4b17023SJohn Marino 		      if (dump_file
1718*e4b17023SJohn Marino 		      	  && profile_status_for_function (cfun) != PROFILE_ABSENT
1719*e4b17023SJohn Marino 			  && (edge_freq > edge->frequency + 10
1720*e4b17023SJohn Marino 			      || edge_freq < edge->frequency - 10))
1721*e4b17023SJohn Marino 			{
1722*e4b17023SJohn Marino 			  fprintf (dump_file, "Edge frequency estimated by "
1723*e4b17023SJohn Marino 			           "cgraph %i diverge from inliner's estimate %i\n",
1724*e4b17023SJohn Marino 			  	   edge_freq,
1725*e4b17023SJohn Marino 				   edge->frequency);
1726*e4b17023SJohn Marino 			  fprintf (dump_file,
1727*e4b17023SJohn Marino 			  	   "Orig bb: %i, orig bb freq %i, new bb freq %i\n",
1728*e4b17023SJohn Marino 				   bb->index,
1729*e4b17023SJohn Marino 				   bb->frequency,
1730*e4b17023SJohn Marino 				   copy_basic_block->frequency);
1731*e4b17023SJohn Marino 			}
1732*e4b17023SJohn Marino 		      stmt = cgraph_redirect_edge_call_stmt_to_callee (edge);
1733*e4b17023SJohn Marino 		    }
1734*e4b17023SJohn Marino 		  break;
1735*e4b17023SJohn Marino 
1736*e4b17023SJohn Marino 		case CB_CGE_MOVE_CLONES:
1737*e4b17023SJohn Marino 		  cgraph_set_call_stmt_including_clones (id->dst_node,
1738*e4b17023SJohn Marino 							 orig_stmt, stmt);
1739*e4b17023SJohn Marino 		  edge = cgraph_edge (id->dst_node, stmt);
1740*e4b17023SJohn Marino 		  break;
1741*e4b17023SJohn Marino 
1742*e4b17023SJohn Marino 		case CB_CGE_MOVE:
1743*e4b17023SJohn Marino 		  edge = cgraph_edge (id->dst_node, orig_stmt);
1744*e4b17023SJohn Marino 		  if (edge)
1745*e4b17023SJohn Marino 		    cgraph_set_call_stmt (edge, stmt);
1746*e4b17023SJohn Marino 		  break;
1747*e4b17023SJohn Marino 
1748*e4b17023SJohn Marino 		default:
1749*e4b17023SJohn Marino 		  gcc_unreachable ();
1750*e4b17023SJohn Marino 		}
1751*e4b17023SJohn Marino 
1752*e4b17023SJohn Marino 	      /* Constant propagation on argument done during inlining
1753*e4b17023SJohn Marino 		 may create new direct call.  Produce an edge for it.  */
1754*e4b17023SJohn Marino 	      if ((!edge
1755*e4b17023SJohn Marino 		   || (edge->indirect_inlining_edge
1756*e4b17023SJohn Marino 		       && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
1757*e4b17023SJohn Marino 		  && id->dst_node->analyzed
1758*e4b17023SJohn Marino 		  && (fn = gimple_call_fndecl (stmt)) != NULL)
1759*e4b17023SJohn Marino 		{
1760*e4b17023SJohn Marino 		  struct cgraph_node *dest = cgraph_get_node (fn);
1761*e4b17023SJohn Marino 
1762*e4b17023SJohn Marino 		  /* We have missing edge in the callgraph.  This can happen
1763*e4b17023SJohn Marino 		     when previous inlining turned an indirect call into a
1764*e4b17023SJohn Marino 		     direct call by constant propagating arguments or we are
1765*e4b17023SJohn Marino 		     producing dead clone (for further cloning).  In all
1766*e4b17023SJohn Marino 		     other cases we hit a bug (incorrect node sharing is the
1767*e4b17023SJohn Marino 		     most common reason for missing edges).  */
1768*e4b17023SJohn Marino 		  gcc_assert (dest->needed || !dest->analyzed
1769*e4b17023SJohn Marino 			      || dest->address_taken
1770*e4b17023SJohn Marino 		  	      || !id->src_node->analyzed
1771*e4b17023SJohn Marino 			      || !id->dst_node->analyzed);
1772*e4b17023SJohn Marino 		  if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
1773*e4b17023SJohn Marino 		    cgraph_create_edge_including_clones
1774*e4b17023SJohn Marino 		      (id->dst_node, dest, orig_stmt, stmt, bb->count,
1775*e4b17023SJohn Marino 		       compute_call_stmt_bb_frequency (id->dst_node->decl,
1776*e4b17023SJohn Marino 		       				       copy_basic_block),
1777*e4b17023SJohn Marino 		       CIF_ORIGINALLY_INDIRECT_CALL);
1778*e4b17023SJohn Marino 		  else
1779*e4b17023SJohn Marino 		    cgraph_create_edge (id->dst_node, dest, stmt,
1780*e4b17023SJohn Marino 					bb->count,
1781*e4b17023SJohn Marino 					compute_call_stmt_bb_frequency
1782*e4b17023SJohn Marino 					  (id->dst_node->decl, copy_basic_block))->inline_failed
1783*e4b17023SJohn Marino 		      = CIF_ORIGINALLY_INDIRECT_CALL;
1784*e4b17023SJohn Marino 		  if (dump_file)
1785*e4b17023SJohn Marino 		    {
1786*e4b17023SJohn Marino 		      fprintf (dump_file, "Created new direct edge to %s\n",
1787*e4b17023SJohn Marino 			       cgraph_node_name (dest));
1788*e4b17023SJohn Marino 		    }
1789*e4b17023SJohn Marino 		}
1790*e4b17023SJohn Marino 
1791*e4b17023SJohn Marino 	      flags = gimple_call_flags (stmt);
1792*e4b17023SJohn Marino 	      if (flags & ECF_MAY_BE_ALLOCA)
1793*e4b17023SJohn Marino 		cfun->calls_alloca = true;
1794*e4b17023SJohn Marino 	      if (flags & ECF_RETURNS_TWICE)
1795*e4b17023SJohn Marino 		cfun->calls_setjmp = true;
1796*e4b17023SJohn Marino 	    }
1797*e4b17023SJohn Marino 
1798*e4b17023SJohn Marino 	  maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
1799*e4b17023SJohn Marino 				      id->eh_map, id->eh_lp_nr);
1800*e4b17023SJohn Marino 
1801*e4b17023SJohn Marino 	  if (gimple_in_ssa_p (cfun) && !is_gimple_debug (stmt))
1802*e4b17023SJohn Marino 	    {
1803*e4b17023SJohn Marino 	      ssa_op_iter i;
1804*e4b17023SJohn Marino 	      tree def;
1805*e4b17023SJohn Marino 
1806*e4b17023SJohn Marino 	      find_new_referenced_vars (gsi_stmt (copy_gsi));
1807*e4b17023SJohn Marino 	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
1808*e4b17023SJohn Marino 		if (TREE_CODE (def) == SSA_NAME)
1809*e4b17023SJohn Marino 		  SSA_NAME_DEF_STMT (def) = stmt;
1810*e4b17023SJohn Marino 	    }
1811*e4b17023SJohn Marino 
1812*e4b17023SJohn Marino 	  gsi_next (&copy_gsi);
1813*e4b17023SJohn Marino 	}
1814*e4b17023SJohn Marino       while (!gsi_end_p (copy_gsi));
1815*e4b17023SJohn Marino 
1816*e4b17023SJohn Marino       copy_gsi = gsi_last_bb (copy_basic_block);
1817*e4b17023SJohn Marino     }
1818*e4b17023SJohn Marino 
1819*e4b17023SJohn Marino   return copy_basic_block;
1820*e4b17023SJohn Marino }
1821*e4b17023SJohn Marino 
1822*e4b17023SJohn Marino /* Inserting Single Entry Multiple Exit region in SSA form into code in SSA
1823*e4b17023SJohn Marino    form is quite easy, since dominator relationship for old basic blocks does
1824*e4b17023SJohn Marino    not change.
1825*e4b17023SJohn Marino 
1826*e4b17023SJohn Marino    There is however exception where inlining might change dominator relation
1827*e4b17023SJohn Marino    across EH edges from basic block within inlined functions destinating
1828*e4b17023SJohn Marino    to landing pads in function we inline into.
1829*e4b17023SJohn Marino 
1830*e4b17023SJohn Marino    The function fills in PHI_RESULTs of such PHI nodes if they refer
1831*e4b17023SJohn Marino    to gimple regs.  Otherwise, the function mark PHI_RESULT of such
1832*e4b17023SJohn Marino    PHI nodes for renaming.  For non-gimple regs, renaming is safe: the
1833*e4b17023SJohn Marino    EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI must be
1834*e4b17023SJohn Marino    set, and this means that there will be no overlapping live ranges
1835*e4b17023SJohn Marino    for the underlying symbol.
1836*e4b17023SJohn Marino 
1837*e4b17023SJohn Marino    This might change in future if we allow redirecting of EH edges and
1838*e4b17023SJohn Marino    we might want to change way build CFG pre-inlining to include
1839*e4b17023SJohn Marino    all the possible edges then.  */
1840*e4b17023SJohn Marino static void
1841*e4b17023SJohn Marino update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
1842*e4b17023SJohn Marino 				  bool can_throw, bool nonlocal_goto)
1843*e4b17023SJohn Marino {
1844*e4b17023SJohn Marino   edge e;
1845*e4b17023SJohn Marino   edge_iterator ei;
1846*e4b17023SJohn Marino 
1847*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
1848*e4b17023SJohn Marino     if (!e->dest->aux
1849*e4b17023SJohn Marino 	|| ((basic_block)e->dest->aux)->index == ENTRY_BLOCK)
1850*e4b17023SJohn Marino       {
1851*e4b17023SJohn Marino 	gimple phi;
1852*e4b17023SJohn Marino 	gimple_stmt_iterator si;
1853*e4b17023SJohn Marino 
1854*e4b17023SJohn Marino 	if (!nonlocal_goto)
1855*e4b17023SJohn Marino 	  gcc_assert (e->flags & EDGE_EH);
1856*e4b17023SJohn Marino 
1857*e4b17023SJohn Marino 	if (!can_throw)
1858*e4b17023SJohn Marino 	  gcc_assert (!(e->flags & EDGE_EH));
1859*e4b17023SJohn Marino 
1860*e4b17023SJohn Marino 	for (si = gsi_start_phis (e->dest); !gsi_end_p (si); gsi_next (&si))
1861*e4b17023SJohn Marino 	  {
1862*e4b17023SJohn Marino 	    edge re;
1863*e4b17023SJohn Marino 
1864*e4b17023SJohn Marino 	    phi = gsi_stmt (si);
1865*e4b17023SJohn Marino 
1866*e4b17023SJohn Marino 	    /* There shouldn't be any PHI nodes in the ENTRY_BLOCK.  */
1867*e4b17023SJohn Marino 	    gcc_assert (!e->dest->aux);
1868*e4b17023SJohn Marino 
1869*e4b17023SJohn Marino 	    gcc_assert ((e->flags & EDGE_EH)
1870*e4b17023SJohn Marino 			|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)));
1871*e4b17023SJohn Marino 
1872*e4b17023SJohn Marino 	    if (!is_gimple_reg (PHI_RESULT (phi)))
1873*e4b17023SJohn Marino 	      {
1874*e4b17023SJohn Marino 		mark_sym_for_renaming (SSA_NAME_VAR (PHI_RESULT (phi)));
1875*e4b17023SJohn Marino 		continue;
1876*e4b17023SJohn Marino 	      }
1877*e4b17023SJohn Marino 
1878*e4b17023SJohn Marino 	    re = find_edge (ret_bb, e->dest);
1879*e4b17023SJohn Marino 	    gcc_assert (re);
1880*e4b17023SJohn Marino 	    gcc_assert ((re->flags & (EDGE_EH | EDGE_ABNORMAL))
1881*e4b17023SJohn Marino 			== (e->flags & (EDGE_EH | EDGE_ABNORMAL)));
1882*e4b17023SJohn Marino 
1883*e4b17023SJohn Marino 	    SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
1884*e4b17023SJohn Marino 		     USE_FROM_PTR (PHI_ARG_DEF_PTR_FROM_EDGE (phi, re)));
1885*e4b17023SJohn Marino 	  }
1886*e4b17023SJohn Marino       }
1887*e4b17023SJohn Marino }
1888*e4b17023SJohn Marino 
1889*e4b17023SJohn Marino 
1890*e4b17023SJohn Marino /* Copy edges from BB into its copy constructed earlier, scale profile
1891*e4b17023SJohn Marino    accordingly.  Edges will be taken care of later.  Assume aux
1892*e4b17023SJohn Marino    pointers to point to the copies of each BB.  Return true if any
1893*e4b17023SJohn Marino    debug stmts are left after a statement that must end the basic block.  */
1894*e4b17023SJohn Marino 
1895*e4b17023SJohn Marino static bool
1896*e4b17023SJohn Marino copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
1897*e4b17023SJohn Marino {
1898*e4b17023SJohn Marino   basic_block new_bb = (basic_block) bb->aux;
1899*e4b17023SJohn Marino   edge_iterator ei;
1900*e4b17023SJohn Marino   edge old_edge;
1901*e4b17023SJohn Marino   gimple_stmt_iterator si;
1902*e4b17023SJohn Marino   int flags;
1903*e4b17023SJohn Marino   bool need_debug_cleanup = false;
1904*e4b17023SJohn Marino 
1905*e4b17023SJohn Marino   /* Use the indices from the original blocks to create edges for the
1906*e4b17023SJohn Marino      new ones.  */
1907*e4b17023SJohn Marino   FOR_EACH_EDGE (old_edge, ei, bb->succs)
1908*e4b17023SJohn Marino     if (!(old_edge->flags & EDGE_EH))
1909*e4b17023SJohn Marino       {
1910*e4b17023SJohn Marino 	edge new_edge;
1911*e4b17023SJohn Marino 
1912*e4b17023SJohn Marino 	flags = old_edge->flags;
1913*e4b17023SJohn Marino 
1914*e4b17023SJohn Marino 	/* Return edges do get a FALLTHRU flag when the get inlined.  */
1915*e4b17023SJohn Marino 	if (old_edge->dest->index == EXIT_BLOCK && !old_edge->flags
1916*e4b17023SJohn Marino 	    && old_edge->dest->aux != EXIT_BLOCK_PTR)
1917*e4b17023SJohn Marino 	  flags |= EDGE_FALLTHRU;
1918*e4b17023SJohn Marino 	new_edge = make_edge (new_bb, (basic_block) old_edge->dest->aux, flags);
1919*e4b17023SJohn Marino 	new_edge->count = old_edge->count * count_scale / REG_BR_PROB_BASE;
1920*e4b17023SJohn Marino 	new_edge->probability = old_edge->probability;
1921*e4b17023SJohn Marino       }
1922*e4b17023SJohn Marino 
1923*e4b17023SJohn Marino   if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
1924*e4b17023SJohn Marino     return false;
1925*e4b17023SJohn Marino 
1926*e4b17023SJohn Marino   for (si = gsi_start_bb (new_bb); !gsi_end_p (si);)
1927*e4b17023SJohn Marino     {
1928*e4b17023SJohn Marino       gimple copy_stmt;
1929*e4b17023SJohn Marino       bool can_throw, nonlocal_goto;
1930*e4b17023SJohn Marino 
1931*e4b17023SJohn Marino       copy_stmt = gsi_stmt (si);
1932*e4b17023SJohn Marino       if (!is_gimple_debug (copy_stmt))
1933*e4b17023SJohn Marino 	{
1934*e4b17023SJohn Marino 	  update_stmt (copy_stmt);
1935*e4b17023SJohn Marino 	  if (gimple_in_ssa_p (cfun))
1936*e4b17023SJohn Marino 	    mark_symbols_for_renaming (copy_stmt);
1937*e4b17023SJohn Marino 	}
1938*e4b17023SJohn Marino 
1939*e4b17023SJohn Marino       /* Do this before the possible split_block.  */
1940*e4b17023SJohn Marino       gsi_next (&si);
1941*e4b17023SJohn Marino 
1942*e4b17023SJohn Marino       /* If this tree could throw an exception, there are two
1943*e4b17023SJohn Marino          cases where we need to add abnormal edge(s): the
1944*e4b17023SJohn Marino          tree wasn't in a region and there is a "current
1945*e4b17023SJohn Marino          region" in the caller; or the original tree had
1946*e4b17023SJohn Marino          EH edges.  In both cases split the block after the tree,
1947*e4b17023SJohn Marino          and add abnormal edge(s) as needed; we need both
1948*e4b17023SJohn Marino          those from the callee and the caller.
1949*e4b17023SJohn Marino          We check whether the copy can throw, because the const
1950*e4b17023SJohn Marino          propagation can change an INDIRECT_REF which throws
1951*e4b17023SJohn Marino          into a COMPONENT_REF which doesn't.  If the copy
1952*e4b17023SJohn Marino          can throw, the original could also throw.  */
1953*e4b17023SJohn Marino       can_throw = stmt_can_throw_internal (copy_stmt);
1954*e4b17023SJohn Marino       nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt);
1955*e4b17023SJohn Marino 
1956*e4b17023SJohn Marino       if (can_throw || nonlocal_goto)
1957*e4b17023SJohn Marino 	{
1958*e4b17023SJohn Marino 	  if (!gsi_end_p (si))
1959*e4b17023SJohn Marino 	    {
1960*e4b17023SJohn Marino 	      while (!gsi_end_p (si) && is_gimple_debug (gsi_stmt (si)))
1961*e4b17023SJohn Marino 		gsi_next (&si);
1962*e4b17023SJohn Marino 	      if (gsi_end_p (si))
1963*e4b17023SJohn Marino 		need_debug_cleanup = true;
1964*e4b17023SJohn Marino 	    }
1965*e4b17023SJohn Marino 	  if (!gsi_end_p (si))
1966*e4b17023SJohn Marino 	    /* Note that bb's predecessor edges aren't necessarily
1967*e4b17023SJohn Marino 	       right at this point; split_block doesn't care.  */
1968*e4b17023SJohn Marino 	    {
1969*e4b17023SJohn Marino 	      edge e = split_block (new_bb, copy_stmt);
1970*e4b17023SJohn Marino 
1971*e4b17023SJohn Marino 	      new_bb = e->dest;
1972*e4b17023SJohn Marino 	      new_bb->aux = e->src->aux;
1973*e4b17023SJohn Marino 	      si = gsi_start_bb (new_bb);
1974*e4b17023SJohn Marino 	    }
1975*e4b17023SJohn Marino 	}
1976*e4b17023SJohn Marino 
1977*e4b17023SJohn Marino       if (gimple_code (copy_stmt) == GIMPLE_EH_DISPATCH)
1978*e4b17023SJohn Marino 	make_eh_dispatch_edges (copy_stmt);
1979*e4b17023SJohn Marino       else if (can_throw)
1980*e4b17023SJohn Marino 	make_eh_edges (copy_stmt);
1981*e4b17023SJohn Marino 
1982*e4b17023SJohn Marino       if (nonlocal_goto)
1983*e4b17023SJohn Marino 	make_abnormal_goto_edges (gimple_bb (copy_stmt), true);
1984*e4b17023SJohn Marino 
1985*e4b17023SJohn Marino       if ((can_throw || nonlocal_goto)
1986*e4b17023SJohn Marino 	  && gimple_in_ssa_p (cfun))
1987*e4b17023SJohn Marino 	update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb,
1988*e4b17023SJohn Marino 					  can_throw, nonlocal_goto);
1989*e4b17023SJohn Marino     }
1990*e4b17023SJohn Marino   return need_debug_cleanup;
1991*e4b17023SJohn Marino }
1992*e4b17023SJohn Marino 
1993*e4b17023SJohn Marino /* Copy the PHIs.  All blocks and edges are copied, some blocks
1994*e4b17023SJohn Marino    was possibly split and new outgoing EH edges inserted.
1995*e4b17023SJohn Marino    BB points to the block of original function and AUX pointers links
1996*e4b17023SJohn Marino    the original and newly copied blocks.  */
1997*e4b17023SJohn Marino 
1998*e4b17023SJohn Marino static void
1999*e4b17023SJohn Marino copy_phis_for_bb (basic_block bb, copy_body_data *id)
2000*e4b17023SJohn Marino {
2001*e4b17023SJohn Marino   basic_block const new_bb = (basic_block) bb->aux;
2002*e4b17023SJohn Marino   edge_iterator ei;
2003*e4b17023SJohn Marino   gimple phi;
2004*e4b17023SJohn Marino   gimple_stmt_iterator si;
2005*e4b17023SJohn Marino   edge new_edge;
2006*e4b17023SJohn Marino   bool inserted = false;
2007*e4b17023SJohn Marino 
2008*e4b17023SJohn Marino   for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si))
2009*e4b17023SJohn Marino     {
2010*e4b17023SJohn Marino       tree res, new_res;
2011*e4b17023SJohn Marino       gimple new_phi;
2012*e4b17023SJohn Marino 
2013*e4b17023SJohn Marino       phi = gsi_stmt (si);
2014*e4b17023SJohn Marino       res = PHI_RESULT (phi);
2015*e4b17023SJohn Marino       new_res = res;
2016*e4b17023SJohn Marino       if (is_gimple_reg (res))
2017*e4b17023SJohn Marino 	{
2018*e4b17023SJohn Marino 	  walk_tree (&new_res, copy_tree_body_r, id, NULL);
2019*e4b17023SJohn Marino 	  SSA_NAME_DEF_STMT (new_res)
2020*e4b17023SJohn Marino 	    = new_phi = create_phi_node (new_res, new_bb);
2021*e4b17023SJohn Marino 	  FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
2022*e4b17023SJohn Marino 	    {
2023*e4b17023SJohn Marino 	      edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
2024*e4b17023SJohn Marino 	      tree arg;
2025*e4b17023SJohn Marino 	      tree new_arg;
2026*e4b17023SJohn Marino 	      tree block = id->block;
2027*e4b17023SJohn Marino 	      edge_iterator ei2;
2028*e4b17023SJohn Marino 
2029*e4b17023SJohn Marino 	      /* When doing partial cloning, we allow PHIs on the entry block
2030*e4b17023SJohn Marino 		 as long as all the arguments are the same.  Find any input
2031*e4b17023SJohn Marino 		 edge to see argument to copy.  */
2032*e4b17023SJohn Marino 	      if (!old_edge)
2033*e4b17023SJohn Marino 		FOR_EACH_EDGE (old_edge, ei2, bb->preds)
2034*e4b17023SJohn Marino 		  if (!old_edge->src->aux)
2035*e4b17023SJohn Marino 		    break;
2036*e4b17023SJohn Marino 
2037*e4b17023SJohn Marino 	      arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
2038*e4b17023SJohn Marino 	      new_arg = arg;
2039*e4b17023SJohn Marino 	      id->block = NULL_TREE;
2040*e4b17023SJohn Marino 	      walk_tree (&new_arg, copy_tree_body_r, id, NULL);
2041*e4b17023SJohn Marino 	      id->block = block;
2042*e4b17023SJohn Marino 	      gcc_assert (new_arg);
2043*e4b17023SJohn Marino 	      /* With return slot optimization we can end up with
2044*e4b17023SJohn Marino 	         non-gimple (foo *)&this->m, fix that here.  */
2045*e4b17023SJohn Marino 	      if (TREE_CODE (new_arg) != SSA_NAME
2046*e4b17023SJohn Marino 		  && TREE_CODE (new_arg) != FUNCTION_DECL
2047*e4b17023SJohn Marino 		  && !is_gimple_val (new_arg))
2048*e4b17023SJohn Marino 		{
2049*e4b17023SJohn Marino 		  gimple_seq stmts = NULL;
2050*e4b17023SJohn Marino 		  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
2051*e4b17023SJohn Marino 		  gsi_insert_seq_on_edge (new_edge, stmts);
2052*e4b17023SJohn Marino 		  inserted = true;
2053*e4b17023SJohn Marino 		}
2054*e4b17023SJohn Marino 	      add_phi_arg (new_phi, new_arg, new_edge,
2055*e4b17023SJohn Marino 			   gimple_phi_arg_location_from_edge (phi, old_edge));
2056*e4b17023SJohn Marino 	    }
2057*e4b17023SJohn Marino 	}
2058*e4b17023SJohn Marino     }
2059*e4b17023SJohn Marino 
2060*e4b17023SJohn Marino   /* Commit the delayed edge insertions.  */
2061*e4b17023SJohn Marino   if (inserted)
2062*e4b17023SJohn Marino     FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
2063*e4b17023SJohn Marino       gsi_commit_one_edge_insert (new_edge, NULL);
2064*e4b17023SJohn Marino }
2065*e4b17023SJohn Marino 
2066*e4b17023SJohn Marino 
2067*e4b17023SJohn Marino /* Wrapper for remap_decl so it can be used as a callback.  */
2068*e4b17023SJohn Marino 
2069*e4b17023SJohn Marino static tree
2070*e4b17023SJohn Marino remap_decl_1 (tree decl, void *data)
2071*e4b17023SJohn Marino {
2072*e4b17023SJohn Marino   return remap_decl (decl, (copy_body_data *) data);
2073*e4b17023SJohn Marino }
2074*e4b17023SJohn Marino 
2075*e4b17023SJohn Marino /* Build struct function and associated datastructures for the new clone
2076*e4b17023SJohn Marino    NEW_FNDECL to be build.  CALLEE_FNDECL is the original */
2077*e4b17023SJohn Marino 
2078*e4b17023SJohn Marino static void
2079*e4b17023SJohn Marino initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
2080*e4b17023SJohn Marino {
2081*e4b17023SJohn Marino   struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
2082*e4b17023SJohn Marino   gcov_type count_scale;
2083*e4b17023SJohn Marino 
2084*e4b17023SJohn Marino   if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
2085*e4b17023SJohn Marino     count_scale = (REG_BR_PROB_BASE * count
2086*e4b17023SJohn Marino 		   / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count);
2087*e4b17023SJohn Marino   else
2088*e4b17023SJohn Marino     count_scale = REG_BR_PROB_BASE;
2089*e4b17023SJohn Marino 
2090*e4b17023SJohn Marino   /* Register specific tree functions.  */
2091*e4b17023SJohn Marino   gimple_register_cfg_hooks ();
2092*e4b17023SJohn Marino 
2093*e4b17023SJohn Marino   /* Get clean struct function.  */
2094*e4b17023SJohn Marino   push_struct_function (new_fndecl);
2095*e4b17023SJohn Marino 
2096*e4b17023SJohn Marino   /* We will rebuild these, so just sanity check that they are empty.  */
2097*e4b17023SJohn Marino   gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL);
2098*e4b17023SJohn Marino   gcc_assert (cfun->local_decls == NULL);
2099*e4b17023SJohn Marino   gcc_assert (cfun->cfg == NULL);
2100*e4b17023SJohn Marino   gcc_assert (cfun->decl == new_fndecl);
2101*e4b17023SJohn Marino 
2102*e4b17023SJohn Marino   /* Copy items we preserve during cloning.  */
2103*e4b17023SJohn Marino   cfun->static_chain_decl = src_cfun->static_chain_decl;
2104*e4b17023SJohn Marino   cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
2105*e4b17023SJohn Marino   cfun->function_end_locus = src_cfun->function_end_locus;
2106*e4b17023SJohn Marino   cfun->curr_properties = src_cfun->curr_properties;
2107*e4b17023SJohn Marino   cfun->last_verified = src_cfun->last_verified;
2108*e4b17023SJohn Marino   cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
2109*e4b17023SJohn Marino   cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
2110*e4b17023SJohn Marino   cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
2111*e4b17023SJohn Marino   cfun->stdarg = src_cfun->stdarg;
2112*e4b17023SJohn Marino   cfun->after_inlining = src_cfun->after_inlining;
2113*e4b17023SJohn Marino   cfun->can_throw_non_call_exceptions
2114*e4b17023SJohn Marino     = src_cfun->can_throw_non_call_exceptions;
2115*e4b17023SJohn Marino   cfun->returns_struct = src_cfun->returns_struct;
2116*e4b17023SJohn Marino   cfun->returns_pcc_struct = src_cfun->returns_pcc_struct;
2117*e4b17023SJohn Marino   cfun->after_tree_profile = src_cfun->after_tree_profile;
2118*e4b17023SJohn Marino 
2119*e4b17023SJohn Marino   init_empty_tree_cfg ();
2120*e4b17023SJohn Marino 
2121*e4b17023SJohn Marino   profile_status_for_function (cfun) = profile_status_for_function (src_cfun);
2122*e4b17023SJohn Marino   ENTRY_BLOCK_PTR->count =
2123*e4b17023SJohn Marino     (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale /
2124*e4b17023SJohn Marino      REG_BR_PROB_BASE);
2125*e4b17023SJohn Marino   ENTRY_BLOCK_PTR->frequency
2126*e4b17023SJohn Marino     = ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency;
2127*e4b17023SJohn Marino   EXIT_BLOCK_PTR->count =
2128*e4b17023SJohn Marino     (EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale /
2129*e4b17023SJohn Marino      REG_BR_PROB_BASE);
2130*e4b17023SJohn Marino   EXIT_BLOCK_PTR->frequency =
2131*e4b17023SJohn Marino     EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency;
2132*e4b17023SJohn Marino   if (src_cfun->eh)
2133*e4b17023SJohn Marino     init_eh_for_function ();
2134*e4b17023SJohn Marino 
2135*e4b17023SJohn Marino   if (src_cfun->gimple_df)
2136*e4b17023SJohn Marino     {
2137*e4b17023SJohn Marino       init_tree_ssa (cfun);
2138*e4b17023SJohn Marino       cfun->gimple_df->in_ssa_p = true;
2139*e4b17023SJohn Marino       init_ssa_operands ();
2140*e4b17023SJohn Marino     }
2141*e4b17023SJohn Marino   pop_cfun ();
2142*e4b17023SJohn Marino }
2143*e4b17023SJohn Marino 
2144*e4b17023SJohn Marino /* Helper function for copy_cfg_body.  Move debug stmts from the end
2145*e4b17023SJohn Marino    of NEW_BB to the beginning of successor basic blocks when needed.  If the
2146*e4b17023SJohn Marino    successor has multiple predecessors, reset them, otherwise keep
2147*e4b17023SJohn Marino    their value.  */
2148*e4b17023SJohn Marino 
2149*e4b17023SJohn Marino static void
2150*e4b17023SJohn Marino maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
2151*e4b17023SJohn Marino {
2152*e4b17023SJohn Marino   edge e;
2153*e4b17023SJohn Marino   edge_iterator ei;
2154*e4b17023SJohn Marino   gimple_stmt_iterator si = gsi_last_nondebug_bb (new_bb);
2155*e4b17023SJohn Marino 
2156*e4b17023SJohn Marino   if (gsi_end_p (si)
2157*e4b17023SJohn Marino       || gsi_one_before_end_p (si)
2158*e4b17023SJohn Marino       || !(stmt_can_throw_internal (gsi_stmt (si))
2159*e4b17023SJohn Marino 	   || stmt_can_make_abnormal_goto (gsi_stmt (si))))
2160*e4b17023SJohn Marino     return;
2161*e4b17023SJohn Marino 
2162*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, new_bb->succs)
2163*e4b17023SJohn Marino     {
2164*e4b17023SJohn Marino       gimple_stmt_iterator ssi = gsi_last_bb (new_bb);
2165*e4b17023SJohn Marino       gimple_stmt_iterator dsi = gsi_after_labels (e->dest);
2166*e4b17023SJohn Marino       while (is_gimple_debug (gsi_stmt (ssi)))
2167*e4b17023SJohn Marino 	{
2168*e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (ssi), new_stmt;
2169*e4b17023SJohn Marino 	  tree var;
2170*e4b17023SJohn Marino 	  tree value;
2171*e4b17023SJohn Marino 
2172*e4b17023SJohn Marino 	  /* For the last edge move the debug stmts instead of copying
2173*e4b17023SJohn Marino 	     them.  */
2174*e4b17023SJohn Marino 	  if (ei_one_before_end_p (ei))
2175*e4b17023SJohn Marino 	    {
2176*e4b17023SJohn Marino 	      si = ssi;
2177*e4b17023SJohn Marino 	      gsi_prev (&ssi);
2178*e4b17023SJohn Marino 	      if (!single_pred_p (e->dest) && gimple_debug_bind_p (stmt))
2179*e4b17023SJohn Marino 		gimple_debug_bind_reset_value (stmt);
2180*e4b17023SJohn Marino 	      gsi_remove (&si, false);
2181*e4b17023SJohn Marino 	      gsi_insert_before (&dsi, stmt, GSI_SAME_STMT);
2182*e4b17023SJohn Marino 	      continue;
2183*e4b17023SJohn Marino 	    }
2184*e4b17023SJohn Marino 
2185*e4b17023SJohn Marino 	  if (gimple_debug_bind_p (stmt))
2186*e4b17023SJohn Marino 	    {
2187*e4b17023SJohn Marino 	      var = gimple_debug_bind_get_var (stmt);
2188*e4b17023SJohn Marino 	      if (single_pred_p (e->dest))
2189*e4b17023SJohn Marino 		{
2190*e4b17023SJohn Marino 		  value = gimple_debug_bind_get_value (stmt);
2191*e4b17023SJohn Marino 		  value = unshare_expr (value);
2192*e4b17023SJohn Marino 		}
2193*e4b17023SJohn Marino 	      else
2194*e4b17023SJohn Marino 		value = NULL_TREE;
2195*e4b17023SJohn Marino 	      new_stmt = gimple_build_debug_bind (var, value, stmt);
2196*e4b17023SJohn Marino 	    }
2197*e4b17023SJohn Marino 	  else if (gimple_debug_source_bind_p (stmt))
2198*e4b17023SJohn Marino 	    {
2199*e4b17023SJohn Marino 	      var = gimple_debug_source_bind_get_var (stmt);
2200*e4b17023SJohn Marino 	      value = gimple_debug_source_bind_get_value (stmt);
2201*e4b17023SJohn Marino 	      new_stmt = gimple_build_debug_source_bind (var, value, stmt);
2202*e4b17023SJohn Marino 	    }
2203*e4b17023SJohn Marino 	  else
2204*e4b17023SJohn Marino 	    gcc_unreachable ();
2205*e4b17023SJohn Marino 	  gsi_insert_before (&dsi, new_stmt, GSI_SAME_STMT);
2206*e4b17023SJohn Marino 	  VEC_safe_push (gimple, heap, id->debug_stmts, new_stmt);
2207*e4b17023SJohn Marino 	  gsi_prev (&ssi);
2208*e4b17023SJohn Marino 	}
2209*e4b17023SJohn Marino     }
2210*e4b17023SJohn Marino }
2211*e4b17023SJohn Marino 
2212*e4b17023SJohn Marino /* Make a copy of the body of FN so that it can be inserted inline in
2213*e4b17023SJohn Marino    another function.  Walks FN via CFG, returns new fndecl.  */
2214*e4b17023SJohn Marino 
2215*e4b17023SJohn Marino static tree
2216*e4b17023SJohn Marino copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
2217*e4b17023SJohn Marino 	       basic_block entry_block_map, basic_block exit_block_map,
2218*e4b17023SJohn Marino 	       bitmap blocks_to_copy, basic_block new_entry)
2219*e4b17023SJohn Marino {
2220*e4b17023SJohn Marino   tree callee_fndecl = id->src_fn;
2221*e4b17023SJohn Marino   /* Original cfun for the callee, doesn't change.  */
2222*e4b17023SJohn Marino   struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
2223*e4b17023SJohn Marino   struct function *cfun_to_copy;
2224*e4b17023SJohn Marino   basic_block bb;
2225*e4b17023SJohn Marino   tree new_fndecl = NULL;
2226*e4b17023SJohn Marino   bool need_debug_cleanup = false;
2227*e4b17023SJohn Marino   gcov_type count_scale;
2228*e4b17023SJohn Marino   int last;
2229*e4b17023SJohn Marino   int incoming_frequency = 0;
2230*e4b17023SJohn Marino   gcov_type incoming_count = 0;
2231*e4b17023SJohn Marino 
2232*e4b17023SJohn Marino   if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count)
2233*e4b17023SJohn Marino     count_scale = (REG_BR_PROB_BASE * count
2234*e4b17023SJohn Marino 		   / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count);
2235*e4b17023SJohn Marino   else
2236*e4b17023SJohn Marino     count_scale = REG_BR_PROB_BASE;
2237*e4b17023SJohn Marino 
2238*e4b17023SJohn Marino   /* Register specific tree functions.  */
2239*e4b17023SJohn Marino   gimple_register_cfg_hooks ();
2240*e4b17023SJohn Marino 
2241*e4b17023SJohn Marino   /* If we are inlining just region of the function, make sure to connect new entry
2242*e4b17023SJohn Marino      to ENTRY_BLOCK_PTR.  Since new entry can be part of loop, we must compute
2243*e4b17023SJohn Marino      frequency and probability of ENTRY_BLOCK_PTR based on the frequencies and
2244*e4b17023SJohn Marino      probabilities of edges incoming from nonduplicated region.  */
2245*e4b17023SJohn Marino   if (new_entry)
2246*e4b17023SJohn Marino     {
2247*e4b17023SJohn Marino       edge e;
2248*e4b17023SJohn Marino       edge_iterator ei;
2249*e4b17023SJohn Marino 
2250*e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, new_entry->preds)
2251*e4b17023SJohn Marino 	if (!e->src->aux)
2252*e4b17023SJohn Marino 	  {
2253*e4b17023SJohn Marino 	    incoming_frequency += EDGE_FREQUENCY (e);
2254*e4b17023SJohn Marino 	    incoming_count += e->count;
2255*e4b17023SJohn Marino 	  }
2256*e4b17023SJohn Marino       incoming_count = incoming_count * count_scale / REG_BR_PROB_BASE;
2257*e4b17023SJohn Marino       incoming_frequency
2258*e4b17023SJohn Marino 	= incoming_frequency * frequency_scale / REG_BR_PROB_BASE;
2259*e4b17023SJohn Marino       ENTRY_BLOCK_PTR->count = incoming_count;
2260*e4b17023SJohn Marino       ENTRY_BLOCK_PTR->frequency = incoming_frequency;
2261*e4b17023SJohn Marino     }
2262*e4b17023SJohn Marino 
2263*e4b17023SJohn Marino   /* Must have a CFG here at this point.  */
2264*e4b17023SJohn Marino   gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION
2265*e4b17023SJohn Marino 	      (DECL_STRUCT_FUNCTION (callee_fndecl)));
2266*e4b17023SJohn Marino 
2267*e4b17023SJohn Marino   cfun_to_copy = id->src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
2268*e4b17023SJohn Marino 
2269*e4b17023SJohn Marino   ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = entry_block_map;
2270*e4b17023SJohn Marino   EXIT_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = exit_block_map;
2271*e4b17023SJohn Marino   entry_block_map->aux = ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy);
2272*e4b17023SJohn Marino   exit_block_map->aux = EXIT_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy);
2273*e4b17023SJohn Marino 
2274*e4b17023SJohn Marino   /* Duplicate any exception-handling regions.  */
2275*e4b17023SJohn Marino   if (cfun->eh)
2276*e4b17023SJohn Marino     id->eh_map = duplicate_eh_regions (cfun_to_copy, NULL, id->eh_lp_nr,
2277*e4b17023SJohn Marino 				       remap_decl_1, id);
2278*e4b17023SJohn Marino 
2279*e4b17023SJohn Marino   /* Use aux pointers to map the original blocks to copy.  */
2280*e4b17023SJohn Marino   FOR_EACH_BB_FN (bb, cfun_to_copy)
2281*e4b17023SJohn Marino     if (!blocks_to_copy || bitmap_bit_p (blocks_to_copy, bb->index))
2282*e4b17023SJohn Marino       {
2283*e4b17023SJohn Marino 	basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale);
2284*e4b17023SJohn Marino 	bb->aux = new_bb;
2285*e4b17023SJohn Marino 	new_bb->aux = bb;
2286*e4b17023SJohn Marino       }
2287*e4b17023SJohn Marino 
2288*e4b17023SJohn Marino   last = last_basic_block;
2289*e4b17023SJohn Marino 
2290*e4b17023SJohn Marino   /* Now that we've duplicated the blocks, duplicate their edges.  */
2291*e4b17023SJohn Marino   FOR_ALL_BB_FN (bb, cfun_to_copy)
2292*e4b17023SJohn Marino     if (!blocks_to_copy
2293*e4b17023SJohn Marino         || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index)))
2294*e4b17023SJohn Marino       need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map);
2295*e4b17023SJohn Marino 
2296*e4b17023SJohn Marino   if (new_entry)
2297*e4b17023SJohn Marino     {
2298*e4b17023SJohn Marino       edge e = make_edge (entry_block_map, (basic_block)new_entry->aux, EDGE_FALLTHRU);
2299*e4b17023SJohn Marino       e->probability = REG_BR_PROB_BASE;
2300*e4b17023SJohn Marino       e->count = incoming_count;
2301*e4b17023SJohn Marino     }
2302*e4b17023SJohn Marino 
2303*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun))
2304*e4b17023SJohn Marino     FOR_ALL_BB_FN (bb, cfun_to_copy)
2305*e4b17023SJohn Marino       if (!blocks_to_copy
2306*e4b17023SJohn Marino 	  || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index)))
2307*e4b17023SJohn Marino 	copy_phis_for_bb (bb, id);
2308*e4b17023SJohn Marino 
2309*e4b17023SJohn Marino   FOR_ALL_BB_FN (bb, cfun_to_copy)
2310*e4b17023SJohn Marino     if (bb->aux)
2311*e4b17023SJohn Marino       {
2312*e4b17023SJohn Marino 	if (need_debug_cleanup
2313*e4b17023SJohn Marino 	    && bb->index != ENTRY_BLOCK
2314*e4b17023SJohn Marino 	    && bb->index != EXIT_BLOCK)
2315*e4b17023SJohn Marino 	  maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux);
2316*e4b17023SJohn Marino 	((basic_block)bb->aux)->aux = NULL;
2317*e4b17023SJohn Marino 	bb->aux = NULL;
2318*e4b17023SJohn Marino       }
2319*e4b17023SJohn Marino 
2320*e4b17023SJohn Marino   /* Zero out AUX fields of newly created block during EH edge
2321*e4b17023SJohn Marino      insertion. */
2322*e4b17023SJohn Marino   for (; last < last_basic_block; last++)
2323*e4b17023SJohn Marino     {
2324*e4b17023SJohn Marino       if (need_debug_cleanup)
2325*e4b17023SJohn Marino 	maybe_move_debug_stmts_to_successors (id, BASIC_BLOCK (last));
2326*e4b17023SJohn Marino       BASIC_BLOCK (last)->aux = NULL;
2327*e4b17023SJohn Marino     }
2328*e4b17023SJohn Marino   entry_block_map->aux = NULL;
2329*e4b17023SJohn Marino   exit_block_map->aux = NULL;
2330*e4b17023SJohn Marino 
2331*e4b17023SJohn Marino   if (id->eh_map)
2332*e4b17023SJohn Marino     {
2333*e4b17023SJohn Marino       pointer_map_destroy (id->eh_map);
2334*e4b17023SJohn Marino       id->eh_map = NULL;
2335*e4b17023SJohn Marino     }
2336*e4b17023SJohn Marino 
2337*e4b17023SJohn Marino   return new_fndecl;
2338*e4b17023SJohn Marino }
2339*e4b17023SJohn Marino 
2340*e4b17023SJohn Marino /* Copy the debug STMT using ID.  We deal with these statements in a
2341*e4b17023SJohn Marino    special way: if any variable in their VALUE expression wasn't
2342*e4b17023SJohn Marino    remapped yet, we won't remap it, because that would get decl uids
2343*e4b17023SJohn Marino    out of sync, causing codegen differences between -g and -g0.  If
2344*e4b17023SJohn Marino    this arises, we drop the VALUE expression altogether.  */
2345*e4b17023SJohn Marino 
2346*e4b17023SJohn Marino static void
2347*e4b17023SJohn Marino copy_debug_stmt (gimple stmt, copy_body_data *id)
2348*e4b17023SJohn Marino {
2349*e4b17023SJohn Marino   tree t, *n;
2350*e4b17023SJohn Marino   struct walk_stmt_info wi;
2351*e4b17023SJohn Marino 
2352*e4b17023SJohn Marino   t = id->block;
2353*e4b17023SJohn Marino   if (gimple_block (stmt))
2354*e4b17023SJohn Marino     {
2355*e4b17023SJohn Marino       n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt));
2356*e4b17023SJohn Marino       if (n)
2357*e4b17023SJohn Marino 	t = *n;
2358*e4b17023SJohn Marino     }
2359*e4b17023SJohn Marino   gimple_set_block (stmt, t);
2360*e4b17023SJohn Marino 
2361*e4b17023SJohn Marino   /* Remap all the operands in COPY.  */
2362*e4b17023SJohn Marino   memset (&wi, 0, sizeof (wi));
2363*e4b17023SJohn Marino   wi.info = id;
2364*e4b17023SJohn Marino 
2365*e4b17023SJohn Marino   processing_debug_stmt = 1;
2366*e4b17023SJohn Marino 
2367*e4b17023SJohn Marino   if (gimple_debug_source_bind_p (stmt))
2368*e4b17023SJohn Marino     t = gimple_debug_source_bind_get_var (stmt);
2369*e4b17023SJohn Marino   else
2370*e4b17023SJohn Marino     t = gimple_debug_bind_get_var (stmt);
2371*e4b17023SJohn Marino 
2372*e4b17023SJohn Marino   if (TREE_CODE (t) == PARM_DECL && id->debug_map
2373*e4b17023SJohn Marino       && (n = (tree *) pointer_map_contains (id->debug_map, t)))
2374*e4b17023SJohn Marino     {
2375*e4b17023SJohn Marino       gcc_assert (TREE_CODE (*n) == VAR_DECL);
2376*e4b17023SJohn Marino       t = *n;
2377*e4b17023SJohn Marino     }
2378*e4b17023SJohn Marino   else if (TREE_CODE (t) == VAR_DECL
2379*e4b17023SJohn Marino 	   && !TREE_STATIC (t)
2380*e4b17023SJohn Marino 	   && gimple_in_ssa_p (cfun)
2381*e4b17023SJohn Marino 	   && !pointer_map_contains (id->decl_map, t)
2382*e4b17023SJohn Marino 	   && !var_ann (t))
2383*e4b17023SJohn Marino     /* T is a non-localized variable.  */;
2384*e4b17023SJohn Marino   else
2385*e4b17023SJohn Marino     walk_tree (&t, remap_gimple_op_r, &wi, NULL);
2386*e4b17023SJohn Marino 
2387*e4b17023SJohn Marino   if (gimple_debug_bind_p (stmt))
2388*e4b17023SJohn Marino     {
2389*e4b17023SJohn Marino       gimple_debug_bind_set_var (stmt, t);
2390*e4b17023SJohn Marino 
2391*e4b17023SJohn Marino       if (gimple_debug_bind_has_value_p (stmt))
2392*e4b17023SJohn Marino 	walk_tree (gimple_debug_bind_get_value_ptr (stmt),
2393*e4b17023SJohn Marino 		   remap_gimple_op_r, &wi, NULL);
2394*e4b17023SJohn Marino 
2395*e4b17023SJohn Marino       /* Punt if any decl couldn't be remapped.  */
2396*e4b17023SJohn Marino       if (processing_debug_stmt < 0)
2397*e4b17023SJohn Marino 	gimple_debug_bind_reset_value (stmt);
2398*e4b17023SJohn Marino     }
2399*e4b17023SJohn Marino   else if (gimple_debug_source_bind_p (stmt))
2400*e4b17023SJohn Marino     {
2401*e4b17023SJohn Marino       gimple_debug_source_bind_set_var (stmt, t);
2402*e4b17023SJohn Marino       walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
2403*e4b17023SJohn Marino 		 remap_gimple_op_r, &wi, NULL);
2404*e4b17023SJohn Marino     }
2405*e4b17023SJohn Marino 
2406*e4b17023SJohn Marino   processing_debug_stmt = 0;
2407*e4b17023SJohn Marino 
2408*e4b17023SJohn Marino   update_stmt (stmt);
2409*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun))
2410*e4b17023SJohn Marino     mark_symbols_for_renaming (stmt);
2411*e4b17023SJohn Marino }
2412*e4b17023SJohn Marino 
2413*e4b17023SJohn Marino /* Process deferred debug stmts.  In order to give values better odds
2414*e4b17023SJohn Marino    of being successfully remapped, we delay the processing of debug
2415*e4b17023SJohn Marino    stmts until all other stmts that might require remapping are
2416*e4b17023SJohn Marino    processed.  */
2417*e4b17023SJohn Marino 
2418*e4b17023SJohn Marino static void
2419*e4b17023SJohn Marino copy_debug_stmts (copy_body_data *id)
2420*e4b17023SJohn Marino {
2421*e4b17023SJohn Marino   size_t i;
2422*e4b17023SJohn Marino   gimple stmt;
2423*e4b17023SJohn Marino 
2424*e4b17023SJohn Marino   if (!id->debug_stmts)
2425*e4b17023SJohn Marino     return;
2426*e4b17023SJohn Marino 
2427*e4b17023SJohn Marino   FOR_EACH_VEC_ELT (gimple, id->debug_stmts, i, stmt)
2428*e4b17023SJohn Marino     copy_debug_stmt (stmt, id);
2429*e4b17023SJohn Marino 
2430*e4b17023SJohn Marino   VEC_free (gimple, heap, id->debug_stmts);
2431*e4b17023SJohn Marino }
2432*e4b17023SJohn Marino 
2433*e4b17023SJohn Marino /* Make a copy of the body of SRC_FN so that it can be inserted inline in
2434*e4b17023SJohn Marino    another function.  */
2435*e4b17023SJohn Marino 
2436*e4b17023SJohn Marino static tree
2437*e4b17023SJohn Marino copy_tree_body (copy_body_data *id)
2438*e4b17023SJohn Marino {
2439*e4b17023SJohn Marino   tree fndecl = id->src_fn;
2440*e4b17023SJohn Marino   tree body = DECL_SAVED_TREE (fndecl);
2441*e4b17023SJohn Marino 
2442*e4b17023SJohn Marino   walk_tree (&body, copy_tree_body_r, id, NULL);
2443*e4b17023SJohn Marino 
2444*e4b17023SJohn Marino   return body;
2445*e4b17023SJohn Marino }
2446*e4b17023SJohn Marino 
2447*e4b17023SJohn Marino /* Make a copy of the body of FN so that it can be inserted inline in
2448*e4b17023SJohn Marino    another function.  */
2449*e4b17023SJohn Marino 
2450*e4b17023SJohn Marino static tree
2451*e4b17023SJohn Marino copy_body (copy_body_data *id, gcov_type count, int frequency_scale,
2452*e4b17023SJohn Marino 	   basic_block entry_block_map, basic_block exit_block_map,
2453*e4b17023SJohn Marino 	   bitmap blocks_to_copy, basic_block new_entry)
2454*e4b17023SJohn Marino {
2455*e4b17023SJohn Marino   tree fndecl = id->src_fn;
2456*e4b17023SJohn Marino   tree body;
2457*e4b17023SJohn Marino 
2458*e4b17023SJohn Marino   /* If this body has a CFG, walk CFG and copy.  */
2459*e4b17023SJohn Marino   gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (fndecl)));
2460*e4b17023SJohn Marino   body = copy_cfg_body (id, count, frequency_scale, entry_block_map, exit_block_map,
2461*e4b17023SJohn Marino 		        blocks_to_copy, new_entry);
2462*e4b17023SJohn Marino   copy_debug_stmts (id);
2463*e4b17023SJohn Marino 
2464*e4b17023SJohn Marino   return body;
2465*e4b17023SJohn Marino }
2466*e4b17023SJohn Marino 
2467*e4b17023SJohn Marino /* Return true if VALUE is an ADDR_EXPR of an automatic variable
2468*e4b17023SJohn Marino    defined in function FN, or of a data member thereof.  */
2469*e4b17023SJohn Marino 
2470*e4b17023SJohn Marino static bool
2471*e4b17023SJohn Marino self_inlining_addr_expr (tree value, tree fn)
2472*e4b17023SJohn Marino {
2473*e4b17023SJohn Marino   tree var;
2474*e4b17023SJohn Marino 
2475*e4b17023SJohn Marino   if (TREE_CODE (value) != ADDR_EXPR)
2476*e4b17023SJohn Marino     return false;
2477*e4b17023SJohn Marino 
2478*e4b17023SJohn Marino   var = get_base_address (TREE_OPERAND (value, 0));
2479*e4b17023SJohn Marino 
2480*e4b17023SJohn Marino   return var && auto_var_in_fn_p (var, fn);
2481*e4b17023SJohn Marino }
2482*e4b17023SJohn Marino 
2483*e4b17023SJohn Marino /* Append to BB a debug annotation that binds VAR to VALUE, inheriting
2484*e4b17023SJohn Marino    lexical block and line number information from base_stmt, if given,
2485*e4b17023SJohn Marino    or from the last stmt of the block otherwise.  */
2486*e4b17023SJohn Marino 
2487*e4b17023SJohn Marino static gimple
2488*e4b17023SJohn Marino insert_init_debug_bind (copy_body_data *id,
2489*e4b17023SJohn Marino 			basic_block bb, tree var, tree value,
2490*e4b17023SJohn Marino 			gimple base_stmt)
2491*e4b17023SJohn Marino {
2492*e4b17023SJohn Marino   gimple note;
2493*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
2494*e4b17023SJohn Marino   tree tracked_var;
2495*e4b17023SJohn Marino 
2496*e4b17023SJohn Marino   if (!gimple_in_ssa_p (id->src_cfun))
2497*e4b17023SJohn Marino     return NULL;
2498*e4b17023SJohn Marino 
2499*e4b17023SJohn Marino   if (!MAY_HAVE_DEBUG_STMTS)
2500*e4b17023SJohn Marino     return NULL;
2501*e4b17023SJohn Marino 
2502*e4b17023SJohn Marino   tracked_var = target_for_debug_bind (var);
2503*e4b17023SJohn Marino   if (!tracked_var)
2504*e4b17023SJohn Marino     return NULL;
2505*e4b17023SJohn Marino 
2506*e4b17023SJohn Marino   if (bb)
2507*e4b17023SJohn Marino     {
2508*e4b17023SJohn Marino       gsi = gsi_last_bb (bb);
2509*e4b17023SJohn Marino       if (!base_stmt && !gsi_end_p (gsi))
2510*e4b17023SJohn Marino 	base_stmt = gsi_stmt (gsi);
2511*e4b17023SJohn Marino     }
2512*e4b17023SJohn Marino 
2513*e4b17023SJohn Marino   note = gimple_build_debug_bind (tracked_var, value, base_stmt);
2514*e4b17023SJohn Marino 
2515*e4b17023SJohn Marino   if (bb)
2516*e4b17023SJohn Marino     {
2517*e4b17023SJohn Marino       if (!gsi_end_p (gsi))
2518*e4b17023SJohn Marino 	gsi_insert_after (&gsi, note, GSI_SAME_STMT);
2519*e4b17023SJohn Marino       else
2520*e4b17023SJohn Marino 	gsi_insert_before (&gsi, note, GSI_SAME_STMT);
2521*e4b17023SJohn Marino     }
2522*e4b17023SJohn Marino 
2523*e4b17023SJohn Marino   return note;
2524*e4b17023SJohn Marino }
2525*e4b17023SJohn Marino 
2526*e4b17023SJohn Marino static void
2527*e4b17023SJohn Marino insert_init_stmt (copy_body_data *id, basic_block bb, gimple init_stmt)
2528*e4b17023SJohn Marino {
2529*e4b17023SJohn Marino   /* If VAR represents a zero-sized variable, it's possible that the
2530*e4b17023SJohn Marino      assignment statement may result in no gimple statements.  */
2531*e4b17023SJohn Marino   if (init_stmt)
2532*e4b17023SJohn Marino     {
2533*e4b17023SJohn Marino       gimple_stmt_iterator si = gsi_last_bb (bb);
2534*e4b17023SJohn Marino 
2535*e4b17023SJohn Marino       /* We can end up with init statements that store to a non-register
2536*e4b17023SJohn Marino          from a rhs with a conversion.  Handle that here by forcing the
2537*e4b17023SJohn Marino 	 rhs into a temporary.  gimple_regimplify_operands is not
2538*e4b17023SJohn Marino 	 prepared to do this for us.  */
2539*e4b17023SJohn Marino       if (!is_gimple_debug (init_stmt)
2540*e4b17023SJohn Marino 	  && !is_gimple_reg (gimple_assign_lhs (init_stmt))
2541*e4b17023SJohn Marino 	  && is_gimple_reg_type (TREE_TYPE (gimple_assign_lhs (init_stmt)))
2542*e4b17023SJohn Marino 	  && gimple_assign_rhs_class (init_stmt) == GIMPLE_UNARY_RHS)
2543*e4b17023SJohn Marino 	{
2544*e4b17023SJohn Marino 	  tree rhs = build1 (gimple_assign_rhs_code (init_stmt),
2545*e4b17023SJohn Marino 			     gimple_expr_type (init_stmt),
2546*e4b17023SJohn Marino 			     gimple_assign_rhs1 (init_stmt));
2547*e4b17023SJohn Marino 	  rhs = force_gimple_operand_gsi (&si, rhs, true, NULL_TREE, false,
2548*e4b17023SJohn Marino 					  GSI_NEW_STMT);
2549*e4b17023SJohn Marino 	  gimple_assign_set_rhs_code (init_stmt, TREE_CODE (rhs));
2550*e4b17023SJohn Marino 	  gimple_assign_set_rhs1 (init_stmt, rhs);
2551*e4b17023SJohn Marino 	}
2552*e4b17023SJohn Marino       gsi_insert_after (&si, init_stmt, GSI_NEW_STMT);
2553*e4b17023SJohn Marino       gimple_regimplify_operands (init_stmt, &si);
2554*e4b17023SJohn Marino       mark_symbols_for_renaming (init_stmt);
2555*e4b17023SJohn Marino 
2556*e4b17023SJohn Marino       if (!is_gimple_debug (init_stmt) && MAY_HAVE_DEBUG_STMTS)
2557*e4b17023SJohn Marino 	{
2558*e4b17023SJohn Marino 	  tree var, def = gimple_assign_lhs (init_stmt);
2559*e4b17023SJohn Marino 
2560*e4b17023SJohn Marino 	  if (TREE_CODE (def) == SSA_NAME)
2561*e4b17023SJohn Marino 	    var = SSA_NAME_VAR (def);
2562*e4b17023SJohn Marino 	  else
2563*e4b17023SJohn Marino 	    var = def;
2564*e4b17023SJohn Marino 
2565*e4b17023SJohn Marino 	  insert_init_debug_bind (id, bb, var, def, init_stmt);
2566*e4b17023SJohn Marino 	}
2567*e4b17023SJohn Marino     }
2568*e4b17023SJohn Marino }
2569*e4b17023SJohn Marino 
2570*e4b17023SJohn Marino /* Initialize parameter P with VALUE.  If needed, produce init statement
2571*e4b17023SJohn Marino    at the end of BB.  When BB is NULL, we return init statement to be
2572*e4b17023SJohn Marino    output later.  */
2573*e4b17023SJohn Marino static gimple
2574*e4b17023SJohn Marino setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
2575*e4b17023SJohn Marino 		     basic_block bb, tree *vars)
2576*e4b17023SJohn Marino {
2577*e4b17023SJohn Marino   gimple init_stmt = NULL;
2578*e4b17023SJohn Marino   tree var;
2579*e4b17023SJohn Marino   tree rhs = value;
2580*e4b17023SJohn Marino   tree def = (gimple_in_ssa_p (cfun)
2581*e4b17023SJohn Marino 	      ? gimple_default_def (id->src_cfun, p) : NULL);
2582*e4b17023SJohn Marino 
2583*e4b17023SJohn Marino   if (value
2584*e4b17023SJohn Marino       && value != error_mark_node
2585*e4b17023SJohn Marino       && !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)))
2586*e4b17023SJohn Marino     {
2587*e4b17023SJohn Marino       /* If we can match up types by promotion/demotion do so.  */
2588*e4b17023SJohn Marino       if (fold_convertible_p (TREE_TYPE (p), value))
2589*e4b17023SJohn Marino 	rhs = fold_convert (TREE_TYPE (p), value);
2590*e4b17023SJohn Marino       else
2591*e4b17023SJohn Marino 	{
2592*e4b17023SJohn Marino 	  /* ???  For valid programs we should not end up here.
2593*e4b17023SJohn Marino 	     Still if we end up with truly mismatched types here, fall back
2594*e4b17023SJohn Marino 	     to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid
2595*e4b17023SJohn Marino 	     GIMPLE to the following passes.  */
2596*e4b17023SJohn Marino 	  if (!is_gimple_reg_type (TREE_TYPE (value))
2597*e4b17023SJohn Marino 	      || TYPE_SIZE (TREE_TYPE (p)) == TYPE_SIZE (TREE_TYPE (value)))
2598*e4b17023SJohn Marino 	    rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (p), value);
2599*e4b17023SJohn Marino 	  else
2600*e4b17023SJohn Marino 	    rhs = build_zero_cst (TREE_TYPE (p));
2601*e4b17023SJohn Marino 	}
2602*e4b17023SJohn Marino     }
2603*e4b17023SJohn Marino 
2604*e4b17023SJohn Marino   /* Make an equivalent VAR_DECL.  Note that we must NOT remap the type
2605*e4b17023SJohn Marino      here since the type of this decl must be visible to the calling
2606*e4b17023SJohn Marino      function.  */
2607*e4b17023SJohn Marino   var = copy_decl_to_var (p, id);
2608*e4b17023SJohn Marino 
2609*e4b17023SJohn Marino   /* We're actually using the newly-created var.  */
2610*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
2611*e4b17023SJohn Marino     add_referenced_var (var);
2612*e4b17023SJohn Marino 
2613*e4b17023SJohn Marino   /* Declare this new variable.  */
2614*e4b17023SJohn Marino   DECL_CHAIN (var) = *vars;
2615*e4b17023SJohn Marino   *vars = var;
2616*e4b17023SJohn Marino 
2617*e4b17023SJohn Marino   /* Make gimplifier happy about this variable.  */
2618*e4b17023SJohn Marino   DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
2619*e4b17023SJohn Marino 
2620*e4b17023SJohn Marino   /* We are eventually using the value - make sure all variables
2621*e4b17023SJohn Marino      referenced therein are properly recorded.  */
2622*e4b17023SJohn Marino   if (value
2623*e4b17023SJohn Marino       && gimple_in_ssa_p (cfun)
2624*e4b17023SJohn Marino       && TREE_CODE (value) == ADDR_EXPR)
2625*e4b17023SJohn Marino     {
2626*e4b17023SJohn Marino       tree base = get_base_address (TREE_OPERAND (value, 0));
2627*e4b17023SJohn Marino       if (base && TREE_CODE (base) == VAR_DECL)
2628*e4b17023SJohn Marino 	add_referenced_var (base);
2629*e4b17023SJohn Marino     }
2630*e4b17023SJohn Marino 
2631*e4b17023SJohn Marino   /* If the parameter is never assigned to, has no SSA_NAMEs created,
2632*e4b17023SJohn Marino      we would not need to create a new variable here at all, if it
2633*e4b17023SJohn Marino      weren't for debug info.  Still, we can just use the argument
2634*e4b17023SJohn Marino      value.  */
2635*e4b17023SJohn Marino   if (TREE_READONLY (p)
2636*e4b17023SJohn Marino       && !TREE_ADDRESSABLE (p)
2637*e4b17023SJohn Marino       && value && !TREE_SIDE_EFFECTS (value)
2638*e4b17023SJohn Marino       && !def)
2639*e4b17023SJohn Marino     {
2640*e4b17023SJohn Marino       /* We may produce non-gimple trees by adding NOPs or introduce
2641*e4b17023SJohn Marino 	 invalid sharing when operand is not really constant.
2642*e4b17023SJohn Marino 	 It is not big deal to prohibit constant propagation here as
2643*e4b17023SJohn Marino 	 we will constant propagate in DOM1 pass anyway.  */
2644*e4b17023SJohn Marino       if (is_gimple_min_invariant (value)
2645*e4b17023SJohn Marino 	  && useless_type_conversion_p (TREE_TYPE (p),
2646*e4b17023SJohn Marino 						 TREE_TYPE (value))
2647*e4b17023SJohn Marino 	  /* We have to be very careful about ADDR_EXPR.  Make sure
2648*e4b17023SJohn Marino 	     the base variable isn't a local variable of the inlined
2649*e4b17023SJohn Marino 	     function, e.g., when doing recursive inlining, direct or
2650*e4b17023SJohn Marino 	     mutually-recursive or whatever, which is why we don't
2651*e4b17023SJohn Marino 	     just test whether fn == current_function_decl.  */
2652*e4b17023SJohn Marino 	  && ! self_inlining_addr_expr (value, fn))
2653*e4b17023SJohn Marino 	{
2654*e4b17023SJohn Marino 	  insert_decl_map (id, p, value);
2655*e4b17023SJohn Marino 	  insert_debug_decl_map (id, p, var);
2656*e4b17023SJohn Marino 	  return insert_init_debug_bind (id, bb, var, value, NULL);
2657*e4b17023SJohn Marino 	}
2658*e4b17023SJohn Marino     }
2659*e4b17023SJohn Marino 
2660*e4b17023SJohn Marino   /* Register the VAR_DECL as the equivalent for the PARM_DECL;
2661*e4b17023SJohn Marino      that way, when the PARM_DECL is encountered, it will be
2662*e4b17023SJohn Marino      automatically replaced by the VAR_DECL.  */
2663*e4b17023SJohn Marino   insert_decl_map (id, p, var);
2664*e4b17023SJohn Marino 
2665*e4b17023SJohn Marino   /* Even if P was TREE_READONLY, the new VAR should not be.
2666*e4b17023SJohn Marino      In the original code, we would have constructed a
2667*e4b17023SJohn Marino      temporary, and then the function body would have never
2668*e4b17023SJohn Marino      changed the value of P.  However, now, we will be
2669*e4b17023SJohn Marino      constructing VAR directly.  The constructor body may
2670*e4b17023SJohn Marino      change its value multiple times as it is being
2671*e4b17023SJohn Marino      constructed.  Therefore, it must not be TREE_READONLY;
2672*e4b17023SJohn Marino      the back-end assumes that TREE_READONLY variable is
2673*e4b17023SJohn Marino      assigned to only once.  */
2674*e4b17023SJohn Marino   if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
2675*e4b17023SJohn Marino     TREE_READONLY (var) = 0;
2676*e4b17023SJohn Marino 
2677*e4b17023SJohn Marino   /* If there is no setup required and we are in SSA, take the easy route
2678*e4b17023SJohn Marino      replacing all SSA names representing the function parameter by the
2679*e4b17023SJohn Marino      SSA name passed to function.
2680*e4b17023SJohn Marino 
2681*e4b17023SJohn Marino      We need to construct map for the variable anyway as it might be used
2682*e4b17023SJohn Marino      in different SSA names when parameter is set in function.
2683*e4b17023SJohn Marino 
2684*e4b17023SJohn Marino      Do replacement at -O0 for const arguments replaced by constant.
2685*e4b17023SJohn Marino      This is important for builtin_constant_p and other construct requiring
2686*e4b17023SJohn Marino      constant argument to be visible in inlined function body.  */
2687*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun) && rhs && def && is_gimple_reg (p)
2688*e4b17023SJohn Marino       && (optimize
2689*e4b17023SJohn Marino           || (TREE_READONLY (p)
2690*e4b17023SJohn Marino 	      && is_gimple_min_invariant (rhs)))
2691*e4b17023SJohn Marino       && (TREE_CODE (rhs) == SSA_NAME
2692*e4b17023SJohn Marino 	  || is_gimple_min_invariant (rhs))
2693*e4b17023SJohn Marino       && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def))
2694*e4b17023SJohn Marino     {
2695*e4b17023SJohn Marino       insert_decl_map (id, def, rhs);
2696*e4b17023SJohn Marino       return insert_init_debug_bind (id, bb, var, rhs, NULL);
2697*e4b17023SJohn Marino     }
2698*e4b17023SJohn Marino 
2699*e4b17023SJohn Marino   /* If the value of argument is never used, don't care about initializing
2700*e4b17023SJohn Marino      it.  */
2701*e4b17023SJohn Marino   if (optimize && gimple_in_ssa_p (cfun) && !def && is_gimple_reg (p))
2702*e4b17023SJohn Marino     {
2703*e4b17023SJohn Marino       gcc_assert (!value || !TREE_SIDE_EFFECTS (value));
2704*e4b17023SJohn Marino       return insert_init_debug_bind (id, bb, var, rhs, NULL);
2705*e4b17023SJohn Marino     }
2706*e4b17023SJohn Marino 
2707*e4b17023SJohn Marino   /* Initialize this VAR_DECL from the equivalent argument.  Convert
2708*e4b17023SJohn Marino      the argument to the proper type in case it was promoted.  */
2709*e4b17023SJohn Marino   if (value)
2710*e4b17023SJohn Marino     {
2711*e4b17023SJohn Marino       if (rhs == error_mark_node)
2712*e4b17023SJohn Marino 	{
2713*e4b17023SJohn Marino 	  insert_decl_map (id, p, var);
2714*e4b17023SJohn Marino 	  return insert_init_debug_bind (id, bb, var, rhs, NULL);
2715*e4b17023SJohn Marino 	}
2716*e4b17023SJohn Marino 
2717*e4b17023SJohn Marino       STRIP_USELESS_TYPE_CONVERSION (rhs);
2718*e4b17023SJohn Marino 
2719*e4b17023SJohn Marino       /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
2720*e4b17023SJohn Marino 	 keep our trees in gimple form.  */
2721*e4b17023SJohn Marino       if (def && gimple_in_ssa_p (cfun) && is_gimple_reg (p))
2722*e4b17023SJohn Marino 	{
2723*e4b17023SJohn Marino 	  def = remap_ssa_name (def, id);
2724*e4b17023SJohn Marino           init_stmt = gimple_build_assign (def, rhs);
2725*e4b17023SJohn Marino 	  SSA_NAME_IS_DEFAULT_DEF (def) = 0;
2726*e4b17023SJohn Marino 	  set_default_def (var, NULL);
2727*e4b17023SJohn Marino 	}
2728*e4b17023SJohn Marino       else
2729*e4b17023SJohn Marino         init_stmt = gimple_build_assign (var, rhs);
2730*e4b17023SJohn Marino 
2731*e4b17023SJohn Marino       if (bb && init_stmt)
2732*e4b17023SJohn Marino         insert_init_stmt (id, bb, init_stmt);
2733*e4b17023SJohn Marino     }
2734*e4b17023SJohn Marino   return init_stmt;
2735*e4b17023SJohn Marino }
2736*e4b17023SJohn Marino 
2737*e4b17023SJohn Marino /* Generate code to initialize the parameters of the function at the
2738*e4b17023SJohn Marino    top of the stack in ID from the GIMPLE_CALL STMT.  */
2739*e4b17023SJohn Marino 
2740*e4b17023SJohn Marino static void
2741*e4b17023SJohn Marino initialize_inlined_parameters (copy_body_data *id, gimple stmt,
2742*e4b17023SJohn Marino 			       tree fn, basic_block bb)
2743*e4b17023SJohn Marino {
2744*e4b17023SJohn Marino   tree parms;
2745*e4b17023SJohn Marino   size_t i;
2746*e4b17023SJohn Marino   tree p;
2747*e4b17023SJohn Marino   tree vars = NULL_TREE;
2748*e4b17023SJohn Marino   tree static_chain = gimple_call_chain (stmt);
2749*e4b17023SJohn Marino 
2750*e4b17023SJohn Marino   /* Figure out what the parameters are.  */
2751*e4b17023SJohn Marino   parms = DECL_ARGUMENTS (fn);
2752*e4b17023SJohn Marino 
2753*e4b17023SJohn Marino   /* Loop through the parameter declarations, replacing each with an
2754*e4b17023SJohn Marino      equivalent VAR_DECL, appropriately initialized.  */
2755*e4b17023SJohn Marino   for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
2756*e4b17023SJohn Marino     {
2757*e4b17023SJohn Marino       tree val;
2758*e4b17023SJohn Marino       val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
2759*e4b17023SJohn Marino       setup_one_parameter (id, p, val, fn, bb, &vars);
2760*e4b17023SJohn Marino     }
2761*e4b17023SJohn Marino   /* After remapping parameters remap their types.  This has to be done
2762*e4b17023SJohn Marino      in a second loop over all parameters to appropriately remap
2763*e4b17023SJohn Marino      variable sized arrays when the size is specified in a
2764*e4b17023SJohn Marino      parameter following the array.  */
2765*e4b17023SJohn Marino   for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
2766*e4b17023SJohn Marino     {
2767*e4b17023SJohn Marino       tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
2768*e4b17023SJohn Marino       if (varp
2769*e4b17023SJohn Marino 	  && TREE_CODE (*varp) == VAR_DECL)
2770*e4b17023SJohn Marino 	{
2771*e4b17023SJohn Marino 	  tree def = (gimple_in_ssa_p (cfun) && is_gimple_reg (p)
2772*e4b17023SJohn Marino 		      ? gimple_default_def (id->src_cfun, p) : NULL);
2773*e4b17023SJohn Marino 	  tree var = *varp;
2774*e4b17023SJohn Marino 	  TREE_TYPE (var) = remap_type (TREE_TYPE (var), id);
2775*e4b17023SJohn Marino 	  /* Also remap the default definition if it was remapped
2776*e4b17023SJohn Marino 	     to the default definition of the parameter replacement
2777*e4b17023SJohn Marino 	     by the parameter setup.  */
2778*e4b17023SJohn Marino 	  if (def)
2779*e4b17023SJohn Marino 	    {
2780*e4b17023SJohn Marino 	      tree *defp = (tree *) pointer_map_contains (id->decl_map, def);
2781*e4b17023SJohn Marino 	      if (defp
2782*e4b17023SJohn Marino 		  && TREE_CODE (*defp) == SSA_NAME
2783*e4b17023SJohn Marino 		  && SSA_NAME_VAR (*defp) == var)
2784*e4b17023SJohn Marino 		TREE_TYPE (*defp) = TREE_TYPE (var);
2785*e4b17023SJohn Marino 	    }
2786*e4b17023SJohn Marino 	}
2787*e4b17023SJohn Marino     }
2788*e4b17023SJohn Marino 
2789*e4b17023SJohn Marino   /* Initialize the static chain.  */
2790*e4b17023SJohn Marino   p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
2791*e4b17023SJohn Marino   gcc_assert (fn != current_function_decl);
2792*e4b17023SJohn Marino   if (p)
2793*e4b17023SJohn Marino     {
2794*e4b17023SJohn Marino       /* No static chain?  Seems like a bug in tree-nested.c.  */
2795*e4b17023SJohn Marino       gcc_assert (static_chain);
2796*e4b17023SJohn Marino 
2797*e4b17023SJohn Marino       setup_one_parameter (id, p, static_chain, fn, bb, &vars);
2798*e4b17023SJohn Marino     }
2799*e4b17023SJohn Marino 
2800*e4b17023SJohn Marino   declare_inline_vars (id->block, vars);
2801*e4b17023SJohn Marino }
2802*e4b17023SJohn Marino 
2803*e4b17023SJohn Marino 
2804*e4b17023SJohn Marino /* Declare a return variable to replace the RESULT_DECL for the
2805*e4b17023SJohn Marino    function we are calling.  An appropriate DECL_STMT is returned.
2806*e4b17023SJohn Marino    The USE_STMT is filled to contain a use of the declaration to
2807*e4b17023SJohn Marino    indicate the return value of the function.
2808*e4b17023SJohn Marino 
2809*e4b17023SJohn Marino    RETURN_SLOT, if non-null is place where to store the result.  It
2810*e4b17023SJohn Marino    is set only for CALL_EXPR_RETURN_SLOT_OPT.  MODIFY_DEST, if non-null,
2811*e4b17023SJohn Marino    was the LHS of the MODIFY_EXPR to which this call is the RHS.
2812*e4b17023SJohn Marino 
2813*e4b17023SJohn Marino    The return value is a (possibly null) value that holds the result
2814*e4b17023SJohn Marino    as seen by the caller.  */
2815*e4b17023SJohn Marino 
2816*e4b17023SJohn Marino static tree
2817*e4b17023SJohn Marino declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest,
2818*e4b17023SJohn Marino 			 basic_block entry_bb)
2819*e4b17023SJohn Marino {
2820*e4b17023SJohn Marino   tree callee = id->src_fn;
2821*e4b17023SJohn Marino   tree result = DECL_RESULT (callee);
2822*e4b17023SJohn Marino   tree callee_type = TREE_TYPE (result);
2823*e4b17023SJohn Marino   tree caller_type;
2824*e4b17023SJohn Marino   tree var, use;
2825*e4b17023SJohn Marino 
2826*e4b17023SJohn Marino   /* Handle type-mismatches in the function declaration return type
2827*e4b17023SJohn Marino      vs. the call expression.  */
2828*e4b17023SJohn Marino   if (modify_dest)
2829*e4b17023SJohn Marino     caller_type = TREE_TYPE (modify_dest);
2830*e4b17023SJohn Marino   else
2831*e4b17023SJohn Marino     caller_type = TREE_TYPE (TREE_TYPE (callee));
2832*e4b17023SJohn Marino 
2833*e4b17023SJohn Marino   /* We don't need to do anything for functions that don't return anything.  */
2834*e4b17023SJohn Marino   if (VOID_TYPE_P (callee_type))
2835*e4b17023SJohn Marino     return NULL_TREE;
2836*e4b17023SJohn Marino 
2837*e4b17023SJohn Marino   /* If there was a return slot, then the return value is the
2838*e4b17023SJohn Marino      dereferenced address of that object.  */
2839*e4b17023SJohn Marino   if (return_slot)
2840*e4b17023SJohn Marino     {
2841*e4b17023SJohn Marino       /* The front end shouldn't have used both return_slot and
2842*e4b17023SJohn Marino 	 a modify expression.  */
2843*e4b17023SJohn Marino       gcc_assert (!modify_dest);
2844*e4b17023SJohn Marino       if (DECL_BY_REFERENCE (result))
2845*e4b17023SJohn Marino 	{
2846*e4b17023SJohn Marino 	  tree return_slot_addr = build_fold_addr_expr (return_slot);
2847*e4b17023SJohn Marino 	  STRIP_USELESS_TYPE_CONVERSION (return_slot_addr);
2848*e4b17023SJohn Marino 
2849*e4b17023SJohn Marino 	  /* We are going to construct *&return_slot and we can't do that
2850*e4b17023SJohn Marino 	     for variables believed to be not addressable.
2851*e4b17023SJohn Marino 
2852*e4b17023SJohn Marino 	     FIXME: This check possibly can match, because values returned
2853*e4b17023SJohn Marino 	     via return slot optimization are not believed to have address
2854*e4b17023SJohn Marino 	     taken by alias analysis.  */
2855*e4b17023SJohn Marino 	  gcc_assert (TREE_CODE (return_slot) != SSA_NAME);
2856*e4b17023SJohn Marino 	  var = return_slot_addr;
2857*e4b17023SJohn Marino 	}
2858*e4b17023SJohn Marino       else
2859*e4b17023SJohn Marino 	{
2860*e4b17023SJohn Marino 	  var = return_slot;
2861*e4b17023SJohn Marino 	  gcc_assert (TREE_CODE (var) != SSA_NAME);
2862*e4b17023SJohn Marino 	  TREE_ADDRESSABLE (var) |= TREE_ADDRESSABLE (result);
2863*e4b17023SJohn Marino 	}
2864*e4b17023SJohn Marino       if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
2865*e4b17023SJohn Marino            || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
2866*e4b17023SJohn Marino 	  && !DECL_GIMPLE_REG_P (result)
2867*e4b17023SJohn Marino 	  && DECL_P (var))
2868*e4b17023SJohn Marino 	DECL_GIMPLE_REG_P (var) = 0;
2869*e4b17023SJohn Marino       use = NULL;
2870*e4b17023SJohn Marino       goto done;
2871*e4b17023SJohn Marino     }
2872*e4b17023SJohn Marino 
2873*e4b17023SJohn Marino   /* All types requiring non-trivial constructors should have been handled.  */
2874*e4b17023SJohn Marino   gcc_assert (!TREE_ADDRESSABLE (callee_type));
2875*e4b17023SJohn Marino 
2876*e4b17023SJohn Marino   /* Attempt to avoid creating a new temporary variable.  */
2877*e4b17023SJohn Marino   if (modify_dest
2878*e4b17023SJohn Marino       && TREE_CODE (modify_dest) != SSA_NAME)
2879*e4b17023SJohn Marino     {
2880*e4b17023SJohn Marino       bool use_it = false;
2881*e4b17023SJohn Marino 
2882*e4b17023SJohn Marino       /* We can't use MODIFY_DEST if there's type promotion involved.  */
2883*e4b17023SJohn Marino       if (!useless_type_conversion_p (callee_type, caller_type))
2884*e4b17023SJohn Marino 	use_it = false;
2885*e4b17023SJohn Marino 
2886*e4b17023SJohn Marino       /* ??? If we're assigning to a variable sized type, then we must
2887*e4b17023SJohn Marino 	 reuse the destination variable, because we've no good way to
2888*e4b17023SJohn Marino 	 create variable sized temporaries at this point.  */
2889*e4b17023SJohn Marino       else if (TREE_CODE (TYPE_SIZE_UNIT (caller_type)) != INTEGER_CST)
2890*e4b17023SJohn Marino 	use_it = true;
2891*e4b17023SJohn Marino 
2892*e4b17023SJohn Marino       /* If the callee cannot possibly modify MODIFY_DEST, then we can
2893*e4b17023SJohn Marino 	 reuse it as the result of the call directly.  Don't do this if
2894*e4b17023SJohn Marino 	 it would promote MODIFY_DEST to addressable.  */
2895*e4b17023SJohn Marino       else if (TREE_ADDRESSABLE (result))
2896*e4b17023SJohn Marino 	use_it = false;
2897*e4b17023SJohn Marino       else
2898*e4b17023SJohn Marino 	{
2899*e4b17023SJohn Marino 	  tree base_m = get_base_address (modify_dest);
2900*e4b17023SJohn Marino 
2901*e4b17023SJohn Marino 	  /* If the base isn't a decl, then it's a pointer, and we don't
2902*e4b17023SJohn Marino 	     know where that's going to go.  */
2903*e4b17023SJohn Marino 	  if (!DECL_P (base_m))
2904*e4b17023SJohn Marino 	    use_it = false;
2905*e4b17023SJohn Marino 	  else if (is_global_var (base_m))
2906*e4b17023SJohn Marino 	    use_it = false;
2907*e4b17023SJohn Marino 	  else if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
2908*e4b17023SJohn Marino 		    || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE)
2909*e4b17023SJohn Marino 		   && !DECL_GIMPLE_REG_P (result)
2910*e4b17023SJohn Marino 		   && DECL_GIMPLE_REG_P (base_m))
2911*e4b17023SJohn Marino 	    use_it = false;
2912*e4b17023SJohn Marino 	  else if (!TREE_ADDRESSABLE (base_m))
2913*e4b17023SJohn Marino 	    use_it = true;
2914*e4b17023SJohn Marino 	}
2915*e4b17023SJohn Marino 
2916*e4b17023SJohn Marino       if (use_it)
2917*e4b17023SJohn Marino 	{
2918*e4b17023SJohn Marino 	  var = modify_dest;
2919*e4b17023SJohn Marino 	  use = NULL;
2920*e4b17023SJohn Marino 	  goto done;
2921*e4b17023SJohn Marino 	}
2922*e4b17023SJohn Marino     }
2923*e4b17023SJohn Marino 
2924*e4b17023SJohn Marino   gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (callee_type)) == INTEGER_CST);
2925*e4b17023SJohn Marino 
2926*e4b17023SJohn Marino   var = copy_result_decl_to_var (result, id);
2927*e4b17023SJohn Marino   if (gimple_in_ssa_p (cfun))
2928*e4b17023SJohn Marino     add_referenced_var (var);
2929*e4b17023SJohn Marino 
2930*e4b17023SJohn Marino   DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
2931*e4b17023SJohn Marino 
2932*e4b17023SJohn Marino   /* Do not have the rest of GCC warn about this variable as it should
2933*e4b17023SJohn Marino      not be visible to the user.  */
2934*e4b17023SJohn Marino   TREE_NO_WARNING (var) = 1;
2935*e4b17023SJohn Marino 
2936*e4b17023SJohn Marino   declare_inline_vars (id->block, var);
2937*e4b17023SJohn Marino 
2938*e4b17023SJohn Marino   /* Build the use expr.  If the return type of the function was
2939*e4b17023SJohn Marino      promoted, convert it back to the expected type.  */
2940*e4b17023SJohn Marino   use = var;
2941*e4b17023SJohn Marino   if (!useless_type_conversion_p (caller_type, TREE_TYPE (var)))
2942*e4b17023SJohn Marino     {
2943*e4b17023SJohn Marino       /* If we can match up types by promotion/demotion do so.  */
2944*e4b17023SJohn Marino       if (fold_convertible_p (caller_type, var))
2945*e4b17023SJohn Marino 	use = fold_convert (caller_type, var);
2946*e4b17023SJohn Marino       else
2947*e4b17023SJohn Marino 	{
2948*e4b17023SJohn Marino 	  /* ???  For valid programs we should not end up here.
2949*e4b17023SJohn Marino 	     Still if we end up with truly mismatched types here, fall back
2950*e4b17023SJohn Marino 	     to using a MEM_REF to not leak invalid GIMPLE to the following
2951*e4b17023SJohn Marino 	     passes.  */
2952*e4b17023SJohn Marino 	  /* Prevent var from being written into SSA form.  */
2953*e4b17023SJohn Marino 	  if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
2954*e4b17023SJohn Marino 	      || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
2955*e4b17023SJohn Marino 	    DECL_GIMPLE_REG_P (var) = false;
2956*e4b17023SJohn Marino 	  else if (is_gimple_reg_type (TREE_TYPE (var)))
2957*e4b17023SJohn Marino 	    TREE_ADDRESSABLE (var) = true;
2958*e4b17023SJohn Marino 	  use = fold_build2 (MEM_REF, caller_type,
2959*e4b17023SJohn Marino 			     build_fold_addr_expr (var),
2960*e4b17023SJohn Marino 			     build_int_cst (ptr_type_node, 0));
2961*e4b17023SJohn Marino 	}
2962*e4b17023SJohn Marino     }
2963*e4b17023SJohn Marino 
2964*e4b17023SJohn Marino   STRIP_USELESS_TYPE_CONVERSION (use);
2965*e4b17023SJohn Marino 
2966*e4b17023SJohn Marino   if (DECL_BY_REFERENCE (result))
2967*e4b17023SJohn Marino     {
2968*e4b17023SJohn Marino       TREE_ADDRESSABLE (var) = 1;
2969*e4b17023SJohn Marino       var = build_fold_addr_expr (var);
2970*e4b17023SJohn Marino     }
2971*e4b17023SJohn Marino 
2972*e4b17023SJohn Marino  done:
2973*e4b17023SJohn Marino   /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
2974*e4b17023SJohn Marino      way, when the RESULT_DECL is encountered, it will be
2975*e4b17023SJohn Marino      automatically replaced by the VAR_DECL.
2976*e4b17023SJohn Marino 
2977*e4b17023SJohn Marino      When returning by reference, ensure that RESULT_DECL remaps to
2978*e4b17023SJohn Marino      gimple_val.  */
2979*e4b17023SJohn Marino   if (DECL_BY_REFERENCE (result)
2980*e4b17023SJohn Marino       && !is_gimple_val (var))
2981*e4b17023SJohn Marino     {
2982*e4b17023SJohn Marino       tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
2983*e4b17023SJohn Marino       if (gimple_in_ssa_p (id->src_cfun))
2984*e4b17023SJohn Marino 	add_referenced_var (temp);
2985*e4b17023SJohn Marino       insert_decl_map (id, result, temp);
2986*e4b17023SJohn Marino       /* When RESULT_DECL is in SSA form, we need to use it's default_def
2987*e4b17023SJohn Marino 	 SSA_NAME.  */
2988*e4b17023SJohn Marino       if (gimple_in_ssa_p (id->src_cfun) && gimple_default_def (id->src_cfun, result))
2989*e4b17023SJohn Marino         temp = remap_ssa_name (gimple_default_def (id->src_cfun, result), id);
2990*e4b17023SJohn Marino       insert_init_stmt (id, entry_bb, gimple_build_assign (temp, var));
2991*e4b17023SJohn Marino     }
2992*e4b17023SJohn Marino   else
2993*e4b17023SJohn Marino     insert_decl_map (id, result, var);
2994*e4b17023SJohn Marino 
2995*e4b17023SJohn Marino   /* Remember this so we can ignore it in remap_decls.  */
2996*e4b17023SJohn Marino   id->retvar = var;
2997*e4b17023SJohn Marino 
2998*e4b17023SJohn Marino   return use;
2999*e4b17023SJohn Marino }
3000*e4b17023SJohn Marino 
3001*e4b17023SJohn Marino /* Callback through walk_tree.  Determine if a DECL_INITIAL makes reference
3002*e4b17023SJohn Marino    to a local label.  */
3003*e4b17023SJohn Marino 
3004*e4b17023SJohn Marino static tree
3005*e4b17023SJohn Marino has_label_address_in_static_1 (tree *nodep, int *walk_subtrees, void *fnp)
3006*e4b17023SJohn Marino {
3007*e4b17023SJohn Marino   tree node = *nodep;
3008*e4b17023SJohn Marino   tree fn = (tree) fnp;
3009*e4b17023SJohn Marino 
3010*e4b17023SJohn Marino   if (TREE_CODE (node) == LABEL_DECL && DECL_CONTEXT (node) == fn)
3011*e4b17023SJohn Marino     return node;
3012*e4b17023SJohn Marino 
3013*e4b17023SJohn Marino   if (TYPE_P (node))
3014*e4b17023SJohn Marino     *walk_subtrees = 0;
3015*e4b17023SJohn Marino 
3016*e4b17023SJohn Marino   return NULL_TREE;
3017*e4b17023SJohn Marino }
3018*e4b17023SJohn Marino 
3019*e4b17023SJohn Marino /* Determine if the function can be copied.  If so return NULL.  If
3020*e4b17023SJohn Marino    not return a string describng the reason for failure.  */
3021*e4b17023SJohn Marino 
3022*e4b17023SJohn Marino static const char *
3023*e4b17023SJohn Marino copy_forbidden (struct function *fun, tree fndecl)
3024*e4b17023SJohn Marino {
3025*e4b17023SJohn Marino   const char *reason = fun->cannot_be_copied_reason;
3026*e4b17023SJohn Marino   tree decl;
3027*e4b17023SJohn Marino   unsigned ix;
3028*e4b17023SJohn Marino 
3029*e4b17023SJohn Marino   /* Only examine the function once.  */
3030*e4b17023SJohn Marino   if (fun->cannot_be_copied_set)
3031*e4b17023SJohn Marino     return reason;
3032*e4b17023SJohn Marino 
3033*e4b17023SJohn Marino   /* We cannot copy a function that receives a non-local goto
3034*e4b17023SJohn Marino      because we cannot remap the destination label used in the
3035*e4b17023SJohn Marino      function that is performing the non-local goto.  */
3036*e4b17023SJohn Marino   /* ??? Actually, this should be possible, if we work at it.
3037*e4b17023SJohn Marino      No doubt there's just a handful of places that simply
3038*e4b17023SJohn Marino      assume it doesn't happen and don't substitute properly.  */
3039*e4b17023SJohn Marino   if (fun->has_nonlocal_label)
3040*e4b17023SJohn Marino     {
3041*e4b17023SJohn Marino       reason = G_("function %q+F can never be copied "
3042*e4b17023SJohn Marino 		  "because it receives a non-local goto");
3043*e4b17023SJohn Marino       goto fail;
3044*e4b17023SJohn Marino     }
3045*e4b17023SJohn Marino 
3046*e4b17023SJohn Marino   FOR_EACH_LOCAL_DECL (fun, ix, decl)
3047*e4b17023SJohn Marino     if (TREE_CODE (decl) == VAR_DECL
3048*e4b17023SJohn Marino 	&& TREE_STATIC (decl)
3049*e4b17023SJohn Marino 	&& !DECL_EXTERNAL (decl)
3050*e4b17023SJohn Marino 	&& DECL_INITIAL (decl)
3051*e4b17023SJohn Marino 	&& walk_tree_without_duplicates (&DECL_INITIAL (decl),
3052*e4b17023SJohn Marino 					 has_label_address_in_static_1,
3053*e4b17023SJohn Marino 					 fndecl))
3054*e4b17023SJohn Marino       {
3055*e4b17023SJohn Marino 	reason = G_("function %q+F can never be copied because it saves "
3056*e4b17023SJohn Marino 		    "address of local label in a static variable");
3057*e4b17023SJohn Marino 	goto fail;
3058*e4b17023SJohn Marino       }
3059*e4b17023SJohn Marino 
3060*e4b17023SJohn Marino  fail:
3061*e4b17023SJohn Marino   fun->cannot_be_copied_reason = reason;
3062*e4b17023SJohn Marino   fun->cannot_be_copied_set = true;
3063*e4b17023SJohn Marino   return reason;
3064*e4b17023SJohn Marino }
3065*e4b17023SJohn Marino 
3066*e4b17023SJohn Marino 
3067*e4b17023SJohn Marino static const char *inline_forbidden_reason;
3068*e4b17023SJohn Marino 
3069*e4b17023SJohn Marino /* A callback for walk_gimple_seq to handle statements.  Returns non-null
3070*e4b17023SJohn Marino    iff a function can not be inlined.  Also sets the reason why. */
3071*e4b17023SJohn Marino 
3072*e4b17023SJohn Marino static tree
3073*e4b17023SJohn Marino inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
3074*e4b17023SJohn Marino 			 struct walk_stmt_info *wip)
3075*e4b17023SJohn Marino {
3076*e4b17023SJohn Marino   tree fn = (tree) wip->info;
3077*e4b17023SJohn Marino   tree t;
3078*e4b17023SJohn Marino   gimple stmt = gsi_stmt (*gsi);
3079*e4b17023SJohn Marino 
3080*e4b17023SJohn Marino   switch (gimple_code (stmt))
3081*e4b17023SJohn Marino     {
3082*e4b17023SJohn Marino     case GIMPLE_CALL:
3083*e4b17023SJohn Marino       /* Refuse to inline alloca call unless user explicitly forced so as
3084*e4b17023SJohn Marino 	 this may change program's memory overhead drastically when the
3085*e4b17023SJohn Marino 	 function using alloca is called in loop.  In GCC present in
3086*e4b17023SJohn Marino 	 SPEC2000 inlining into schedule_block cause it to require 2GB of
3087*e4b17023SJohn Marino 	 RAM instead of 256MB.  Don't do so for alloca calls emitted for
3088*e4b17023SJohn Marino 	 VLA objects as those can't cause unbounded growth (they're always
3089*e4b17023SJohn Marino 	 wrapped inside stack_save/stack_restore regions.  */
3090*e4b17023SJohn Marino       if (gimple_alloca_call_p (stmt)
3091*e4b17023SJohn Marino 	  && !gimple_call_alloca_for_var_p (stmt)
3092*e4b17023SJohn Marino 	  && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
3093*e4b17023SJohn Marino 	{
3094*e4b17023SJohn Marino 	  inline_forbidden_reason
3095*e4b17023SJohn Marino 	    = G_("function %q+F can never be inlined because it uses "
3096*e4b17023SJohn Marino 		 "alloca (override using the always_inline attribute)");
3097*e4b17023SJohn Marino 	  *handled_ops_p = true;
3098*e4b17023SJohn Marino 	  return fn;
3099*e4b17023SJohn Marino 	}
3100*e4b17023SJohn Marino 
3101*e4b17023SJohn Marino       t = gimple_call_fndecl (stmt);
3102*e4b17023SJohn Marino       if (t == NULL_TREE)
3103*e4b17023SJohn Marino 	break;
3104*e4b17023SJohn Marino 
3105*e4b17023SJohn Marino       /* We cannot inline functions that call setjmp.  */
3106*e4b17023SJohn Marino       if (setjmp_call_p (t))
3107*e4b17023SJohn Marino 	{
3108*e4b17023SJohn Marino 	  inline_forbidden_reason
3109*e4b17023SJohn Marino 	    = G_("function %q+F can never be inlined because it uses setjmp");
3110*e4b17023SJohn Marino 	  *handled_ops_p = true;
3111*e4b17023SJohn Marino 	  return t;
3112*e4b17023SJohn Marino 	}
3113*e4b17023SJohn Marino 
3114*e4b17023SJohn Marino       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
3115*e4b17023SJohn Marino 	switch (DECL_FUNCTION_CODE (t))
3116*e4b17023SJohn Marino 	  {
3117*e4b17023SJohn Marino 	    /* We cannot inline functions that take a variable number of
3118*e4b17023SJohn Marino 	       arguments.  */
3119*e4b17023SJohn Marino 	  case BUILT_IN_VA_START:
3120*e4b17023SJohn Marino 	  case BUILT_IN_NEXT_ARG:
3121*e4b17023SJohn Marino 	  case BUILT_IN_VA_END:
3122*e4b17023SJohn Marino 	    inline_forbidden_reason
3123*e4b17023SJohn Marino 	      = G_("function %q+F can never be inlined because it "
3124*e4b17023SJohn Marino 		   "uses variable argument lists");
3125*e4b17023SJohn Marino 	    *handled_ops_p = true;
3126*e4b17023SJohn Marino 	    return t;
3127*e4b17023SJohn Marino 
3128*e4b17023SJohn Marino 	  case BUILT_IN_LONGJMP:
3129*e4b17023SJohn Marino 	    /* We can't inline functions that call __builtin_longjmp at
3130*e4b17023SJohn Marino 	       all.  The non-local goto machinery really requires the
3131*e4b17023SJohn Marino 	       destination be in a different function.  If we allow the
3132*e4b17023SJohn Marino 	       function calling __builtin_longjmp to be inlined into the
3133*e4b17023SJohn Marino 	       function calling __builtin_setjmp, Things will Go Awry.  */
3134*e4b17023SJohn Marino 	    inline_forbidden_reason
3135*e4b17023SJohn Marino 	      = G_("function %q+F can never be inlined because "
3136*e4b17023SJohn Marino 		   "it uses setjmp-longjmp exception handling");
3137*e4b17023SJohn Marino 	    *handled_ops_p = true;
3138*e4b17023SJohn Marino 	    return t;
3139*e4b17023SJohn Marino 
3140*e4b17023SJohn Marino 	  case BUILT_IN_NONLOCAL_GOTO:
3141*e4b17023SJohn Marino 	    /* Similarly.  */
3142*e4b17023SJohn Marino 	    inline_forbidden_reason
3143*e4b17023SJohn Marino 	      = G_("function %q+F can never be inlined because "
3144*e4b17023SJohn Marino 		   "it uses non-local goto");
3145*e4b17023SJohn Marino 	    *handled_ops_p = true;
3146*e4b17023SJohn Marino 	    return t;
3147*e4b17023SJohn Marino 
3148*e4b17023SJohn Marino 	  case BUILT_IN_RETURN:
3149*e4b17023SJohn Marino 	  case BUILT_IN_APPLY_ARGS:
3150*e4b17023SJohn Marino 	    /* If a __builtin_apply_args caller would be inlined,
3151*e4b17023SJohn Marino 	       it would be saving arguments of the function it has
3152*e4b17023SJohn Marino 	       been inlined into.  Similarly __builtin_return would
3153*e4b17023SJohn Marino 	       return from the function the inline has been inlined into.  */
3154*e4b17023SJohn Marino 	    inline_forbidden_reason
3155*e4b17023SJohn Marino 	      = G_("function %q+F can never be inlined because "
3156*e4b17023SJohn Marino 		   "it uses __builtin_return or __builtin_apply_args");
3157*e4b17023SJohn Marino 	    *handled_ops_p = true;
3158*e4b17023SJohn Marino 	    return t;
3159*e4b17023SJohn Marino 
3160*e4b17023SJohn Marino 	  default:
3161*e4b17023SJohn Marino 	    break;
3162*e4b17023SJohn Marino 	  }
3163*e4b17023SJohn Marino       break;
3164*e4b17023SJohn Marino 
3165*e4b17023SJohn Marino     case GIMPLE_GOTO:
3166*e4b17023SJohn Marino       t = gimple_goto_dest (stmt);
3167*e4b17023SJohn Marino 
3168*e4b17023SJohn Marino       /* We will not inline a function which uses computed goto.  The
3169*e4b17023SJohn Marino 	 addresses of its local labels, which may be tucked into
3170*e4b17023SJohn Marino 	 global storage, are of course not constant across
3171*e4b17023SJohn Marino 	 instantiations, which causes unexpected behavior.  */
3172*e4b17023SJohn Marino       if (TREE_CODE (t) != LABEL_DECL)
3173*e4b17023SJohn Marino 	{
3174*e4b17023SJohn Marino 	  inline_forbidden_reason
3175*e4b17023SJohn Marino 	    = G_("function %q+F can never be inlined "
3176*e4b17023SJohn Marino 		 "because it contains a computed goto");
3177*e4b17023SJohn Marino 	  *handled_ops_p = true;
3178*e4b17023SJohn Marino 	  return t;
3179*e4b17023SJohn Marino 	}
3180*e4b17023SJohn Marino       break;
3181*e4b17023SJohn Marino 
3182*e4b17023SJohn Marino     default:
3183*e4b17023SJohn Marino       break;
3184*e4b17023SJohn Marino     }
3185*e4b17023SJohn Marino 
3186*e4b17023SJohn Marino   *handled_ops_p = false;
3187*e4b17023SJohn Marino   return NULL_TREE;
3188*e4b17023SJohn Marino }
3189*e4b17023SJohn Marino 
3190*e4b17023SJohn Marino /* Return true if FNDECL is a function that cannot be inlined into
3191*e4b17023SJohn Marino    another one.  */
3192*e4b17023SJohn Marino 
3193*e4b17023SJohn Marino static bool
3194*e4b17023SJohn Marino inline_forbidden_p (tree fndecl)
3195*e4b17023SJohn Marino {
3196*e4b17023SJohn Marino   struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
3197*e4b17023SJohn Marino   struct walk_stmt_info wi;
3198*e4b17023SJohn Marino   struct pointer_set_t *visited_nodes;
3199*e4b17023SJohn Marino   basic_block bb;
3200*e4b17023SJohn Marino   bool forbidden_p = false;
3201*e4b17023SJohn Marino 
3202*e4b17023SJohn Marino   /* First check for shared reasons not to copy the code.  */
3203*e4b17023SJohn Marino   inline_forbidden_reason = copy_forbidden (fun, fndecl);
3204*e4b17023SJohn Marino   if (inline_forbidden_reason != NULL)
3205*e4b17023SJohn Marino     return true;
3206*e4b17023SJohn Marino 
3207*e4b17023SJohn Marino   /* Next, walk the statements of the function looking for
3208*e4b17023SJohn Marino      constraucts we can't handle, or are non-optimal for inlining.  */
3209*e4b17023SJohn Marino   visited_nodes = pointer_set_create ();
3210*e4b17023SJohn Marino   memset (&wi, 0, sizeof (wi));
3211*e4b17023SJohn Marino   wi.info = (void *) fndecl;
3212*e4b17023SJohn Marino   wi.pset = visited_nodes;
3213*e4b17023SJohn Marino 
3214*e4b17023SJohn Marino   FOR_EACH_BB_FN (bb, fun)
3215*e4b17023SJohn Marino     {
3216*e4b17023SJohn Marino       gimple ret;
3217*e4b17023SJohn Marino       gimple_seq seq = bb_seq (bb);
3218*e4b17023SJohn Marino       ret = walk_gimple_seq (seq, inline_forbidden_p_stmt, NULL, &wi);
3219*e4b17023SJohn Marino       forbidden_p = (ret != NULL);
3220*e4b17023SJohn Marino       if (forbidden_p)
3221*e4b17023SJohn Marino 	break;
3222*e4b17023SJohn Marino     }
3223*e4b17023SJohn Marino 
3224*e4b17023SJohn Marino   pointer_set_destroy (visited_nodes);
3225*e4b17023SJohn Marino   return forbidden_p;
3226*e4b17023SJohn Marino }
3227*e4b17023SJohn Marino 
3228*e4b17023SJohn Marino /* Returns nonzero if FN is a function that does not have any
3229*e4b17023SJohn Marino    fundamental inline blocking properties.  */
3230*e4b17023SJohn Marino 
3231*e4b17023SJohn Marino bool
3232*e4b17023SJohn Marino tree_inlinable_function_p (tree fn)
3233*e4b17023SJohn Marino {
3234*e4b17023SJohn Marino   bool inlinable = true;
3235*e4b17023SJohn Marino   bool do_warning;
3236*e4b17023SJohn Marino   tree always_inline;
3237*e4b17023SJohn Marino 
3238*e4b17023SJohn Marino   /* If we've already decided this function shouldn't be inlined,
3239*e4b17023SJohn Marino      there's no need to check again.  */
3240*e4b17023SJohn Marino   if (DECL_UNINLINABLE (fn))
3241*e4b17023SJohn Marino     return false;
3242*e4b17023SJohn Marino 
3243*e4b17023SJohn Marino   /* We only warn for functions declared `inline' by the user.  */
3244*e4b17023SJohn Marino   do_warning = (warn_inline
3245*e4b17023SJohn Marino 		&& DECL_DECLARED_INLINE_P (fn)
3246*e4b17023SJohn Marino 		&& !DECL_NO_INLINE_WARNING_P (fn)
3247*e4b17023SJohn Marino 		&& !DECL_IN_SYSTEM_HEADER (fn));
3248*e4b17023SJohn Marino 
3249*e4b17023SJohn Marino   always_inline = lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn));
3250*e4b17023SJohn Marino 
3251*e4b17023SJohn Marino   if (flag_no_inline
3252*e4b17023SJohn Marino       && always_inline == NULL)
3253*e4b17023SJohn Marino     {
3254*e4b17023SJohn Marino       if (do_warning)
3255*e4b17023SJohn Marino         warning (OPT_Winline, "function %q+F can never be inlined because it "
3256*e4b17023SJohn Marino                  "is suppressed using -fno-inline", fn);
3257*e4b17023SJohn Marino       inlinable = false;
3258*e4b17023SJohn Marino     }
3259*e4b17023SJohn Marino 
3260*e4b17023SJohn Marino   else if (!function_attribute_inlinable_p (fn))
3261*e4b17023SJohn Marino     {
3262*e4b17023SJohn Marino       if (do_warning)
3263*e4b17023SJohn Marino         warning (OPT_Winline, "function %q+F can never be inlined because it "
3264*e4b17023SJohn Marino                  "uses attributes conflicting with inlining", fn);
3265*e4b17023SJohn Marino       inlinable = false;
3266*e4b17023SJohn Marino     }
3267*e4b17023SJohn Marino 
3268*e4b17023SJohn Marino   else if (inline_forbidden_p (fn))
3269*e4b17023SJohn Marino     {
3270*e4b17023SJohn Marino       /* See if we should warn about uninlinable functions.  Previously,
3271*e4b17023SJohn Marino 	 some of these warnings would be issued while trying to expand
3272*e4b17023SJohn Marino 	 the function inline, but that would cause multiple warnings
3273*e4b17023SJohn Marino 	 about functions that would for example call alloca.  But since
3274*e4b17023SJohn Marino 	 this a property of the function, just one warning is enough.
3275*e4b17023SJohn Marino 	 As a bonus we can now give more details about the reason why a
3276*e4b17023SJohn Marino 	 function is not inlinable.  */
3277*e4b17023SJohn Marino       if (always_inline)
3278*e4b17023SJohn Marino 	error (inline_forbidden_reason, fn);
3279*e4b17023SJohn Marino       else if (do_warning)
3280*e4b17023SJohn Marino 	warning (OPT_Winline, inline_forbidden_reason, fn);
3281*e4b17023SJohn Marino 
3282*e4b17023SJohn Marino       inlinable = false;
3283*e4b17023SJohn Marino     }
3284*e4b17023SJohn Marino 
3285*e4b17023SJohn Marino   /* Squirrel away the result so that we don't have to check again.  */
3286*e4b17023SJohn Marino   DECL_UNINLINABLE (fn) = !inlinable;
3287*e4b17023SJohn Marino 
3288*e4b17023SJohn Marino   return inlinable;
3289*e4b17023SJohn Marino }
3290*e4b17023SJohn Marino 
3291*e4b17023SJohn Marino /* Estimate the cost of a memory move.  Use machine dependent
3292*e4b17023SJohn Marino    word size and take possible memcpy call into account.  */
3293*e4b17023SJohn Marino 
3294*e4b17023SJohn Marino int
3295*e4b17023SJohn Marino estimate_move_cost (tree type)
3296*e4b17023SJohn Marino {
3297*e4b17023SJohn Marino   HOST_WIDE_INT size;
3298*e4b17023SJohn Marino 
3299*e4b17023SJohn Marino   gcc_assert (!VOID_TYPE_P (type));
3300*e4b17023SJohn Marino 
3301*e4b17023SJohn Marino   if (TREE_CODE (type) == VECTOR_TYPE)
3302*e4b17023SJohn Marino     {
3303*e4b17023SJohn Marino       enum machine_mode inner = TYPE_MODE (TREE_TYPE (type));
3304*e4b17023SJohn Marino       enum machine_mode simd
3305*e4b17023SJohn Marino 	= targetm.vectorize.preferred_simd_mode (inner);
3306*e4b17023SJohn Marino       int simd_mode_size = GET_MODE_SIZE (simd);
3307*e4b17023SJohn Marino       return ((GET_MODE_SIZE (TYPE_MODE (type)) + simd_mode_size - 1)
3308*e4b17023SJohn Marino 	      / simd_mode_size);
3309*e4b17023SJohn Marino     }
3310*e4b17023SJohn Marino 
3311*e4b17023SJohn Marino   size = int_size_in_bytes (type);
3312*e4b17023SJohn Marino 
3313*e4b17023SJohn Marino   if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO (!optimize_size))
3314*e4b17023SJohn Marino     /* Cost of a memcpy call, 3 arguments and the call.  */
3315*e4b17023SJohn Marino     return 4;
3316*e4b17023SJohn Marino   else
3317*e4b17023SJohn Marino     return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
3318*e4b17023SJohn Marino }
3319*e4b17023SJohn Marino 
3320*e4b17023SJohn Marino /* Returns cost of operation CODE, according to WEIGHTS  */
3321*e4b17023SJohn Marino 
3322*e4b17023SJohn Marino static int
3323*e4b17023SJohn Marino estimate_operator_cost (enum tree_code code, eni_weights *weights,
3324*e4b17023SJohn Marino 			tree op1 ATTRIBUTE_UNUSED, tree op2)
3325*e4b17023SJohn Marino {
3326*e4b17023SJohn Marino   switch (code)
3327*e4b17023SJohn Marino     {
3328*e4b17023SJohn Marino     /* These are "free" conversions, or their presumed cost
3329*e4b17023SJohn Marino        is folded into other operations.  */
3330*e4b17023SJohn Marino     case RANGE_EXPR:
3331*e4b17023SJohn Marino     CASE_CONVERT:
3332*e4b17023SJohn Marino     case COMPLEX_EXPR:
3333*e4b17023SJohn Marino     case PAREN_EXPR:
3334*e4b17023SJohn Marino     case VIEW_CONVERT_EXPR:
3335*e4b17023SJohn Marino       return 0;
3336*e4b17023SJohn Marino 
3337*e4b17023SJohn Marino     /* Assign cost of 1 to usual operations.
3338*e4b17023SJohn Marino        ??? We may consider mapping RTL costs to this.  */
3339*e4b17023SJohn Marino     case COND_EXPR:
3340*e4b17023SJohn Marino     case VEC_COND_EXPR:
3341*e4b17023SJohn Marino     case VEC_PERM_EXPR:
3342*e4b17023SJohn Marino 
3343*e4b17023SJohn Marino     case PLUS_EXPR:
3344*e4b17023SJohn Marino     case POINTER_PLUS_EXPR:
3345*e4b17023SJohn Marino     case MINUS_EXPR:
3346*e4b17023SJohn Marino     case MULT_EXPR:
3347*e4b17023SJohn Marino     case FMA_EXPR:
3348*e4b17023SJohn Marino 
3349*e4b17023SJohn Marino     case ADDR_SPACE_CONVERT_EXPR:
3350*e4b17023SJohn Marino     case FIXED_CONVERT_EXPR:
3351*e4b17023SJohn Marino     case FIX_TRUNC_EXPR:
3352*e4b17023SJohn Marino 
3353*e4b17023SJohn Marino     case NEGATE_EXPR:
3354*e4b17023SJohn Marino     case FLOAT_EXPR:
3355*e4b17023SJohn Marino     case MIN_EXPR:
3356*e4b17023SJohn Marino     case MAX_EXPR:
3357*e4b17023SJohn Marino     case ABS_EXPR:
3358*e4b17023SJohn Marino 
3359*e4b17023SJohn Marino     case LSHIFT_EXPR:
3360*e4b17023SJohn Marino     case RSHIFT_EXPR:
3361*e4b17023SJohn Marino     case LROTATE_EXPR:
3362*e4b17023SJohn Marino     case RROTATE_EXPR:
3363*e4b17023SJohn Marino     case VEC_LSHIFT_EXPR:
3364*e4b17023SJohn Marino     case VEC_RSHIFT_EXPR:
3365*e4b17023SJohn Marino 
3366*e4b17023SJohn Marino     case BIT_IOR_EXPR:
3367*e4b17023SJohn Marino     case BIT_XOR_EXPR:
3368*e4b17023SJohn Marino     case BIT_AND_EXPR:
3369*e4b17023SJohn Marino     case BIT_NOT_EXPR:
3370*e4b17023SJohn Marino 
3371*e4b17023SJohn Marino     case TRUTH_ANDIF_EXPR:
3372*e4b17023SJohn Marino     case TRUTH_ORIF_EXPR:
3373*e4b17023SJohn Marino     case TRUTH_AND_EXPR:
3374*e4b17023SJohn Marino     case TRUTH_OR_EXPR:
3375*e4b17023SJohn Marino     case TRUTH_XOR_EXPR:
3376*e4b17023SJohn Marino     case TRUTH_NOT_EXPR:
3377*e4b17023SJohn Marino 
3378*e4b17023SJohn Marino     case LT_EXPR:
3379*e4b17023SJohn Marino     case LE_EXPR:
3380*e4b17023SJohn Marino     case GT_EXPR:
3381*e4b17023SJohn Marino     case GE_EXPR:
3382*e4b17023SJohn Marino     case EQ_EXPR:
3383*e4b17023SJohn Marino     case NE_EXPR:
3384*e4b17023SJohn Marino     case ORDERED_EXPR:
3385*e4b17023SJohn Marino     case UNORDERED_EXPR:
3386*e4b17023SJohn Marino 
3387*e4b17023SJohn Marino     case UNLT_EXPR:
3388*e4b17023SJohn Marino     case UNLE_EXPR:
3389*e4b17023SJohn Marino     case UNGT_EXPR:
3390*e4b17023SJohn Marino     case UNGE_EXPR:
3391*e4b17023SJohn Marino     case UNEQ_EXPR:
3392*e4b17023SJohn Marino     case LTGT_EXPR:
3393*e4b17023SJohn Marino 
3394*e4b17023SJohn Marino     case CONJ_EXPR:
3395*e4b17023SJohn Marino 
3396*e4b17023SJohn Marino     case PREDECREMENT_EXPR:
3397*e4b17023SJohn Marino     case PREINCREMENT_EXPR:
3398*e4b17023SJohn Marino     case POSTDECREMENT_EXPR:
3399*e4b17023SJohn Marino     case POSTINCREMENT_EXPR:
3400*e4b17023SJohn Marino 
3401*e4b17023SJohn Marino     case REALIGN_LOAD_EXPR:
3402*e4b17023SJohn Marino 
3403*e4b17023SJohn Marino     case REDUC_MAX_EXPR:
3404*e4b17023SJohn Marino     case REDUC_MIN_EXPR:
3405*e4b17023SJohn Marino     case REDUC_PLUS_EXPR:
3406*e4b17023SJohn Marino     case WIDEN_SUM_EXPR:
3407*e4b17023SJohn Marino     case WIDEN_MULT_EXPR:
3408*e4b17023SJohn Marino     case DOT_PROD_EXPR:
3409*e4b17023SJohn Marino     case WIDEN_MULT_PLUS_EXPR:
3410*e4b17023SJohn Marino     case WIDEN_MULT_MINUS_EXPR:
3411*e4b17023SJohn Marino     case WIDEN_LSHIFT_EXPR:
3412*e4b17023SJohn Marino 
3413*e4b17023SJohn Marino     case VEC_WIDEN_MULT_HI_EXPR:
3414*e4b17023SJohn Marino     case VEC_WIDEN_MULT_LO_EXPR:
3415*e4b17023SJohn Marino     case VEC_UNPACK_HI_EXPR:
3416*e4b17023SJohn Marino     case VEC_UNPACK_LO_EXPR:
3417*e4b17023SJohn Marino     case VEC_UNPACK_FLOAT_HI_EXPR:
3418*e4b17023SJohn Marino     case VEC_UNPACK_FLOAT_LO_EXPR:
3419*e4b17023SJohn Marino     case VEC_PACK_TRUNC_EXPR:
3420*e4b17023SJohn Marino     case VEC_PACK_SAT_EXPR:
3421*e4b17023SJohn Marino     case VEC_PACK_FIX_TRUNC_EXPR:
3422*e4b17023SJohn Marino     case VEC_WIDEN_LSHIFT_HI_EXPR:
3423*e4b17023SJohn Marino     case VEC_WIDEN_LSHIFT_LO_EXPR:
3424*e4b17023SJohn Marino 
3425*e4b17023SJohn Marino       return 1;
3426*e4b17023SJohn Marino 
3427*e4b17023SJohn Marino     /* Few special cases of expensive operations.  This is useful
3428*e4b17023SJohn Marino        to avoid inlining on functions having too many of these.  */
3429*e4b17023SJohn Marino     case TRUNC_DIV_EXPR:
3430*e4b17023SJohn Marino     case CEIL_DIV_EXPR:
3431*e4b17023SJohn Marino     case FLOOR_DIV_EXPR:
3432*e4b17023SJohn Marino     case ROUND_DIV_EXPR:
3433*e4b17023SJohn Marino     case EXACT_DIV_EXPR:
3434*e4b17023SJohn Marino     case TRUNC_MOD_EXPR:
3435*e4b17023SJohn Marino     case CEIL_MOD_EXPR:
3436*e4b17023SJohn Marino     case FLOOR_MOD_EXPR:
3437*e4b17023SJohn Marino     case ROUND_MOD_EXPR:
3438*e4b17023SJohn Marino     case RDIV_EXPR:
3439*e4b17023SJohn Marino       if (TREE_CODE (op2) != INTEGER_CST)
3440*e4b17023SJohn Marino         return weights->div_mod_cost;
3441*e4b17023SJohn Marino       return 1;
3442*e4b17023SJohn Marino 
3443*e4b17023SJohn Marino     default:
3444*e4b17023SJohn Marino       /* We expect a copy assignment with no operator.  */
3445*e4b17023SJohn Marino       gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS);
3446*e4b17023SJohn Marino       return 0;
3447*e4b17023SJohn Marino     }
3448*e4b17023SJohn Marino }
3449*e4b17023SJohn Marino 
3450*e4b17023SJohn Marino 
3451*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding
3452*e4b17023SJohn Marino    the statements in the statement sequence STMTS.
3453*e4b17023SJohn Marino    WEIGHTS contains weights attributed to various constructs.  */
3454*e4b17023SJohn Marino 
3455*e4b17023SJohn Marino static
3456*e4b17023SJohn Marino int estimate_num_insns_seq (gimple_seq stmts, eni_weights *weights)
3457*e4b17023SJohn Marino {
3458*e4b17023SJohn Marino   int cost;
3459*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
3460*e4b17023SJohn Marino 
3461*e4b17023SJohn Marino   cost = 0;
3462*e4b17023SJohn Marino   for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
3463*e4b17023SJohn Marino     cost += estimate_num_insns (gsi_stmt (gsi), weights);
3464*e4b17023SJohn Marino 
3465*e4b17023SJohn Marino   return cost;
3466*e4b17023SJohn Marino }
3467*e4b17023SJohn Marino 
3468*e4b17023SJohn Marino 
3469*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding STMT.
3470*e4b17023SJohn Marino    WEIGHTS contains weights attributed to various constructs.  */
3471*e4b17023SJohn Marino 
3472*e4b17023SJohn Marino int
3473*e4b17023SJohn Marino estimate_num_insns (gimple stmt, eni_weights *weights)
3474*e4b17023SJohn Marino {
3475*e4b17023SJohn Marino   unsigned cost, i;
3476*e4b17023SJohn Marino   enum gimple_code code = gimple_code (stmt);
3477*e4b17023SJohn Marino   tree lhs;
3478*e4b17023SJohn Marino   tree rhs;
3479*e4b17023SJohn Marino 
3480*e4b17023SJohn Marino   switch (code)
3481*e4b17023SJohn Marino     {
3482*e4b17023SJohn Marino     case GIMPLE_ASSIGN:
3483*e4b17023SJohn Marino       /* Try to estimate the cost of assignments.  We have three cases to
3484*e4b17023SJohn Marino 	 deal with:
3485*e4b17023SJohn Marino 	 1) Simple assignments to registers;
3486*e4b17023SJohn Marino 	 2) Stores to things that must live in memory.  This includes
3487*e4b17023SJohn Marino 	    "normal" stores to scalars, but also assignments of large
3488*e4b17023SJohn Marino 	    structures, or constructors of big arrays;
3489*e4b17023SJohn Marino 
3490*e4b17023SJohn Marino 	 Let us look at the first two cases, assuming we have "a = b + C":
3491*e4b17023SJohn Marino 	 <GIMPLE_ASSIGN <var_decl "a">
3492*e4b17023SJohn Marino 	        <plus_expr <var_decl "b"> <constant C>>
3493*e4b17023SJohn Marino 	 If "a" is a GIMPLE register, the assignment to it is free on almost
3494*e4b17023SJohn Marino 	 any target, because "a" usually ends up in a real register.  Hence
3495*e4b17023SJohn Marino 	 the only cost of this expression comes from the PLUS_EXPR, and we
3496*e4b17023SJohn Marino 	 can ignore the GIMPLE_ASSIGN.
3497*e4b17023SJohn Marino 	 If "a" is not a GIMPLE register, the assignment to "a" will most
3498*e4b17023SJohn Marino 	 likely be a real store, so the cost of the GIMPLE_ASSIGN is the cost
3499*e4b17023SJohn Marino 	 of moving something into "a", which we compute using the function
3500*e4b17023SJohn Marino 	 estimate_move_cost.  */
3501*e4b17023SJohn Marino       if (gimple_clobber_p (stmt))
3502*e4b17023SJohn Marino 	return 0;	/* ={v} {CLOBBER} stmt expands to nothing.  */
3503*e4b17023SJohn Marino 
3504*e4b17023SJohn Marino       lhs = gimple_assign_lhs (stmt);
3505*e4b17023SJohn Marino       rhs = gimple_assign_rhs1 (stmt);
3506*e4b17023SJohn Marino 
3507*e4b17023SJohn Marino       if (is_gimple_reg (lhs))
3508*e4b17023SJohn Marino 	cost = 0;
3509*e4b17023SJohn Marino       else
3510*e4b17023SJohn Marino 	cost = estimate_move_cost (TREE_TYPE (lhs));
3511*e4b17023SJohn Marino 
3512*e4b17023SJohn Marino       if (!is_gimple_reg (rhs) && !is_gimple_min_invariant (rhs))
3513*e4b17023SJohn Marino 	cost += estimate_move_cost (TREE_TYPE (rhs));
3514*e4b17023SJohn Marino 
3515*e4b17023SJohn Marino       cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights,
3516*e4b17023SJohn Marino       				      gimple_assign_rhs1 (stmt),
3517*e4b17023SJohn Marino 				      get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
3518*e4b17023SJohn Marino 				      == GIMPLE_BINARY_RHS
3519*e4b17023SJohn Marino 				      ? gimple_assign_rhs2 (stmt) : NULL);
3520*e4b17023SJohn Marino       break;
3521*e4b17023SJohn Marino 
3522*e4b17023SJohn Marino     case GIMPLE_COND:
3523*e4b17023SJohn Marino       cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights,
3524*e4b17023SJohn Marino       				         gimple_op (stmt, 0),
3525*e4b17023SJohn Marino 				         gimple_op (stmt, 1));
3526*e4b17023SJohn Marino       break;
3527*e4b17023SJohn Marino 
3528*e4b17023SJohn Marino     case GIMPLE_SWITCH:
3529*e4b17023SJohn Marino       /* Take into account cost of the switch + guess 2 conditional jumps for
3530*e4b17023SJohn Marino          each case label.
3531*e4b17023SJohn Marino 
3532*e4b17023SJohn Marino 	 TODO: once the switch expansion logic is sufficiently separated, we can
3533*e4b17023SJohn Marino 	 do better job on estimating cost of the switch.  */
3534*e4b17023SJohn Marino       if (weights->time_based)
3535*e4b17023SJohn Marino         cost = floor_log2 (gimple_switch_num_labels (stmt)) * 2;
3536*e4b17023SJohn Marino       else
3537*e4b17023SJohn Marino         cost = gimple_switch_num_labels (stmt) * 2;
3538*e4b17023SJohn Marino       break;
3539*e4b17023SJohn Marino 
3540*e4b17023SJohn Marino     case GIMPLE_CALL:
3541*e4b17023SJohn Marino       {
3542*e4b17023SJohn Marino 	tree decl = gimple_call_fndecl (stmt);
3543*e4b17023SJohn Marino 	struct cgraph_node *node = NULL;
3544*e4b17023SJohn Marino 
3545*e4b17023SJohn Marino 	/* Do not special case builtins where we see the body.
3546*e4b17023SJohn Marino 	   This just confuse inliner.  */
3547*e4b17023SJohn Marino 	if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed)
3548*e4b17023SJohn Marino 	  ;
3549*e4b17023SJohn Marino 	/* For buitins that are likely expanded to nothing or
3550*e4b17023SJohn Marino 	   inlined do not account operand costs.  */
3551*e4b17023SJohn Marino 	else if (is_simple_builtin (decl))
3552*e4b17023SJohn Marino 	  return 0;
3553*e4b17023SJohn Marino 	else if (is_inexpensive_builtin (decl))
3554*e4b17023SJohn Marino 	  return weights->target_builtin_call_cost;
3555*e4b17023SJohn Marino 	else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
3556*e4b17023SJohn Marino 	  {
3557*e4b17023SJohn Marino 	    /* We canonicalize x * x to pow (x, 2.0) with -ffast-math, so
3558*e4b17023SJohn Marino 	       specialize the cheap expansion we do here.
3559*e4b17023SJohn Marino 	       ???  This asks for a more general solution.  */
3560*e4b17023SJohn Marino 	    switch (DECL_FUNCTION_CODE (decl))
3561*e4b17023SJohn Marino 	      {
3562*e4b17023SJohn Marino 		case BUILT_IN_POW:
3563*e4b17023SJohn Marino 		case BUILT_IN_POWF:
3564*e4b17023SJohn Marino 		case BUILT_IN_POWL:
3565*e4b17023SJohn Marino 		  if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
3566*e4b17023SJohn Marino 		      && REAL_VALUES_EQUAL
3567*e4b17023SJohn Marino 			   (TREE_REAL_CST (gimple_call_arg (stmt, 1)), dconst2))
3568*e4b17023SJohn Marino 		    return estimate_operator_cost (MULT_EXPR, weights,
3569*e4b17023SJohn Marino 						   gimple_call_arg (stmt, 0),
3570*e4b17023SJohn Marino 						   gimple_call_arg (stmt, 0));
3571*e4b17023SJohn Marino 		  break;
3572*e4b17023SJohn Marino 
3573*e4b17023SJohn Marino 		default:
3574*e4b17023SJohn Marino 		  break;
3575*e4b17023SJohn Marino 	      }
3576*e4b17023SJohn Marino 	  }
3577*e4b17023SJohn Marino 
3578*e4b17023SJohn Marino 	cost = node ? weights->call_cost : weights->indirect_call_cost;
3579*e4b17023SJohn Marino 	if (gimple_call_lhs (stmt))
3580*e4b17023SJohn Marino 	  cost += estimate_move_cost (TREE_TYPE (gimple_call_lhs (stmt)));
3581*e4b17023SJohn Marino 	for (i = 0; i < gimple_call_num_args (stmt); i++)
3582*e4b17023SJohn Marino 	  {
3583*e4b17023SJohn Marino 	    tree arg = gimple_call_arg (stmt, i);
3584*e4b17023SJohn Marino 	    cost += estimate_move_cost (TREE_TYPE (arg));
3585*e4b17023SJohn Marino 	  }
3586*e4b17023SJohn Marino 	break;
3587*e4b17023SJohn Marino       }
3588*e4b17023SJohn Marino 
3589*e4b17023SJohn Marino     case GIMPLE_RETURN:
3590*e4b17023SJohn Marino       return weights->return_cost;
3591*e4b17023SJohn Marino 
3592*e4b17023SJohn Marino     case GIMPLE_GOTO:
3593*e4b17023SJohn Marino     case GIMPLE_LABEL:
3594*e4b17023SJohn Marino     case GIMPLE_NOP:
3595*e4b17023SJohn Marino     case GIMPLE_PHI:
3596*e4b17023SJohn Marino     case GIMPLE_PREDICT:
3597*e4b17023SJohn Marino     case GIMPLE_DEBUG:
3598*e4b17023SJohn Marino       return 0;
3599*e4b17023SJohn Marino 
3600*e4b17023SJohn Marino     case GIMPLE_ASM:
3601*e4b17023SJohn Marino       return asm_str_count (gimple_asm_string (stmt));
3602*e4b17023SJohn Marino 
3603*e4b17023SJohn Marino     case GIMPLE_RESX:
3604*e4b17023SJohn Marino       /* This is either going to be an external function call with one
3605*e4b17023SJohn Marino 	 argument, or two register copy statements plus a goto.  */
3606*e4b17023SJohn Marino       return 2;
3607*e4b17023SJohn Marino 
3608*e4b17023SJohn Marino     case GIMPLE_EH_DISPATCH:
3609*e4b17023SJohn Marino       /* ??? This is going to turn into a switch statement.  Ideally
3610*e4b17023SJohn Marino 	 we'd have a look at the eh region and estimate the number of
3611*e4b17023SJohn Marino 	 edges involved.  */
3612*e4b17023SJohn Marino       return 10;
3613*e4b17023SJohn Marino 
3614*e4b17023SJohn Marino     case GIMPLE_BIND:
3615*e4b17023SJohn Marino       return estimate_num_insns_seq (gimple_bind_body (stmt), weights);
3616*e4b17023SJohn Marino 
3617*e4b17023SJohn Marino     case GIMPLE_EH_FILTER:
3618*e4b17023SJohn Marino       return estimate_num_insns_seq (gimple_eh_filter_failure (stmt), weights);
3619*e4b17023SJohn Marino 
3620*e4b17023SJohn Marino     case GIMPLE_CATCH:
3621*e4b17023SJohn Marino       return estimate_num_insns_seq (gimple_catch_handler (stmt), weights);
3622*e4b17023SJohn Marino 
3623*e4b17023SJohn Marino     case GIMPLE_TRY:
3624*e4b17023SJohn Marino       return (estimate_num_insns_seq (gimple_try_eval (stmt), weights)
3625*e4b17023SJohn Marino               + estimate_num_insns_seq (gimple_try_cleanup (stmt), weights));
3626*e4b17023SJohn Marino 
3627*e4b17023SJohn Marino     /* OpenMP directives are generally very expensive.  */
3628*e4b17023SJohn Marino 
3629*e4b17023SJohn Marino     case GIMPLE_OMP_RETURN:
3630*e4b17023SJohn Marino     case GIMPLE_OMP_SECTIONS_SWITCH:
3631*e4b17023SJohn Marino     case GIMPLE_OMP_ATOMIC_STORE:
3632*e4b17023SJohn Marino     case GIMPLE_OMP_CONTINUE:
3633*e4b17023SJohn Marino       /* ...except these, which are cheap.  */
3634*e4b17023SJohn Marino       return 0;
3635*e4b17023SJohn Marino 
3636*e4b17023SJohn Marino     case GIMPLE_OMP_ATOMIC_LOAD:
3637*e4b17023SJohn Marino       return weights->omp_cost;
3638*e4b17023SJohn Marino 
3639*e4b17023SJohn Marino     case GIMPLE_OMP_FOR:
3640*e4b17023SJohn Marino       return (weights->omp_cost
3641*e4b17023SJohn Marino               + estimate_num_insns_seq (gimple_omp_body (stmt), weights)
3642*e4b17023SJohn Marino               + estimate_num_insns_seq (gimple_omp_for_pre_body (stmt), weights));
3643*e4b17023SJohn Marino 
3644*e4b17023SJohn Marino     case GIMPLE_OMP_PARALLEL:
3645*e4b17023SJohn Marino     case GIMPLE_OMP_TASK:
3646*e4b17023SJohn Marino     case GIMPLE_OMP_CRITICAL:
3647*e4b17023SJohn Marino     case GIMPLE_OMP_MASTER:
3648*e4b17023SJohn Marino     case GIMPLE_OMP_ORDERED:
3649*e4b17023SJohn Marino     case GIMPLE_OMP_SECTION:
3650*e4b17023SJohn Marino     case GIMPLE_OMP_SECTIONS:
3651*e4b17023SJohn Marino     case GIMPLE_OMP_SINGLE:
3652*e4b17023SJohn Marino       return (weights->omp_cost
3653*e4b17023SJohn Marino               + estimate_num_insns_seq (gimple_omp_body (stmt), weights));
3654*e4b17023SJohn Marino 
3655*e4b17023SJohn Marino     case GIMPLE_TRANSACTION:
3656*e4b17023SJohn Marino       return (weights->tm_cost
3657*e4b17023SJohn Marino 	      + estimate_num_insns_seq (gimple_transaction_body (stmt),
3658*e4b17023SJohn Marino 					weights));
3659*e4b17023SJohn Marino 
3660*e4b17023SJohn Marino     default:
3661*e4b17023SJohn Marino       gcc_unreachable ();
3662*e4b17023SJohn Marino     }
3663*e4b17023SJohn Marino 
3664*e4b17023SJohn Marino   return cost;
3665*e4b17023SJohn Marino }
3666*e4b17023SJohn Marino 
3667*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding
3668*e4b17023SJohn Marino    function FNDECL.  WEIGHTS contains weights attributed to various
3669*e4b17023SJohn Marino    constructs.  */
3670*e4b17023SJohn Marino 
3671*e4b17023SJohn Marino int
3672*e4b17023SJohn Marino estimate_num_insns_fn (tree fndecl, eni_weights *weights)
3673*e4b17023SJohn Marino {
3674*e4b17023SJohn Marino   struct function *my_function = DECL_STRUCT_FUNCTION (fndecl);
3675*e4b17023SJohn Marino   gimple_stmt_iterator bsi;
3676*e4b17023SJohn Marino   basic_block bb;
3677*e4b17023SJohn Marino   int n = 0;
3678*e4b17023SJohn Marino 
3679*e4b17023SJohn Marino   gcc_assert (my_function && my_function->cfg);
3680*e4b17023SJohn Marino   FOR_EACH_BB_FN (bb, my_function)
3681*e4b17023SJohn Marino     {
3682*e4b17023SJohn Marino       for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
3683*e4b17023SJohn Marino 	n += estimate_num_insns (gsi_stmt (bsi), weights);
3684*e4b17023SJohn Marino     }
3685*e4b17023SJohn Marino 
3686*e4b17023SJohn Marino   return n;
3687*e4b17023SJohn Marino }
3688*e4b17023SJohn Marino 
3689*e4b17023SJohn Marino 
3690*e4b17023SJohn Marino /* Initializes weights used by estimate_num_insns.  */
3691*e4b17023SJohn Marino 
3692*e4b17023SJohn Marino void
3693*e4b17023SJohn Marino init_inline_once (void)
3694*e4b17023SJohn Marino {
3695*e4b17023SJohn Marino   eni_size_weights.call_cost = 1;
3696*e4b17023SJohn Marino   eni_size_weights.indirect_call_cost = 3;
3697*e4b17023SJohn Marino   eni_size_weights.target_builtin_call_cost = 1;
3698*e4b17023SJohn Marino   eni_size_weights.div_mod_cost = 1;
3699*e4b17023SJohn Marino   eni_size_weights.omp_cost = 40;
3700*e4b17023SJohn Marino   eni_size_weights.tm_cost = 10;
3701*e4b17023SJohn Marino   eni_size_weights.time_based = false;
3702*e4b17023SJohn Marino   eni_size_weights.return_cost = 1;
3703*e4b17023SJohn Marino 
3704*e4b17023SJohn Marino   /* Estimating time for call is difficult, since we have no idea what the
3705*e4b17023SJohn Marino      called function does.  In the current uses of eni_time_weights,
3706*e4b17023SJohn Marino      underestimating the cost does less harm than overestimating it, so
3707*e4b17023SJohn Marino      we choose a rather small value here.  */
3708*e4b17023SJohn Marino   eni_time_weights.call_cost = 10;
3709*e4b17023SJohn Marino   eni_time_weights.indirect_call_cost = 15;
3710*e4b17023SJohn Marino   eni_time_weights.target_builtin_call_cost = 1;
3711*e4b17023SJohn Marino   eni_time_weights.div_mod_cost = 10;
3712*e4b17023SJohn Marino   eni_time_weights.omp_cost = 40;
3713*e4b17023SJohn Marino   eni_time_weights.tm_cost = 40;
3714*e4b17023SJohn Marino   eni_time_weights.time_based = true;
3715*e4b17023SJohn Marino   eni_time_weights.return_cost = 2;
3716*e4b17023SJohn Marino }
3717*e4b17023SJohn Marino 
3718*e4b17023SJohn Marino /* Estimate the number of instructions in a gimple_seq. */
3719*e4b17023SJohn Marino 
3720*e4b17023SJohn Marino int
3721*e4b17023SJohn Marino count_insns_seq (gimple_seq seq, eni_weights *weights)
3722*e4b17023SJohn Marino {
3723*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
3724*e4b17023SJohn Marino   int n = 0;
3725*e4b17023SJohn Marino   for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
3726*e4b17023SJohn Marino     n += estimate_num_insns (gsi_stmt (gsi), weights);
3727*e4b17023SJohn Marino 
3728*e4b17023SJohn Marino   return n;
3729*e4b17023SJohn Marino }
3730*e4b17023SJohn Marino 
3731*e4b17023SJohn Marino 
3732*e4b17023SJohn Marino /* Install new lexical TREE_BLOCK underneath 'current_block'.  */
3733*e4b17023SJohn Marino 
3734*e4b17023SJohn Marino static void
3735*e4b17023SJohn Marino prepend_lexical_block (tree current_block, tree new_block)
3736*e4b17023SJohn Marino {
3737*e4b17023SJohn Marino   BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (current_block);
3738*e4b17023SJohn Marino   BLOCK_SUBBLOCKS (current_block) = new_block;
3739*e4b17023SJohn Marino   BLOCK_SUPERCONTEXT (new_block) = current_block;
3740*e4b17023SJohn Marino }
3741*e4b17023SJohn Marino 
3742*e4b17023SJohn Marino /* Add local variables from CALLEE to CALLER.  */
3743*e4b17023SJohn Marino 
3744*e4b17023SJohn Marino static inline void
3745*e4b17023SJohn Marino add_local_variables (struct function *callee, struct function *caller,
3746*e4b17023SJohn Marino 		     copy_body_data *id, bool check_var_ann)
3747*e4b17023SJohn Marino {
3748*e4b17023SJohn Marino   tree var;
3749*e4b17023SJohn Marino   unsigned ix;
3750*e4b17023SJohn Marino 
3751*e4b17023SJohn Marino   FOR_EACH_LOCAL_DECL (callee, ix, var)
3752*e4b17023SJohn Marino     if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
3753*e4b17023SJohn Marino       {
3754*e4b17023SJohn Marino 	if (!check_var_ann
3755*e4b17023SJohn Marino 	    || (var_ann (var) && add_referenced_var (var)))
3756*e4b17023SJohn Marino 	  add_local_decl (caller, var);
3757*e4b17023SJohn Marino       }
3758*e4b17023SJohn Marino     else if (!can_be_nonlocal (var, id))
3759*e4b17023SJohn Marino       {
3760*e4b17023SJohn Marino         tree new_var = remap_decl (var, id);
3761*e4b17023SJohn Marino 
3762*e4b17023SJohn Marino         /* Remap debug-expressions.  */
3763*e4b17023SJohn Marino 	if (TREE_CODE (new_var) == VAR_DECL
3764*e4b17023SJohn Marino 	    && DECL_DEBUG_EXPR_IS_FROM (new_var)
3765*e4b17023SJohn Marino 	    && new_var != var)
3766*e4b17023SJohn Marino 	  {
3767*e4b17023SJohn Marino 	    tree tem = DECL_DEBUG_EXPR (var);
3768*e4b17023SJohn Marino 	    bool old_regimplify = id->regimplify;
3769*e4b17023SJohn Marino 	    id->remapping_type_depth++;
3770*e4b17023SJohn Marino 	    walk_tree (&tem, copy_tree_body_r, id, NULL);
3771*e4b17023SJohn Marino 	    id->remapping_type_depth--;
3772*e4b17023SJohn Marino 	    id->regimplify = old_regimplify;
3773*e4b17023SJohn Marino 	    SET_DECL_DEBUG_EXPR (new_var, tem);
3774*e4b17023SJohn Marino 	  }
3775*e4b17023SJohn Marino 	add_local_decl (caller, new_var);
3776*e4b17023SJohn Marino       }
3777*e4b17023SJohn Marino }
3778*e4b17023SJohn Marino 
3779*e4b17023SJohn Marino /* If STMT is a GIMPLE_CALL, replace it with its inline expansion.  */
3780*e4b17023SJohn Marino 
3781*e4b17023SJohn Marino static bool
3782*e4b17023SJohn Marino expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
3783*e4b17023SJohn Marino {
3784*e4b17023SJohn Marino   tree use_retvar;
3785*e4b17023SJohn Marino   tree fn;
3786*e4b17023SJohn Marino   struct pointer_map_t *st, *dst;
3787*e4b17023SJohn Marino   tree return_slot;
3788*e4b17023SJohn Marino   tree modify_dest;
3789*e4b17023SJohn Marino   location_t saved_location;
3790*e4b17023SJohn Marino   struct cgraph_edge *cg_edge;
3791*e4b17023SJohn Marino   cgraph_inline_failed_t reason;
3792*e4b17023SJohn Marino   basic_block return_block;
3793*e4b17023SJohn Marino   edge e;
3794*e4b17023SJohn Marino   gimple_stmt_iterator gsi, stmt_gsi;
3795*e4b17023SJohn Marino   bool successfully_inlined = FALSE;
3796*e4b17023SJohn Marino   bool purge_dead_abnormal_edges;
3797*e4b17023SJohn Marino 
3798*e4b17023SJohn Marino   /* Set input_location here so we get the right instantiation context
3799*e4b17023SJohn Marino      if we call instantiate_decl from inlinable_function_p.  */
3800*e4b17023SJohn Marino   saved_location = input_location;
3801*e4b17023SJohn Marino   if (gimple_has_location (stmt))
3802*e4b17023SJohn Marino     input_location = gimple_location (stmt);
3803*e4b17023SJohn Marino 
3804*e4b17023SJohn Marino   /* From here on, we're only interested in CALL_EXPRs.  */
3805*e4b17023SJohn Marino   if (gimple_code (stmt) != GIMPLE_CALL)
3806*e4b17023SJohn Marino     goto egress;
3807*e4b17023SJohn Marino 
3808*e4b17023SJohn Marino   cg_edge = cgraph_edge (id->dst_node, stmt);
3809*e4b17023SJohn Marino   gcc_checking_assert (cg_edge);
3810*e4b17023SJohn Marino   /* First, see if we can figure out what function is being called.
3811*e4b17023SJohn Marino      If we cannot, then there is no hope of inlining the function.  */
3812*e4b17023SJohn Marino   if (cg_edge->indirect_unknown_callee)
3813*e4b17023SJohn Marino     goto egress;
3814*e4b17023SJohn Marino   fn = cg_edge->callee->decl;
3815*e4b17023SJohn Marino   gcc_checking_assert (fn);
3816*e4b17023SJohn Marino 
3817*e4b17023SJohn Marino   /* If FN is a declaration of a function in a nested scope that was
3818*e4b17023SJohn Marino      globally declared inline, we don't set its DECL_INITIAL.
3819*e4b17023SJohn Marino      However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the
3820*e4b17023SJohn Marino      C++ front-end uses it for cdtors to refer to their internal
3821*e4b17023SJohn Marino      declarations, that are not real functions.  Fortunately those
3822*e4b17023SJohn Marino      don't have trees to be saved, so we can tell by checking their
3823*e4b17023SJohn Marino      gimple_body.  */
3824*e4b17023SJohn Marino   if (!DECL_INITIAL (fn)
3825*e4b17023SJohn Marino       && DECL_ABSTRACT_ORIGIN (fn)
3826*e4b17023SJohn Marino       && gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
3827*e4b17023SJohn Marino     fn = DECL_ABSTRACT_ORIGIN (fn);
3828*e4b17023SJohn Marino 
3829*e4b17023SJohn Marino   /* Don't try to inline functions that are not well-suited to inlining.  */
3830*e4b17023SJohn Marino   if (!cgraph_inline_p (cg_edge, &reason))
3831*e4b17023SJohn Marino     {
3832*e4b17023SJohn Marino       /* If this call was originally indirect, we do not want to emit any
3833*e4b17023SJohn Marino 	 inlining related warnings or sorry messages because there are no
3834*e4b17023SJohn Marino 	 guarantees regarding those.  */
3835*e4b17023SJohn Marino       if (cg_edge->indirect_inlining_edge)
3836*e4b17023SJohn Marino 	goto egress;
3837*e4b17023SJohn Marino 
3838*e4b17023SJohn Marino       if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
3839*e4b17023SJohn Marino 	  /* Avoid warnings during early inline pass. */
3840*e4b17023SJohn Marino 	  && cgraph_global_info_ready
3841*e4b17023SJohn Marino 	  /* PR 20090218-1_0.c. Body can be provided by another module. */
3842*e4b17023SJohn Marino 	  && (reason != CIF_BODY_NOT_AVAILABLE || !flag_generate_lto))
3843*e4b17023SJohn Marino 	{
3844*e4b17023SJohn Marino 	  error ("inlining failed in call to always_inline %q+F: %s", fn,
3845*e4b17023SJohn Marino 		 cgraph_inline_failed_string (reason));
3846*e4b17023SJohn Marino 	  error ("called from here");
3847*e4b17023SJohn Marino 	}
3848*e4b17023SJohn Marino       else if (warn_inline
3849*e4b17023SJohn Marino 	       && DECL_DECLARED_INLINE_P (fn)
3850*e4b17023SJohn Marino 	       && !DECL_NO_INLINE_WARNING_P (fn)
3851*e4b17023SJohn Marino 	       && !DECL_IN_SYSTEM_HEADER (fn)
3852*e4b17023SJohn Marino 	       && reason != CIF_UNSPECIFIED
3853*e4b17023SJohn Marino 	       && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn))
3854*e4b17023SJohn Marino 	       /* Do not warn about not inlined recursive calls.  */
3855*e4b17023SJohn Marino 	       && !cgraph_edge_recursive_p (cg_edge)
3856*e4b17023SJohn Marino 	       /* Avoid warnings during early inline pass. */
3857*e4b17023SJohn Marino 	       && cgraph_global_info_ready)
3858*e4b17023SJohn Marino 	{
3859*e4b17023SJohn Marino 	  warning (OPT_Winline, "inlining failed in call to %q+F: %s",
3860*e4b17023SJohn Marino 		   fn, _(cgraph_inline_failed_string (reason)));
3861*e4b17023SJohn Marino 	  warning (OPT_Winline, "called from here");
3862*e4b17023SJohn Marino 	}
3863*e4b17023SJohn Marino       goto egress;
3864*e4b17023SJohn Marino     }
3865*e4b17023SJohn Marino   fn = cg_edge->callee->decl;
3866*e4b17023SJohn Marino 
3867*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
3868*e4b17023SJohn Marino   if (cg_edge->callee->decl != id->dst_node->decl)
3869*e4b17023SJohn Marino     verify_cgraph_node (cg_edge->callee);
3870*e4b17023SJohn Marino #endif
3871*e4b17023SJohn Marino 
3872*e4b17023SJohn Marino   /* We will be inlining this callee.  */
3873*e4b17023SJohn Marino   id->eh_lp_nr = lookup_stmt_eh_lp (stmt);
3874*e4b17023SJohn Marino 
3875*e4b17023SJohn Marino   /* Update the callers EH personality.  */
3876*e4b17023SJohn Marino   if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl))
3877*e4b17023SJohn Marino     DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
3878*e4b17023SJohn Marino       = DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
3879*e4b17023SJohn Marino 
3880*e4b17023SJohn Marino   /* Split the block holding the GIMPLE_CALL.  */
3881*e4b17023SJohn Marino   e = split_block (bb, stmt);
3882*e4b17023SJohn Marino   bb = e->src;
3883*e4b17023SJohn Marino   return_block = e->dest;
3884*e4b17023SJohn Marino   remove_edge (e);
3885*e4b17023SJohn Marino 
3886*e4b17023SJohn Marino   /* split_block splits after the statement; work around this by
3887*e4b17023SJohn Marino      moving the call into the second block manually.  Not pretty,
3888*e4b17023SJohn Marino      but seems easier than doing the CFG manipulation by hand
3889*e4b17023SJohn Marino      when the GIMPLE_CALL is in the last statement of BB.  */
3890*e4b17023SJohn Marino   stmt_gsi = gsi_last_bb (bb);
3891*e4b17023SJohn Marino   gsi_remove (&stmt_gsi, false);
3892*e4b17023SJohn Marino 
3893*e4b17023SJohn Marino   /* If the GIMPLE_CALL was in the last statement of BB, it may have
3894*e4b17023SJohn Marino      been the source of abnormal edges.  In this case, schedule
3895*e4b17023SJohn Marino      the removal of dead abnormal edges.  */
3896*e4b17023SJohn Marino   gsi = gsi_start_bb (return_block);
3897*e4b17023SJohn Marino   if (gsi_end_p (gsi))
3898*e4b17023SJohn Marino     {
3899*e4b17023SJohn Marino       gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
3900*e4b17023SJohn Marino       purge_dead_abnormal_edges = true;
3901*e4b17023SJohn Marino     }
3902*e4b17023SJohn Marino   else
3903*e4b17023SJohn Marino     {
3904*e4b17023SJohn Marino       gsi_insert_before (&gsi, stmt, GSI_NEW_STMT);
3905*e4b17023SJohn Marino       purge_dead_abnormal_edges = false;
3906*e4b17023SJohn Marino     }
3907*e4b17023SJohn Marino 
3908*e4b17023SJohn Marino   stmt_gsi = gsi_start_bb (return_block);
3909*e4b17023SJohn Marino 
3910*e4b17023SJohn Marino   /* Build a block containing code to initialize the arguments, the
3911*e4b17023SJohn Marino      actual inline expansion of the body, and a label for the return
3912*e4b17023SJohn Marino      statements within the function to jump to.  The type of the
3913*e4b17023SJohn Marino      statement expression is the return type of the function call.  */
3914*e4b17023SJohn Marino   id->block = make_node (BLOCK);
3915*e4b17023SJohn Marino   BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
3916*e4b17023SJohn Marino   BLOCK_SOURCE_LOCATION (id->block) = input_location;
3917*e4b17023SJohn Marino   prepend_lexical_block (gimple_block (stmt), id->block);
3918*e4b17023SJohn Marino 
3919*e4b17023SJohn Marino   /* Local declarations will be replaced by their equivalents in this
3920*e4b17023SJohn Marino      map.  */
3921*e4b17023SJohn Marino   st = id->decl_map;
3922*e4b17023SJohn Marino   id->decl_map = pointer_map_create ();
3923*e4b17023SJohn Marino   dst = id->debug_map;
3924*e4b17023SJohn Marino   id->debug_map = NULL;
3925*e4b17023SJohn Marino 
3926*e4b17023SJohn Marino   /* Record the function we are about to inline.  */
3927*e4b17023SJohn Marino   id->src_fn = fn;
3928*e4b17023SJohn Marino   id->src_node = cg_edge->callee;
3929*e4b17023SJohn Marino   id->src_cfun = DECL_STRUCT_FUNCTION (fn);
3930*e4b17023SJohn Marino   id->gimple_call = stmt;
3931*e4b17023SJohn Marino 
3932*e4b17023SJohn Marino   gcc_assert (!id->src_cfun->after_inlining);
3933*e4b17023SJohn Marino 
3934*e4b17023SJohn Marino   id->entry_bb = bb;
3935*e4b17023SJohn Marino   if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn)))
3936*e4b17023SJohn Marino     {
3937*e4b17023SJohn Marino       gimple_stmt_iterator si = gsi_last_bb (bb);
3938*e4b17023SJohn Marino       gsi_insert_after (&si, gimple_build_predict (PRED_COLD_FUNCTION,
3939*e4b17023SJohn Marino       						   NOT_TAKEN),
3940*e4b17023SJohn Marino 			GSI_NEW_STMT);
3941*e4b17023SJohn Marino     }
3942*e4b17023SJohn Marino   initialize_inlined_parameters (id, stmt, fn, bb);
3943*e4b17023SJohn Marino 
3944*e4b17023SJohn Marino   if (DECL_INITIAL (fn))
3945*e4b17023SJohn Marino     prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
3946*e4b17023SJohn Marino 
3947*e4b17023SJohn Marino   /* Return statements in the function body will be replaced by jumps
3948*e4b17023SJohn Marino      to the RET_LABEL.  */
3949*e4b17023SJohn Marino   gcc_assert (DECL_INITIAL (fn));
3950*e4b17023SJohn Marino   gcc_assert (TREE_CODE (DECL_INITIAL (fn)) == BLOCK);
3951*e4b17023SJohn Marino 
3952*e4b17023SJohn Marino   /* Find the LHS to which the result of this call is assigned.  */
3953*e4b17023SJohn Marino   return_slot = NULL;
3954*e4b17023SJohn Marino   if (gimple_call_lhs (stmt))
3955*e4b17023SJohn Marino     {
3956*e4b17023SJohn Marino       modify_dest = gimple_call_lhs (stmt);
3957*e4b17023SJohn Marino 
3958*e4b17023SJohn Marino       /* The function which we are inlining might not return a value,
3959*e4b17023SJohn Marino 	 in which case we should issue a warning that the function
3960*e4b17023SJohn Marino 	 does not return a value.  In that case the optimizers will
3961*e4b17023SJohn Marino 	 see that the variable to which the value is assigned was not
3962*e4b17023SJohn Marino 	 initialized.  We do not want to issue a warning about that
3963*e4b17023SJohn Marino 	 uninitialized variable.  */
3964*e4b17023SJohn Marino       if (DECL_P (modify_dest))
3965*e4b17023SJohn Marino 	TREE_NO_WARNING (modify_dest) = 1;
3966*e4b17023SJohn Marino 
3967*e4b17023SJohn Marino       if (gimple_call_return_slot_opt_p (stmt))
3968*e4b17023SJohn Marino 	{
3969*e4b17023SJohn Marino 	  return_slot = modify_dest;
3970*e4b17023SJohn Marino 	  modify_dest = NULL;
3971*e4b17023SJohn Marino 	}
3972*e4b17023SJohn Marino     }
3973*e4b17023SJohn Marino   else
3974*e4b17023SJohn Marino     modify_dest = NULL;
3975*e4b17023SJohn Marino 
3976*e4b17023SJohn Marino   /* If we are inlining a call to the C++ operator new, we don't want
3977*e4b17023SJohn Marino      to use type based alias analysis on the return value.  Otherwise
3978*e4b17023SJohn Marino      we may get confused if the compiler sees that the inlined new
3979*e4b17023SJohn Marino      function returns a pointer which was just deleted.  See bug
3980*e4b17023SJohn Marino      33407.  */
3981*e4b17023SJohn Marino   if (DECL_IS_OPERATOR_NEW (fn))
3982*e4b17023SJohn Marino     {
3983*e4b17023SJohn Marino       return_slot = NULL;
3984*e4b17023SJohn Marino       modify_dest = NULL;
3985*e4b17023SJohn Marino     }
3986*e4b17023SJohn Marino 
3987*e4b17023SJohn Marino   /* Declare the return variable for the function.  */
3988*e4b17023SJohn Marino   use_retvar = declare_return_variable (id, return_slot, modify_dest, bb);
3989*e4b17023SJohn Marino 
3990*e4b17023SJohn Marino   /* Add local vars in this inlined callee to caller.  */
3991*e4b17023SJohn Marino   add_local_variables (id->src_cfun, cfun, id, true);
3992*e4b17023SJohn Marino 
3993*e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
3994*e4b17023SJohn Marino     {
3995*e4b17023SJohn Marino       fprintf (dump_file, "Inlining ");
3996*e4b17023SJohn Marino       print_generic_expr (dump_file, id->src_fn, 0);
3997*e4b17023SJohn Marino       fprintf (dump_file, " to ");
3998*e4b17023SJohn Marino       print_generic_expr (dump_file, id->dst_fn, 0);
3999*e4b17023SJohn Marino       fprintf (dump_file, " with frequency %i\n", cg_edge->frequency);
4000*e4b17023SJohn Marino     }
4001*e4b17023SJohn Marino 
4002*e4b17023SJohn Marino   /* This is it.  Duplicate the callee body.  Assume callee is
4003*e4b17023SJohn Marino      pre-gimplified.  Note that we must not alter the caller
4004*e4b17023SJohn Marino      function in any way before this point, as this CALL_EXPR may be
4005*e4b17023SJohn Marino      a self-referential call; if we're calling ourselves, we need to
4006*e4b17023SJohn Marino      duplicate our body before altering anything.  */
4007*e4b17023SJohn Marino   copy_body (id, bb->count,
4008*e4b17023SJohn Marino   	     cg_edge->frequency * REG_BR_PROB_BASE / CGRAPH_FREQ_BASE,
4009*e4b17023SJohn Marino 	     bb, return_block, NULL, NULL);
4010*e4b17023SJohn Marino 
4011*e4b17023SJohn Marino   /* Reset the escaped solution.  */
4012*e4b17023SJohn Marino   if (cfun->gimple_df)
4013*e4b17023SJohn Marino     pt_solution_reset (&cfun->gimple_df->escaped);
4014*e4b17023SJohn Marino 
4015*e4b17023SJohn Marino   /* Clean up.  */
4016*e4b17023SJohn Marino   if (id->debug_map)
4017*e4b17023SJohn Marino     {
4018*e4b17023SJohn Marino       pointer_map_destroy (id->debug_map);
4019*e4b17023SJohn Marino       id->debug_map = dst;
4020*e4b17023SJohn Marino     }
4021*e4b17023SJohn Marino   pointer_map_destroy (id->decl_map);
4022*e4b17023SJohn Marino   id->decl_map = st;
4023*e4b17023SJohn Marino 
4024*e4b17023SJohn Marino   /* Unlink the calls virtual operands before replacing it.  */
4025*e4b17023SJohn Marino   unlink_stmt_vdef (stmt);
4026*e4b17023SJohn Marino 
4027*e4b17023SJohn Marino   /* If the inlined function returns a result that we care about,
4028*e4b17023SJohn Marino      substitute the GIMPLE_CALL with an assignment of the return
4029*e4b17023SJohn Marino      variable to the LHS of the call.  That is, if STMT was
4030*e4b17023SJohn Marino      'a = foo (...)', substitute the call with 'a = USE_RETVAR'.  */
4031*e4b17023SJohn Marino   if (use_retvar && gimple_call_lhs (stmt))
4032*e4b17023SJohn Marino     {
4033*e4b17023SJohn Marino       gimple old_stmt = stmt;
4034*e4b17023SJohn Marino       stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar);
4035*e4b17023SJohn Marino       gsi_replace (&stmt_gsi, stmt, false);
4036*e4b17023SJohn Marino       if (gimple_in_ssa_p (cfun))
4037*e4b17023SJohn Marino 	mark_symbols_for_renaming (stmt);
4038*e4b17023SJohn Marino       maybe_clean_or_replace_eh_stmt (old_stmt, stmt);
4039*e4b17023SJohn Marino     }
4040*e4b17023SJohn Marino   else
4041*e4b17023SJohn Marino     {
4042*e4b17023SJohn Marino       /* Handle the case of inlining a function with no return
4043*e4b17023SJohn Marino 	 statement, which causes the return value to become undefined.  */
4044*e4b17023SJohn Marino       if (gimple_call_lhs (stmt)
4045*e4b17023SJohn Marino 	  && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
4046*e4b17023SJohn Marino 	{
4047*e4b17023SJohn Marino 	  tree name = gimple_call_lhs (stmt);
4048*e4b17023SJohn Marino 	  tree var = SSA_NAME_VAR (name);
4049*e4b17023SJohn Marino 	  tree def = gimple_default_def (cfun, var);
4050*e4b17023SJohn Marino 
4051*e4b17023SJohn Marino 	  if (def)
4052*e4b17023SJohn Marino 	    {
4053*e4b17023SJohn Marino 	      /* If the variable is used undefined, make this name
4054*e4b17023SJohn Marino 		 undefined via a move.  */
4055*e4b17023SJohn Marino 	      stmt = gimple_build_assign (gimple_call_lhs (stmt), def);
4056*e4b17023SJohn Marino 	      gsi_replace (&stmt_gsi, stmt, true);
4057*e4b17023SJohn Marino 	    }
4058*e4b17023SJohn Marino 	  else
4059*e4b17023SJohn Marino 	    {
4060*e4b17023SJohn Marino 	      /* Otherwise make this variable undefined.  */
4061*e4b17023SJohn Marino 	      gsi_remove (&stmt_gsi, true);
4062*e4b17023SJohn Marino 	      set_default_def (var, name);
4063*e4b17023SJohn Marino 	      SSA_NAME_DEF_STMT (name) = gimple_build_nop ();
4064*e4b17023SJohn Marino 	    }
4065*e4b17023SJohn Marino 	}
4066*e4b17023SJohn Marino       else
4067*e4b17023SJohn Marino         gsi_remove (&stmt_gsi, true);
4068*e4b17023SJohn Marino     }
4069*e4b17023SJohn Marino 
4070*e4b17023SJohn Marino   if (purge_dead_abnormal_edges)
4071*e4b17023SJohn Marino     {
4072*e4b17023SJohn Marino       gimple_purge_dead_eh_edges (return_block);
4073*e4b17023SJohn Marino       gimple_purge_dead_abnormal_call_edges (return_block);
4074*e4b17023SJohn Marino     }
4075*e4b17023SJohn Marino 
4076*e4b17023SJohn Marino   /* If the value of the new expression is ignored, that's OK.  We
4077*e4b17023SJohn Marino      don't warn about this for CALL_EXPRs, so we shouldn't warn about
4078*e4b17023SJohn Marino      the equivalent inlined version either.  */
4079*e4b17023SJohn Marino   if (is_gimple_assign (stmt))
4080*e4b17023SJohn Marino     {
4081*e4b17023SJohn Marino       gcc_assert (gimple_assign_single_p (stmt)
4082*e4b17023SJohn Marino 		  || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)));
4083*e4b17023SJohn Marino       TREE_USED (gimple_assign_rhs1 (stmt)) = 1;
4084*e4b17023SJohn Marino     }
4085*e4b17023SJohn Marino 
4086*e4b17023SJohn Marino   /* Output the inlining info for this abstract function, since it has been
4087*e4b17023SJohn Marino      inlined.  If we don't do this now, we can lose the information about the
4088*e4b17023SJohn Marino      variables in the function when the blocks get blown away as soon as we
4089*e4b17023SJohn Marino      remove the cgraph node.  */
4090*e4b17023SJohn Marino   (*debug_hooks->outlining_inline_function) (cg_edge->callee->decl);
4091*e4b17023SJohn Marino 
4092*e4b17023SJohn Marino   /* Update callgraph if needed.  */
4093*e4b17023SJohn Marino   cgraph_remove_node (cg_edge->callee);
4094*e4b17023SJohn Marino 
4095*e4b17023SJohn Marino   id->block = NULL_TREE;
4096*e4b17023SJohn Marino   successfully_inlined = TRUE;
4097*e4b17023SJohn Marino 
4098*e4b17023SJohn Marino  egress:
4099*e4b17023SJohn Marino   input_location = saved_location;
4100*e4b17023SJohn Marino   return successfully_inlined;
4101*e4b17023SJohn Marino }
4102*e4b17023SJohn Marino 
4103*e4b17023SJohn Marino /* Expand call statements reachable from STMT_P.
4104*e4b17023SJohn Marino    We can only have CALL_EXPRs as the "toplevel" tree code or nested
4105*e4b17023SJohn Marino    in a MODIFY_EXPR.  */
4106*e4b17023SJohn Marino 
4107*e4b17023SJohn Marino static bool
4108*e4b17023SJohn Marino gimple_expand_calls_inline (basic_block bb, copy_body_data *id)
4109*e4b17023SJohn Marino {
4110*e4b17023SJohn Marino   gimple_stmt_iterator gsi;
4111*e4b17023SJohn Marino 
4112*e4b17023SJohn Marino   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
4113*e4b17023SJohn Marino     {
4114*e4b17023SJohn Marino       gimple stmt = gsi_stmt (gsi);
4115*e4b17023SJohn Marino 
4116*e4b17023SJohn Marino       if (is_gimple_call (stmt)
4117*e4b17023SJohn Marino 	  && expand_call_inline (bb, stmt, id))
4118*e4b17023SJohn Marino 	return true;
4119*e4b17023SJohn Marino     }
4120*e4b17023SJohn Marino 
4121*e4b17023SJohn Marino   return false;
4122*e4b17023SJohn Marino }
4123*e4b17023SJohn Marino 
4124*e4b17023SJohn Marino 
4125*e4b17023SJohn Marino /* Walk all basic blocks created after FIRST and try to fold every statement
4126*e4b17023SJohn Marino    in the STATEMENTS pointer set.  */
4127*e4b17023SJohn Marino 
4128*e4b17023SJohn Marino static void
4129*e4b17023SJohn Marino fold_marked_statements (int first, struct pointer_set_t *statements)
4130*e4b17023SJohn Marino {
4131*e4b17023SJohn Marino   for (; first < n_basic_blocks; first++)
4132*e4b17023SJohn Marino     if (BASIC_BLOCK (first))
4133*e4b17023SJohn Marino       {
4134*e4b17023SJohn Marino         gimple_stmt_iterator gsi;
4135*e4b17023SJohn Marino 
4136*e4b17023SJohn Marino 	for (gsi = gsi_start_bb (BASIC_BLOCK (first));
4137*e4b17023SJohn Marino 	     !gsi_end_p (gsi);
4138*e4b17023SJohn Marino 	     gsi_next (&gsi))
4139*e4b17023SJohn Marino 	  if (pointer_set_contains (statements, gsi_stmt (gsi)))
4140*e4b17023SJohn Marino 	    {
4141*e4b17023SJohn Marino 	      gimple old_stmt = gsi_stmt (gsi);
4142*e4b17023SJohn Marino 	      tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0;
4143*e4b17023SJohn Marino 
4144*e4b17023SJohn Marino 	      if (old_decl && DECL_BUILT_IN (old_decl))
4145*e4b17023SJohn Marino 		{
4146*e4b17023SJohn Marino 		  /* Folding builtins can create multiple instructions,
4147*e4b17023SJohn Marino 		     we need to look at all of them.  */
4148*e4b17023SJohn Marino 		  gimple_stmt_iterator i2 = gsi;
4149*e4b17023SJohn Marino 		  gsi_prev (&i2);
4150*e4b17023SJohn Marino 		  if (fold_stmt (&gsi))
4151*e4b17023SJohn Marino 		    {
4152*e4b17023SJohn Marino 		      gimple new_stmt;
4153*e4b17023SJohn Marino 		      /* If a builtin at the end of a bb folded into nothing,
4154*e4b17023SJohn Marino 			 the following loop won't work.  */
4155*e4b17023SJohn Marino 		      if (gsi_end_p (gsi))
4156*e4b17023SJohn Marino 			{
4157*e4b17023SJohn Marino 			  cgraph_update_edges_for_call_stmt (old_stmt,
4158*e4b17023SJohn Marino 							     old_decl, NULL);
4159*e4b17023SJohn Marino 			  break;
4160*e4b17023SJohn Marino 			}
4161*e4b17023SJohn Marino 		      if (gsi_end_p (i2))
4162*e4b17023SJohn Marino 			i2 = gsi_start_bb (BASIC_BLOCK (first));
4163*e4b17023SJohn Marino 		      else
4164*e4b17023SJohn Marino 			gsi_next (&i2);
4165*e4b17023SJohn Marino 		      while (1)
4166*e4b17023SJohn Marino 			{
4167*e4b17023SJohn Marino 			  new_stmt = gsi_stmt (i2);
4168*e4b17023SJohn Marino 			  update_stmt (new_stmt);
4169*e4b17023SJohn Marino 			  cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
4170*e4b17023SJohn Marino 							     new_stmt);
4171*e4b17023SJohn Marino 
4172*e4b17023SJohn Marino 			  if (new_stmt == gsi_stmt (gsi))
4173*e4b17023SJohn Marino 			    {
4174*e4b17023SJohn Marino 			      /* It is okay to check only for the very last
4175*e4b17023SJohn Marino 				 of these statements.  If it is a throwing
4176*e4b17023SJohn Marino 				 statement nothing will change.  If it isn't
4177*e4b17023SJohn Marino 				 this can remove EH edges.  If that weren't
4178*e4b17023SJohn Marino 				 correct then because some intermediate stmts
4179*e4b17023SJohn Marino 				 throw, but not the last one.  That would mean
4180*e4b17023SJohn Marino 				 we'd have to split the block, which we can't
4181*e4b17023SJohn Marino 				 here and we'd loose anyway.  And as builtins
4182*e4b17023SJohn Marino 				 probably never throw, this all
4183*e4b17023SJohn Marino 				 is mood anyway.  */
4184*e4b17023SJohn Marino 			      if (maybe_clean_or_replace_eh_stmt (old_stmt,
4185*e4b17023SJohn Marino 								  new_stmt))
4186*e4b17023SJohn Marino 				gimple_purge_dead_eh_edges (BASIC_BLOCK (first));
4187*e4b17023SJohn Marino 			      break;
4188*e4b17023SJohn Marino 			    }
4189*e4b17023SJohn Marino 			  gsi_next (&i2);
4190*e4b17023SJohn Marino 			}
4191*e4b17023SJohn Marino 		    }
4192*e4b17023SJohn Marino 		}
4193*e4b17023SJohn Marino 	      else if (fold_stmt (&gsi))
4194*e4b17023SJohn Marino 		{
4195*e4b17023SJohn Marino 		  /* Re-read the statement from GSI as fold_stmt() may
4196*e4b17023SJohn Marino 		     have changed it.  */
4197*e4b17023SJohn Marino 		  gimple new_stmt = gsi_stmt (gsi);
4198*e4b17023SJohn Marino 		  update_stmt (new_stmt);
4199*e4b17023SJohn Marino 
4200*e4b17023SJohn Marino 		  if (is_gimple_call (old_stmt)
4201*e4b17023SJohn Marino 		      || is_gimple_call (new_stmt))
4202*e4b17023SJohn Marino 		    cgraph_update_edges_for_call_stmt (old_stmt, old_decl,
4203*e4b17023SJohn Marino 						       new_stmt);
4204*e4b17023SJohn Marino 
4205*e4b17023SJohn Marino 		  if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt))
4206*e4b17023SJohn Marino 		    gimple_purge_dead_eh_edges (BASIC_BLOCK (first));
4207*e4b17023SJohn Marino 		}
4208*e4b17023SJohn Marino 	    }
4209*e4b17023SJohn Marino       }
4210*e4b17023SJohn Marino }
4211*e4b17023SJohn Marino 
4212*e4b17023SJohn Marino /* Return true if BB has at least one abnormal outgoing edge.  */
4213*e4b17023SJohn Marino 
4214*e4b17023SJohn Marino static inline bool
4215*e4b17023SJohn Marino has_abnormal_outgoing_edge_p (basic_block bb)
4216*e4b17023SJohn Marino {
4217*e4b17023SJohn Marino   edge e;
4218*e4b17023SJohn Marino   edge_iterator ei;
4219*e4b17023SJohn Marino 
4220*e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
4221*e4b17023SJohn Marino     if (e->flags & EDGE_ABNORMAL)
4222*e4b17023SJohn Marino       return true;
4223*e4b17023SJohn Marino 
4224*e4b17023SJohn Marino   return false;
4225*e4b17023SJohn Marino }
4226*e4b17023SJohn Marino 
4227*e4b17023SJohn Marino /* Expand calls to inline functions in the body of FN.  */
4228*e4b17023SJohn Marino 
4229*e4b17023SJohn Marino unsigned int
4230*e4b17023SJohn Marino optimize_inline_calls (tree fn)
4231*e4b17023SJohn Marino {
4232*e4b17023SJohn Marino   copy_body_data id;
4233*e4b17023SJohn Marino   basic_block bb;
4234*e4b17023SJohn Marino   int last = n_basic_blocks;
4235*e4b17023SJohn Marino   struct gimplify_ctx gctx;
4236*e4b17023SJohn Marino   bool inlined_p = false;
4237*e4b17023SJohn Marino 
4238*e4b17023SJohn Marino   /* Clear out ID.  */
4239*e4b17023SJohn Marino   memset (&id, 0, sizeof (id));
4240*e4b17023SJohn Marino 
4241*e4b17023SJohn Marino   id.src_node = id.dst_node = cgraph_get_node (fn);
4242*e4b17023SJohn Marino   gcc_assert (id.dst_node->analyzed);
4243*e4b17023SJohn Marino   id.dst_fn = fn;
4244*e4b17023SJohn Marino   /* Or any functions that aren't finished yet.  */
4245*e4b17023SJohn Marino   if (current_function_decl)
4246*e4b17023SJohn Marino     id.dst_fn = current_function_decl;
4247*e4b17023SJohn Marino 
4248*e4b17023SJohn Marino   id.copy_decl = copy_decl_maybe_to_var;
4249*e4b17023SJohn Marino   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
4250*e4b17023SJohn Marino   id.transform_new_cfg = false;
4251*e4b17023SJohn Marino   id.transform_return_to_modify = true;
4252*e4b17023SJohn Marino   id.transform_lang_insert_block = NULL;
4253*e4b17023SJohn Marino   id.statements_to_fold = pointer_set_create ();
4254*e4b17023SJohn Marino 
4255*e4b17023SJohn Marino   push_gimplify_context (&gctx);
4256*e4b17023SJohn Marino 
4257*e4b17023SJohn Marino   /* We make no attempts to keep dominance info up-to-date.  */
4258*e4b17023SJohn Marino   free_dominance_info (CDI_DOMINATORS);
4259*e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
4260*e4b17023SJohn Marino 
4261*e4b17023SJohn Marino   /* Register specific gimple functions.  */
4262*e4b17023SJohn Marino   gimple_register_cfg_hooks ();
4263*e4b17023SJohn Marino 
4264*e4b17023SJohn Marino   /* Reach the trees by walking over the CFG, and note the
4265*e4b17023SJohn Marino      enclosing basic-blocks in the call edges.  */
4266*e4b17023SJohn Marino   /* We walk the blocks going forward, because inlined function bodies
4267*e4b17023SJohn Marino      will split id->current_basic_block, and the new blocks will
4268*e4b17023SJohn Marino      follow it; we'll trudge through them, processing their CALL_EXPRs
4269*e4b17023SJohn Marino      along the way.  */
4270*e4b17023SJohn Marino   FOR_EACH_BB (bb)
4271*e4b17023SJohn Marino     inlined_p |= gimple_expand_calls_inline (bb, &id);
4272*e4b17023SJohn Marino 
4273*e4b17023SJohn Marino   pop_gimplify_context (NULL);
4274*e4b17023SJohn Marino 
4275*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
4276*e4b17023SJohn Marino     {
4277*e4b17023SJohn Marino       struct cgraph_edge *e;
4278*e4b17023SJohn Marino 
4279*e4b17023SJohn Marino       verify_cgraph_node (id.dst_node);
4280*e4b17023SJohn Marino 
4281*e4b17023SJohn Marino       /* Double check that we inlined everything we are supposed to inline.  */
4282*e4b17023SJohn Marino       for (e = id.dst_node->callees; e; e = e->next_callee)
4283*e4b17023SJohn Marino 	gcc_assert (e->inline_failed);
4284*e4b17023SJohn Marino     }
4285*e4b17023SJohn Marino #endif
4286*e4b17023SJohn Marino 
4287*e4b17023SJohn Marino   /* Fold queued statements.  */
4288*e4b17023SJohn Marino   fold_marked_statements (last, id.statements_to_fold);
4289*e4b17023SJohn Marino   pointer_set_destroy (id.statements_to_fold);
4290*e4b17023SJohn Marino 
4291*e4b17023SJohn Marino   gcc_assert (!id.debug_stmts);
4292*e4b17023SJohn Marino 
4293*e4b17023SJohn Marino   /* If we didn't inline into the function there is nothing to do.  */
4294*e4b17023SJohn Marino   if (!inlined_p)
4295*e4b17023SJohn Marino     return 0;
4296*e4b17023SJohn Marino 
4297*e4b17023SJohn Marino   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
4298*e4b17023SJohn Marino   number_blocks (fn);
4299*e4b17023SJohn Marino 
4300*e4b17023SJohn Marino   delete_unreachable_blocks_update_callgraph (&id);
4301*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
4302*e4b17023SJohn Marino   verify_cgraph_node (id.dst_node);
4303*e4b17023SJohn Marino #endif
4304*e4b17023SJohn Marino 
4305*e4b17023SJohn Marino   /* It would be nice to check SSA/CFG/statement consistency here, but it is
4306*e4b17023SJohn Marino      not possible yet - the IPA passes might make various functions to not
4307*e4b17023SJohn Marino      throw and they don't care to proactively update local EH info.  This is
4308*e4b17023SJohn Marino      done later in fixup_cfg pass that also execute the verification.  */
4309*e4b17023SJohn Marino   return (TODO_update_ssa
4310*e4b17023SJohn Marino 	  | TODO_cleanup_cfg
4311*e4b17023SJohn Marino 	  | (gimple_in_ssa_p (cfun) ? TODO_remove_unused_locals : 0)
4312*e4b17023SJohn Marino 	  | (gimple_in_ssa_p (cfun) ? TODO_update_address_taken : 0)
4313*e4b17023SJohn Marino 	  | (profile_status != PROFILE_ABSENT ? TODO_rebuild_frequencies : 0));
4314*e4b17023SJohn Marino }
4315*e4b17023SJohn Marino 
4316*e4b17023SJohn Marino /* Passed to walk_tree.  Copies the node pointed to, if appropriate.  */
4317*e4b17023SJohn Marino 
4318*e4b17023SJohn Marino tree
4319*e4b17023SJohn Marino copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
4320*e4b17023SJohn Marino {
4321*e4b17023SJohn Marino   enum tree_code code = TREE_CODE (*tp);
4322*e4b17023SJohn Marino   enum tree_code_class cl = TREE_CODE_CLASS (code);
4323*e4b17023SJohn Marino 
4324*e4b17023SJohn Marino   /* We make copies of most nodes.  */
4325*e4b17023SJohn Marino   if (IS_EXPR_CODE_CLASS (cl)
4326*e4b17023SJohn Marino       || code == TREE_LIST
4327*e4b17023SJohn Marino       || code == TREE_VEC
4328*e4b17023SJohn Marino       || code == TYPE_DECL
4329*e4b17023SJohn Marino       || code == OMP_CLAUSE)
4330*e4b17023SJohn Marino     {
4331*e4b17023SJohn Marino       /* Because the chain gets clobbered when we make a copy, we save it
4332*e4b17023SJohn Marino 	 here.  */
4333*e4b17023SJohn Marino       tree chain = NULL_TREE, new_tree;
4334*e4b17023SJohn Marino 
4335*e4b17023SJohn Marino       if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
4336*e4b17023SJohn Marino 	chain = TREE_CHAIN (*tp);
4337*e4b17023SJohn Marino 
4338*e4b17023SJohn Marino       /* Copy the node.  */
4339*e4b17023SJohn Marino       new_tree = copy_node (*tp);
4340*e4b17023SJohn Marino 
4341*e4b17023SJohn Marino       /* Propagate mudflap marked-ness.  */
4342*e4b17023SJohn Marino       if (flag_mudflap && mf_marked_p (*tp))
4343*e4b17023SJohn Marino         mf_mark (new_tree);
4344*e4b17023SJohn Marino 
4345*e4b17023SJohn Marino       *tp = new_tree;
4346*e4b17023SJohn Marino 
4347*e4b17023SJohn Marino       /* Now, restore the chain, if appropriate.  That will cause
4348*e4b17023SJohn Marino 	 walk_tree to walk into the chain as well.  */
4349*e4b17023SJohn Marino       if (code == PARM_DECL
4350*e4b17023SJohn Marino 	  || code == TREE_LIST
4351*e4b17023SJohn Marino 	  || code == OMP_CLAUSE)
4352*e4b17023SJohn Marino 	TREE_CHAIN (*tp) = chain;
4353*e4b17023SJohn Marino 
4354*e4b17023SJohn Marino       /* For now, we don't update BLOCKs when we make copies.  So, we
4355*e4b17023SJohn Marino 	 have to nullify all BIND_EXPRs.  */
4356*e4b17023SJohn Marino       if (TREE_CODE (*tp) == BIND_EXPR)
4357*e4b17023SJohn Marino 	BIND_EXPR_BLOCK (*tp) = NULL_TREE;
4358*e4b17023SJohn Marino     }
4359*e4b17023SJohn Marino   else if (code == CONSTRUCTOR)
4360*e4b17023SJohn Marino     {
4361*e4b17023SJohn Marino       /* CONSTRUCTOR nodes need special handling because
4362*e4b17023SJohn Marino          we need to duplicate the vector of elements.  */
4363*e4b17023SJohn Marino       tree new_tree;
4364*e4b17023SJohn Marino 
4365*e4b17023SJohn Marino       new_tree = copy_node (*tp);
4366*e4b17023SJohn Marino 
4367*e4b17023SJohn Marino       /* Propagate mudflap marked-ness.  */
4368*e4b17023SJohn Marino       if (flag_mudflap && mf_marked_p (*tp))
4369*e4b17023SJohn Marino         mf_mark (new_tree);
4370*e4b17023SJohn Marino 
4371*e4b17023SJohn Marino       CONSTRUCTOR_ELTS (new_tree) = VEC_copy (constructor_elt, gc,
4372*e4b17023SJohn Marino 					 CONSTRUCTOR_ELTS (*tp));
4373*e4b17023SJohn Marino       *tp = new_tree;
4374*e4b17023SJohn Marino     }
4375*e4b17023SJohn Marino   else if (code == STATEMENT_LIST)
4376*e4b17023SJohn Marino     /* We used to just abort on STATEMENT_LIST, but we can run into them
4377*e4b17023SJohn Marino        with statement-expressions (c++/40975).  */
4378*e4b17023SJohn Marino     copy_statement_list (tp);
4379*e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_type)
4380*e4b17023SJohn Marino     *walk_subtrees = 0;
4381*e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_declaration)
4382*e4b17023SJohn Marino     *walk_subtrees = 0;
4383*e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_constant)
4384*e4b17023SJohn Marino     *walk_subtrees = 0;
4385*e4b17023SJohn Marino   return NULL_TREE;
4386*e4b17023SJohn Marino }
4387*e4b17023SJohn Marino 
4388*e4b17023SJohn Marino /* The SAVE_EXPR pointed to by TP is being copied.  If ST contains
4389*e4b17023SJohn Marino    information indicating to what new SAVE_EXPR this one should be mapped,
4390*e4b17023SJohn Marino    use that one.  Otherwise, create a new node and enter it in ST.  FN is
4391*e4b17023SJohn Marino    the function into which the copy will be placed.  */
4392*e4b17023SJohn Marino 
4393*e4b17023SJohn Marino static void
4394*e4b17023SJohn Marino remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
4395*e4b17023SJohn Marino {
4396*e4b17023SJohn Marino   struct pointer_map_t *st = (struct pointer_map_t *) st_;
4397*e4b17023SJohn Marino   tree *n;
4398*e4b17023SJohn Marino   tree t;
4399*e4b17023SJohn Marino 
4400*e4b17023SJohn Marino   /* See if we already encountered this SAVE_EXPR.  */
4401*e4b17023SJohn Marino   n = (tree *) pointer_map_contains (st, *tp);
4402*e4b17023SJohn Marino 
4403*e4b17023SJohn Marino   /* If we didn't already remap this SAVE_EXPR, do so now.  */
4404*e4b17023SJohn Marino   if (!n)
4405*e4b17023SJohn Marino     {
4406*e4b17023SJohn Marino       t = copy_node (*tp);
4407*e4b17023SJohn Marino 
4408*e4b17023SJohn Marino       /* Remember this SAVE_EXPR.  */
4409*e4b17023SJohn Marino       *pointer_map_insert (st, *tp) = t;
4410*e4b17023SJohn Marino       /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
4411*e4b17023SJohn Marino       *pointer_map_insert (st, t) = t;
4412*e4b17023SJohn Marino     }
4413*e4b17023SJohn Marino   else
4414*e4b17023SJohn Marino     {
4415*e4b17023SJohn Marino       /* We've already walked into this SAVE_EXPR; don't do it again.  */
4416*e4b17023SJohn Marino       *walk_subtrees = 0;
4417*e4b17023SJohn Marino       t = *n;
4418*e4b17023SJohn Marino     }
4419*e4b17023SJohn Marino 
4420*e4b17023SJohn Marino   /* Replace this SAVE_EXPR with the copy.  */
4421*e4b17023SJohn Marino   *tp = t;
4422*e4b17023SJohn Marino }
4423*e4b17023SJohn Marino 
4424*e4b17023SJohn Marino /* Called via walk_tree.  If *TP points to a DECL_STMT for a local label,
4425*e4b17023SJohn Marino    copies the declaration and enters it in the splay_tree in DATA (which is
4426*e4b17023SJohn Marino    really an `copy_body_data *').  */
4427*e4b17023SJohn Marino 
4428*e4b17023SJohn Marino static tree
4429*e4b17023SJohn Marino mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
4430*e4b17023SJohn Marino 			void *data)
4431*e4b17023SJohn Marino {
4432*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) data;
4433*e4b17023SJohn Marino 
4434*e4b17023SJohn Marino   /* Don't walk into types.  */
4435*e4b17023SJohn Marino   if (TYPE_P (*tp))
4436*e4b17023SJohn Marino     *walk_subtrees = 0;
4437*e4b17023SJohn Marino 
4438*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == LABEL_EXPR)
4439*e4b17023SJohn Marino     {
4440*e4b17023SJohn Marino       tree decl = TREE_OPERAND (*tp, 0);
4441*e4b17023SJohn Marino 
4442*e4b17023SJohn Marino       /* Copy the decl and remember the copy.  */
4443*e4b17023SJohn Marino       insert_decl_map (id, decl, id->copy_decl (decl, id));
4444*e4b17023SJohn Marino     }
4445*e4b17023SJohn Marino 
4446*e4b17023SJohn Marino   return NULL_TREE;
4447*e4b17023SJohn Marino }
4448*e4b17023SJohn Marino 
4449*e4b17023SJohn Marino /* Perform any modifications to EXPR required when it is unsaved.  Does
4450*e4b17023SJohn Marino    not recurse into EXPR's subtrees.  */
4451*e4b17023SJohn Marino 
4452*e4b17023SJohn Marino static void
4453*e4b17023SJohn Marino unsave_expr_1 (tree expr)
4454*e4b17023SJohn Marino {
4455*e4b17023SJohn Marino   switch (TREE_CODE (expr))
4456*e4b17023SJohn Marino     {
4457*e4b17023SJohn Marino     case TARGET_EXPR:
4458*e4b17023SJohn Marino       /* Don't mess with a TARGET_EXPR that hasn't been expanded.
4459*e4b17023SJohn Marino          It's OK for this to happen if it was part of a subtree that
4460*e4b17023SJohn Marino          isn't immediately expanded, such as operand 2 of another
4461*e4b17023SJohn Marino          TARGET_EXPR.  */
4462*e4b17023SJohn Marino       if (TREE_OPERAND (expr, 1))
4463*e4b17023SJohn Marino 	break;
4464*e4b17023SJohn Marino 
4465*e4b17023SJohn Marino       TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3);
4466*e4b17023SJohn Marino       TREE_OPERAND (expr, 3) = NULL_TREE;
4467*e4b17023SJohn Marino       break;
4468*e4b17023SJohn Marino 
4469*e4b17023SJohn Marino     default:
4470*e4b17023SJohn Marino       break;
4471*e4b17023SJohn Marino     }
4472*e4b17023SJohn Marino }
4473*e4b17023SJohn Marino 
4474*e4b17023SJohn Marino /* Called via walk_tree when an expression is unsaved.  Using the
4475*e4b17023SJohn Marino    splay_tree pointed to by ST (which is really a `splay_tree'),
4476*e4b17023SJohn Marino    remaps all local declarations to appropriate replacements.  */
4477*e4b17023SJohn Marino 
4478*e4b17023SJohn Marino static tree
4479*e4b17023SJohn Marino unsave_r (tree *tp, int *walk_subtrees, void *data)
4480*e4b17023SJohn Marino {
4481*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) data;
4482*e4b17023SJohn Marino   struct pointer_map_t *st = id->decl_map;
4483*e4b17023SJohn Marino   tree *n;
4484*e4b17023SJohn Marino 
4485*e4b17023SJohn Marino   /* Only a local declaration (variable or label).  */
4486*e4b17023SJohn Marino   if ((TREE_CODE (*tp) == VAR_DECL && !TREE_STATIC (*tp))
4487*e4b17023SJohn Marino       || TREE_CODE (*tp) == LABEL_DECL)
4488*e4b17023SJohn Marino     {
4489*e4b17023SJohn Marino       /* Lookup the declaration.  */
4490*e4b17023SJohn Marino       n = (tree *) pointer_map_contains (st, *tp);
4491*e4b17023SJohn Marino 
4492*e4b17023SJohn Marino       /* If it's there, remap it.  */
4493*e4b17023SJohn Marino       if (n)
4494*e4b17023SJohn Marino 	*tp = *n;
4495*e4b17023SJohn Marino     }
4496*e4b17023SJohn Marino 
4497*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == STATEMENT_LIST)
4498*e4b17023SJohn Marino     gcc_unreachable ();
4499*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == BIND_EXPR)
4500*e4b17023SJohn Marino     copy_bind_expr (tp, walk_subtrees, id);
4501*e4b17023SJohn Marino   else if (TREE_CODE (*tp) == SAVE_EXPR
4502*e4b17023SJohn Marino 	   || TREE_CODE (*tp) == TARGET_EXPR)
4503*e4b17023SJohn Marino     remap_save_expr (tp, st, walk_subtrees);
4504*e4b17023SJohn Marino   else
4505*e4b17023SJohn Marino     {
4506*e4b17023SJohn Marino       copy_tree_r (tp, walk_subtrees, NULL);
4507*e4b17023SJohn Marino 
4508*e4b17023SJohn Marino       /* Do whatever unsaving is required.  */
4509*e4b17023SJohn Marino       unsave_expr_1 (*tp);
4510*e4b17023SJohn Marino     }
4511*e4b17023SJohn Marino 
4512*e4b17023SJohn Marino   /* Keep iterating.  */
4513*e4b17023SJohn Marino   return NULL_TREE;
4514*e4b17023SJohn Marino }
4515*e4b17023SJohn Marino 
4516*e4b17023SJohn Marino /* Copies everything in EXPR and replaces variables, labels
4517*e4b17023SJohn Marino    and SAVE_EXPRs local to EXPR.  */
4518*e4b17023SJohn Marino 
4519*e4b17023SJohn Marino tree
4520*e4b17023SJohn Marino unsave_expr_now (tree expr)
4521*e4b17023SJohn Marino {
4522*e4b17023SJohn Marino   copy_body_data id;
4523*e4b17023SJohn Marino 
4524*e4b17023SJohn Marino   /* There's nothing to do for NULL_TREE.  */
4525*e4b17023SJohn Marino   if (expr == 0)
4526*e4b17023SJohn Marino     return expr;
4527*e4b17023SJohn Marino 
4528*e4b17023SJohn Marino   /* Set up ID.  */
4529*e4b17023SJohn Marino   memset (&id, 0, sizeof (id));
4530*e4b17023SJohn Marino   id.src_fn = current_function_decl;
4531*e4b17023SJohn Marino   id.dst_fn = current_function_decl;
4532*e4b17023SJohn Marino   id.decl_map = pointer_map_create ();
4533*e4b17023SJohn Marino   id.debug_map = NULL;
4534*e4b17023SJohn Marino 
4535*e4b17023SJohn Marino   id.copy_decl = copy_decl_no_change;
4536*e4b17023SJohn Marino   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
4537*e4b17023SJohn Marino   id.transform_new_cfg = false;
4538*e4b17023SJohn Marino   id.transform_return_to_modify = false;
4539*e4b17023SJohn Marino   id.transform_lang_insert_block = NULL;
4540*e4b17023SJohn Marino 
4541*e4b17023SJohn Marino   /* Walk the tree once to find local labels.  */
4542*e4b17023SJohn Marino   walk_tree_without_duplicates (&expr, mark_local_for_remap_r, &id);
4543*e4b17023SJohn Marino 
4544*e4b17023SJohn Marino   /* Walk the tree again, copying, remapping, and unsaving.  */
4545*e4b17023SJohn Marino   walk_tree (&expr, unsave_r, &id, NULL);
4546*e4b17023SJohn Marino 
4547*e4b17023SJohn Marino   /* Clean up.  */
4548*e4b17023SJohn Marino   pointer_map_destroy (id.decl_map);
4549*e4b17023SJohn Marino   if (id.debug_map)
4550*e4b17023SJohn Marino     pointer_map_destroy (id.debug_map);
4551*e4b17023SJohn Marino 
4552*e4b17023SJohn Marino   return expr;
4553*e4b17023SJohn Marino }
4554*e4b17023SJohn Marino 
4555*e4b17023SJohn Marino /* Called via walk_gimple_seq.  If *GSIP points to a GIMPLE_LABEL for a local
4556*e4b17023SJohn Marino    label, copies the declaration and enters it in the splay_tree in DATA (which
4557*e4b17023SJohn Marino    is really a 'copy_body_data *'.  */
4558*e4b17023SJohn Marino 
4559*e4b17023SJohn Marino static tree
4560*e4b17023SJohn Marino mark_local_labels_stmt (gimple_stmt_iterator *gsip,
4561*e4b17023SJohn Marino 		        bool *handled_ops_p ATTRIBUTE_UNUSED,
4562*e4b17023SJohn Marino 		        struct walk_stmt_info *wi)
4563*e4b17023SJohn Marino {
4564*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) wi->info;
4565*e4b17023SJohn Marino   gimple stmt = gsi_stmt (*gsip);
4566*e4b17023SJohn Marino 
4567*e4b17023SJohn Marino   if (gimple_code (stmt) == GIMPLE_LABEL)
4568*e4b17023SJohn Marino     {
4569*e4b17023SJohn Marino       tree decl = gimple_label_label (stmt);
4570*e4b17023SJohn Marino 
4571*e4b17023SJohn Marino       /* Copy the decl and remember the copy.  */
4572*e4b17023SJohn Marino       insert_decl_map (id, decl, id->copy_decl (decl, id));
4573*e4b17023SJohn Marino     }
4574*e4b17023SJohn Marino 
4575*e4b17023SJohn Marino   return NULL_TREE;
4576*e4b17023SJohn Marino }
4577*e4b17023SJohn Marino 
4578*e4b17023SJohn Marino 
4579*e4b17023SJohn Marino /* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local.
4580*e4b17023SJohn Marino    Using the splay_tree pointed to by ST (which is really a `splay_tree'),
4581*e4b17023SJohn Marino    remaps all local declarations to appropriate replacements in gimple
4582*e4b17023SJohn Marino    operands. */
4583*e4b17023SJohn Marino 
4584*e4b17023SJohn Marino static tree
4585*e4b17023SJohn Marino replace_locals_op (tree *tp, int *walk_subtrees, void *data)
4586*e4b17023SJohn Marino {
4587*e4b17023SJohn Marino   struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
4588*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) wi->info;
4589*e4b17023SJohn Marino   struct pointer_map_t *st = id->decl_map;
4590*e4b17023SJohn Marino   tree *n;
4591*e4b17023SJohn Marino   tree expr = *tp;
4592*e4b17023SJohn Marino 
4593*e4b17023SJohn Marino   /* Only a local declaration (variable or label).  */
4594*e4b17023SJohn Marino   if ((TREE_CODE (expr) == VAR_DECL
4595*e4b17023SJohn Marino        && !TREE_STATIC (expr))
4596*e4b17023SJohn Marino       || TREE_CODE (expr) == LABEL_DECL)
4597*e4b17023SJohn Marino     {
4598*e4b17023SJohn Marino       /* Lookup the declaration.  */
4599*e4b17023SJohn Marino       n = (tree *) pointer_map_contains (st, expr);
4600*e4b17023SJohn Marino 
4601*e4b17023SJohn Marino       /* If it's there, remap it.  */
4602*e4b17023SJohn Marino       if (n)
4603*e4b17023SJohn Marino 	*tp = *n;
4604*e4b17023SJohn Marino       *walk_subtrees = 0;
4605*e4b17023SJohn Marino     }
4606*e4b17023SJohn Marino   else if (TREE_CODE (expr) == STATEMENT_LIST
4607*e4b17023SJohn Marino 	   || TREE_CODE (expr) == BIND_EXPR
4608*e4b17023SJohn Marino 	   || TREE_CODE (expr) == SAVE_EXPR)
4609*e4b17023SJohn Marino     gcc_unreachable ();
4610*e4b17023SJohn Marino   else if (TREE_CODE (expr) == TARGET_EXPR)
4611*e4b17023SJohn Marino     {
4612*e4b17023SJohn Marino       /* Don't mess with a TARGET_EXPR that hasn't been expanded.
4613*e4b17023SJohn Marino          It's OK for this to happen if it was part of a subtree that
4614*e4b17023SJohn Marino          isn't immediately expanded, such as operand 2 of another
4615*e4b17023SJohn Marino          TARGET_EXPR.  */
4616*e4b17023SJohn Marino       if (!TREE_OPERAND (expr, 1))
4617*e4b17023SJohn Marino 	{
4618*e4b17023SJohn Marino 	  TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3);
4619*e4b17023SJohn Marino 	  TREE_OPERAND (expr, 3) = NULL_TREE;
4620*e4b17023SJohn Marino 	}
4621*e4b17023SJohn Marino     }
4622*e4b17023SJohn Marino 
4623*e4b17023SJohn Marino   /* Keep iterating.  */
4624*e4b17023SJohn Marino   return NULL_TREE;
4625*e4b17023SJohn Marino }
4626*e4b17023SJohn Marino 
4627*e4b17023SJohn Marino 
4628*e4b17023SJohn Marino /* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local.
4629*e4b17023SJohn Marino    Using the splay_tree pointed to by ST (which is really a `splay_tree'),
4630*e4b17023SJohn Marino    remaps all local declarations to appropriate replacements in gimple
4631*e4b17023SJohn Marino    statements. */
4632*e4b17023SJohn Marino 
4633*e4b17023SJohn Marino static tree
4634*e4b17023SJohn Marino replace_locals_stmt (gimple_stmt_iterator *gsip,
4635*e4b17023SJohn Marino 		     bool *handled_ops_p ATTRIBUTE_UNUSED,
4636*e4b17023SJohn Marino 		     struct walk_stmt_info *wi)
4637*e4b17023SJohn Marino {
4638*e4b17023SJohn Marino   copy_body_data *id = (copy_body_data *) wi->info;
4639*e4b17023SJohn Marino   gimple stmt = gsi_stmt (*gsip);
4640*e4b17023SJohn Marino 
4641*e4b17023SJohn Marino   if (gimple_code (stmt) == GIMPLE_BIND)
4642*e4b17023SJohn Marino     {
4643*e4b17023SJohn Marino       tree block = gimple_bind_block (stmt);
4644*e4b17023SJohn Marino 
4645*e4b17023SJohn Marino       if (block)
4646*e4b17023SJohn Marino 	{
4647*e4b17023SJohn Marino 	  remap_block (&block, id);
4648*e4b17023SJohn Marino 	  gimple_bind_set_block (stmt, block);
4649*e4b17023SJohn Marino 	}
4650*e4b17023SJohn Marino 
4651*e4b17023SJohn Marino       /* This will remap a lot of the same decls again, but this should be
4652*e4b17023SJohn Marino 	 harmless.  */
4653*e4b17023SJohn Marino       if (gimple_bind_vars (stmt))
4654*e4b17023SJohn Marino 	gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), NULL, id));
4655*e4b17023SJohn Marino     }
4656*e4b17023SJohn Marino 
4657*e4b17023SJohn Marino   /* Keep iterating.  */
4658*e4b17023SJohn Marino   return NULL_TREE;
4659*e4b17023SJohn Marino }
4660*e4b17023SJohn Marino 
4661*e4b17023SJohn Marino 
4662*e4b17023SJohn Marino /* Copies everything in SEQ and replaces variables and labels local to
4663*e4b17023SJohn Marino    current_function_decl.  */
4664*e4b17023SJohn Marino 
4665*e4b17023SJohn Marino gimple_seq
4666*e4b17023SJohn Marino copy_gimple_seq_and_replace_locals (gimple_seq seq)
4667*e4b17023SJohn Marino {
4668*e4b17023SJohn Marino   copy_body_data id;
4669*e4b17023SJohn Marino   struct walk_stmt_info wi;
4670*e4b17023SJohn Marino   struct pointer_set_t *visited;
4671*e4b17023SJohn Marino   gimple_seq copy;
4672*e4b17023SJohn Marino 
4673*e4b17023SJohn Marino   /* There's nothing to do for NULL_TREE.  */
4674*e4b17023SJohn Marino   if (seq == NULL)
4675*e4b17023SJohn Marino     return seq;
4676*e4b17023SJohn Marino 
4677*e4b17023SJohn Marino   /* Set up ID.  */
4678*e4b17023SJohn Marino   memset (&id, 0, sizeof (id));
4679*e4b17023SJohn Marino   id.src_fn = current_function_decl;
4680*e4b17023SJohn Marino   id.dst_fn = current_function_decl;
4681*e4b17023SJohn Marino   id.decl_map = pointer_map_create ();
4682*e4b17023SJohn Marino   id.debug_map = NULL;
4683*e4b17023SJohn Marino 
4684*e4b17023SJohn Marino   id.copy_decl = copy_decl_no_change;
4685*e4b17023SJohn Marino   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
4686*e4b17023SJohn Marino   id.transform_new_cfg = false;
4687*e4b17023SJohn Marino   id.transform_return_to_modify = false;
4688*e4b17023SJohn Marino   id.transform_lang_insert_block = NULL;
4689*e4b17023SJohn Marino 
4690*e4b17023SJohn Marino   /* Walk the tree once to find local labels.  */
4691*e4b17023SJohn Marino   memset (&wi, 0, sizeof (wi));
4692*e4b17023SJohn Marino   visited = pointer_set_create ();
4693*e4b17023SJohn Marino   wi.info = &id;
4694*e4b17023SJohn Marino   wi.pset = visited;
4695*e4b17023SJohn Marino   walk_gimple_seq (seq, mark_local_labels_stmt, NULL, &wi);
4696*e4b17023SJohn Marino   pointer_set_destroy (visited);
4697*e4b17023SJohn Marino 
4698*e4b17023SJohn Marino   copy = gimple_seq_copy (seq);
4699*e4b17023SJohn Marino 
4700*e4b17023SJohn Marino   /* Walk the copy, remapping decls.  */
4701*e4b17023SJohn Marino   memset (&wi, 0, sizeof (wi));
4702*e4b17023SJohn Marino   wi.info = &id;
4703*e4b17023SJohn Marino   walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi);
4704*e4b17023SJohn Marino 
4705*e4b17023SJohn Marino   /* Clean up.  */
4706*e4b17023SJohn Marino   pointer_map_destroy (id.decl_map);
4707*e4b17023SJohn Marino   if (id.debug_map)
4708*e4b17023SJohn Marino     pointer_map_destroy (id.debug_map);
4709*e4b17023SJohn Marino 
4710*e4b17023SJohn Marino   return copy;
4711*e4b17023SJohn Marino }
4712*e4b17023SJohn Marino 
4713*e4b17023SJohn Marino 
4714*e4b17023SJohn Marino /* Allow someone to determine if SEARCH is a child of TOP from gdb.  */
4715*e4b17023SJohn Marino 
4716*e4b17023SJohn Marino static tree
4717*e4b17023SJohn Marino debug_find_tree_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
4718*e4b17023SJohn Marino {
4719*e4b17023SJohn Marino   if (*tp == data)
4720*e4b17023SJohn Marino     return (tree) data;
4721*e4b17023SJohn Marino   else
4722*e4b17023SJohn Marino     return NULL;
4723*e4b17023SJohn Marino }
4724*e4b17023SJohn Marino 
4725*e4b17023SJohn Marino DEBUG_FUNCTION bool
4726*e4b17023SJohn Marino debug_find_tree (tree top, tree search)
4727*e4b17023SJohn Marino {
4728*e4b17023SJohn Marino   return walk_tree_without_duplicates (&top, debug_find_tree_1, search) != 0;
4729*e4b17023SJohn Marino }
4730*e4b17023SJohn Marino 
4731*e4b17023SJohn Marino 
4732*e4b17023SJohn Marino /* Declare the variables created by the inliner.  Add all the variables in
4733*e4b17023SJohn Marino    VARS to BIND_EXPR.  */
4734*e4b17023SJohn Marino 
4735*e4b17023SJohn Marino static void
4736*e4b17023SJohn Marino declare_inline_vars (tree block, tree vars)
4737*e4b17023SJohn Marino {
4738*e4b17023SJohn Marino   tree t;
4739*e4b17023SJohn Marino   for (t = vars; t; t = DECL_CHAIN (t))
4740*e4b17023SJohn Marino     {
4741*e4b17023SJohn Marino       DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
4742*e4b17023SJohn Marino       gcc_assert (!TREE_STATIC (t) && !TREE_ASM_WRITTEN (t));
4743*e4b17023SJohn Marino       add_local_decl (cfun, t);
4744*e4b17023SJohn Marino     }
4745*e4b17023SJohn Marino 
4746*e4b17023SJohn Marino   if (block)
4747*e4b17023SJohn Marino     BLOCK_VARS (block) = chainon (BLOCK_VARS (block), vars);
4748*e4b17023SJohn Marino }
4749*e4b17023SJohn Marino 
4750*e4b17023SJohn Marino /* Copy NODE (which must be a DECL).  The DECL originally was in the FROM_FN,
4751*e4b17023SJohn Marino    but now it will be in the TO_FN.  PARM_TO_VAR means enable PARM_DECL to
4752*e4b17023SJohn Marino    VAR_DECL translation.  */
4753*e4b17023SJohn Marino 
4754*e4b17023SJohn Marino static tree
4755*e4b17023SJohn Marino copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy)
4756*e4b17023SJohn Marino {
4757*e4b17023SJohn Marino   /* Don't generate debug information for the copy if we wouldn't have
4758*e4b17023SJohn Marino      generated it for the copy either.  */
4759*e4b17023SJohn Marino   DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
4760*e4b17023SJohn Marino   DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
4761*e4b17023SJohn Marino 
4762*e4b17023SJohn Marino   /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what
4763*e4b17023SJohn Marino      declaration inspired this copy.  */
4764*e4b17023SJohn Marino   DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
4765*e4b17023SJohn Marino 
4766*e4b17023SJohn Marino   /* The new variable/label has no RTL, yet.  */
4767*e4b17023SJohn Marino   if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL)
4768*e4b17023SJohn Marino       && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
4769*e4b17023SJohn Marino     SET_DECL_RTL (copy, 0);
4770*e4b17023SJohn Marino 
4771*e4b17023SJohn Marino   /* These args would always appear unused, if not for this.  */
4772*e4b17023SJohn Marino   TREE_USED (copy) = 1;
4773*e4b17023SJohn Marino 
4774*e4b17023SJohn Marino   /* Set the context for the new declaration.  */
4775*e4b17023SJohn Marino   if (!DECL_CONTEXT (decl))
4776*e4b17023SJohn Marino     /* Globals stay global.  */
4777*e4b17023SJohn Marino     ;
4778*e4b17023SJohn Marino   else if (DECL_CONTEXT (decl) != id->src_fn)
4779*e4b17023SJohn Marino     /* Things that weren't in the scope of the function we're inlining
4780*e4b17023SJohn Marino        from aren't in the scope we're inlining to, either.  */
4781*e4b17023SJohn Marino     ;
4782*e4b17023SJohn Marino   else if (TREE_STATIC (decl))
4783*e4b17023SJohn Marino     /* Function-scoped static variables should stay in the original
4784*e4b17023SJohn Marino        function.  */
4785*e4b17023SJohn Marino     ;
4786*e4b17023SJohn Marino   else
4787*e4b17023SJohn Marino     /* Ordinary automatic local variables are now in the scope of the
4788*e4b17023SJohn Marino        new function.  */
4789*e4b17023SJohn Marino     DECL_CONTEXT (copy) = id->dst_fn;
4790*e4b17023SJohn Marino 
4791*e4b17023SJohn Marino   if (TREE_CODE (decl) == VAR_DECL
4792*e4b17023SJohn Marino       /* C++ clones functions during parsing, before
4793*e4b17023SJohn Marino 	 referenced_vars.  */
4794*e4b17023SJohn Marino       && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
4795*e4b17023SJohn Marino       && referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
4796*e4b17023SJohn Marino 				DECL_UID (decl)))
4797*e4b17023SJohn Marino     add_referenced_var (copy);
4798*e4b17023SJohn Marino 
4799*e4b17023SJohn Marino   return copy;
4800*e4b17023SJohn Marino }
4801*e4b17023SJohn Marino 
4802*e4b17023SJohn Marino static tree
4803*e4b17023SJohn Marino copy_decl_to_var (tree decl, copy_body_data *id)
4804*e4b17023SJohn Marino {
4805*e4b17023SJohn Marino   tree copy, type;
4806*e4b17023SJohn Marino 
4807*e4b17023SJohn Marino   gcc_assert (TREE_CODE (decl) == PARM_DECL
4808*e4b17023SJohn Marino 	      || TREE_CODE (decl) == RESULT_DECL);
4809*e4b17023SJohn Marino 
4810*e4b17023SJohn Marino   type = TREE_TYPE (decl);
4811*e4b17023SJohn Marino 
4812*e4b17023SJohn Marino   copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
4813*e4b17023SJohn Marino 		     VAR_DECL, DECL_NAME (decl), type);
4814*e4b17023SJohn Marino   if (DECL_PT_UID_SET_P (decl))
4815*e4b17023SJohn Marino     SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
4816*e4b17023SJohn Marino   TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
4817*e4b17023SJohn Marino   TREE_READONLY (copy) = TREE_READONLY (decl);
4818*e4b17023SJohn Marino   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
4819*e4b17023SJohn Marino   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
4820*e4b17023SJohn Marino 
4821*e4b17023SJohn Marino   return copy_decl_for_dup_finish (id, decl, copy);
4822*e4b17023SJohn Marino }
4823*e4b17023SJohn Marino 
4824*e4b17023SJohn Marino /* Like copy_decl_to_var, but create a return slot object instead of a
4825*e4b17023SJohn Marino    pointer variable for return by invisible reference.  */
4826*e4b17023SJohn Marino 
4827*e4b17023SJohn Marino static tree
4828*e4b17023SJohn Marino copy_result_decl_to_var (tree decl, copy_body_data *id)
4829*e4b17023SJohn Marino {
4830*e4b17023SJohn Marino   tree copy, type;
4831*e4b17023SJohn Marino 
4832*e4b17023SJohn Marino   gcc_assert (TREE_CODE (decl) == PARM_DECL
4833*e4b17023SJohn Marino 	      || TREE_CODE (decl) == RESULT_DECL);
4834*e4b17023SJohn Marino 
4835*e4b17023SJohn Marino   type = TREE_TYPE (decl);
4836*e4b17023SJohn Marino   if (DECL_BY_REFERENCE (decl))
4837*e4b17023SJohn Marino     type = TREE_TYPE (type);
4838*e4b17023SJohn Marino 
4839*e4b17023SJohn Marino   copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn),
4840*e4b17023SJohn Marino 		     VAR_DECL, DECL_NAME (decl), type);
4841*e4b17023SJohn Marino   if (DECL_PT_UID_SET_P (decl))
4842*e4b17023SJohn Marino     SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
4843*e4b17023SJohn Marino   TREE_READONLY (copy) = TREE_READONLY (decl);
4844*e4b17023SJohn Marino   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
4845*e4b17023SJohn Marino   if (!DECL_BY_REFERENCE (decl))
4846*e4b17023SJohn Marino     {
4847*e4b17023SJohn Marino       TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
4848*e4b17023SJohn Marino       DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
4849*e4b17023SJohn Marino     }
4850*e4b17023SJohn Marino 
4851*e4b17023SJohn Marino   return copy_decl_for_dup_finish (id, decl, copy);
4852*e4b17023SJohn Marino }
4853*e4b17023SJohn Marino 
4854*e4b17023SJohn Marino tree
4855*e4b17023SJohn Marino copy_decl_no_change (tree decl, copy_body_data *id)
4856*e4b17023SJohn Marino {
4857*e4b17023SJohn Marino   tree copy;
4858*e4b17023SJohn Marino 
4859*e4b17023SJohn Marino   copy = copy_node (decl);
4860*e4b17023SJohn Marino 
4861*e4b17023SJohn Marino   /* The COPY is not abstract; it will be generated in DST_FN.  */
4862*e4b17023SJohn Marino   DECL_ABSTRACT (copy) = 0;
4863*e4b17023SJohn Marino   lang_hooks.dup_lang_specific_decl (copy);
4864*e4b17023SJohn Marino 
4865*e4b17023SJohn Marino   /* TREE_ADDRESSABLE isn't used to indicate that a label's address has
4866*e4b17023SJohn Marino      been taken; it's for internal bookkeeping in expand_goto_internal.  */
4867*e4b17023SJohn Marino   if (TREE_CODE (copy) == LABEL_DECL)
4868*e4b17023SJohn Marino     {
4869*e4b17023SJohn Marino       TREE_ADDRESSABLE (copy) = 0;
4870*e4b17023SJohn Marino       LABEL_DECL_UID (copy) = -1;
4871*e4b17023SJohn Marino     }
4872*e4b17023SJohn Marino 
4873*e4b17023SJohn Marino   return copy_decl_for_dup_finish (id, decl, copy);
4874*e4b17023SJohn Marino }
4875*e4b17023SJohn Marino 
4876*e4b17023SJohn Marino static tree
4877*e4b17023SJohn Marino copy_decl_maybe_to_var (tree decl, copy_body_data *id)
4878*e4b17023SJohn Marino {
4879*e4b17023SJohn Marino   if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL)
4880*e4b17023SJohn Marino     return copy_decl_to_var (decl, id);
4881*e4b17023SJohn Marino   else
4882*e4b17023SJohn Marino     return copy_decl_no_change (decl, id);
4883*e4b17023SJohn Marino }
4884*e4b17023SJohn Marino 
4885*e4b17023SJohn Marino /* Return a copy of the function's argument tree.  */
4886*e4b17023SJohn Marino static tree
4887*e4b17023SJohn Marino copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
4888*e4b17023SJohn Marino 			       bitmap args_to_skip, tree *vars)
4889*e4b17023SJohn Marino {
4890*e4b17023SJohn Marino   tree arg, *parg;
4891*e4b17023SJohn Marino   tree new_parm = NULL;
4892*e4b17023SJohn Marino   int i = 0;
4893*e4b17023SJohn Marino 
4894*e4b17023SJohn Marino   parg = &new_parm;
4895*e4b17023SJohn Marino 
4896*e4b17023SJohn Marino   for (arg = orig_parm; arg; arg = DECL_CHAIN (arg), i++)
4897*e4b17023SJohn Marino     if (!args_to_skip || !bitmap_bit_p (args_to_skip, i))
4898*e4b17023SJohn Marino       {
4899*e4b17023SJohn Marino         tree new_tree = remap_decl (arg, id);
4900*e4b17023SJohn Marino 	if (TREE_CODE (new_tree) != PARM_DECL)
4901*e4b17023SJohn Marino 	  new_tree = id->copy_decl (arg, id);
4902*e4b17023SJohn Marino         lang_hooks.dup_lang_specific_decl (new_tree);
4903*e4b17023SJohn Marino         *parg = new_tree;
4904*e4b17023SJohn Marino 	parg = &DECL_CHAIN (new_tree);
4905*e4b17023SJohn Marino       }
4906*e4b17023SJohn Marino     else if (!pointer_map_contains (id->decl_map, arg))
4907*e4b17023SJohn Marino       {
4908*e4b17023SJohn Marino 	/* Make an equivalent VAR_DECL.  If the argument was used
4909*e4b17023SJohn Marino 	   as temporary variable later in function, the uses will be
4910*e4b17023SJohn Marino 	   replaced by local variable.  */
4911*e4b17023SJohn Marino 	tree var = copy_decl_to_var (arg, id);
4912*e4b17023SJohn Marino 	add_referenced_var (var);
4913*e4b17023SJohn Marino 	insert_decl_map (id, arg, var);
4914*e4b17023SJohn Marino         /* Declare this new variable.  */
4915*e4b17023SJohn Marino         DECL_CHAIN (var) = *vars;
4916*e4b17023SJohn Marino         *vars = var;
4917*e4b17023SJohn Marino       }
4918*e4b17023SJohn Marino   return new_parm;
4919*e4b17023SJohn Marino }
4920*e4b17023SJohn Marino 
4921*e4b17023SJohn Marino /* Return a copy of the function's static chain.  */
4922*e4b17023SJohn Marino static tree
4923*e4b17023SJohn Marino copy_static_chain (tree static_chain, copy_body_data * id)
4924*e4b17023SJohn Marino {
4925*e4b17023SJohn Marino   tree *chain_copy, *pvar;
4926*e4b17023SJohn Marino 
4927*e4b17023SJohn Marino   chain_copy = &static_chain;
4928*e4b17023SJohn Marino   for (pvar = chain_copy; *pvar; pvar = &DECL_CHAIN (*pvar))
4929*e4b17023SJohn Marino     {
4930*e4b17023SJohn Marino       tree new_tree = remap_decl (*pvar, id);
4931*e4b17023SJohn Marino       lang_hooks.dup_lang_specific_decl (new_tree);
4932*e4b17023SJohn Marino       DECL_CHAIN (new_tree) = DECL_CHAIN (*pvar);
4933*e4b17023SJohn Marino       *pvar = new_tree;
4934*e4b17023SJohn Marino     }
4935*e4b17023SJohn Marino   return static_chain;
4936*e4b17023SJohn Marino }
4937*e4b17023SJohn Marino 
4938*e4b17023SJohn Marino /* Return true if the function is allowed to be versioned.
4939*e4b17023SJohn Marino    This is a guard for the versioning functionality.  */
4940*e4b17023SJohn Marino 
4941*e4b17023SJohn Marino bool
4942*e4b17023SJohn Marino tree_versionable_function_p (tree fndecl)
4943*e4b17023SJohn Marino {
4944*e4b17023SJohn Marino   return (!lookup_attribute ("noclone", DECL_ATTRIBUTES (fndecl))
4945*e4b17023SJohn Marino 	  && copy_forbidden (DECL_STRUCT_FUNCTION (fndecl), fndecl) == NULL);
4946*e4b17023SJohn Marino }
4947*e4b17023SJohn Marino 
4948*e4b17023SJohn Marino /* Delete all unreachable basic blocks and update callgraph.
4949*e4b17023SJohn Marino    Doing so is somewhat nontrivial because we need to update all clones and
4950*e4b17023SJohn Marino    remove inline function that become unreachable.  */
4951*e4b17023SJohn Marino 
4952*e4b17023SJohn Marino static bool
4953*e4b17023SJohn Marino delete_unreachable_blocks_update_callgraph (copy_body_data *id)
4954*e4b17023SJohn Marino {
4955*e4b17023SJohn Marino   bool changed = false;
4956*e4b17023SJohn Marino   basic_block b, next_bb;
4957*e4b17023SJohn Marino 
4958*e4b17023SJohn Marino   find_unreachable_blocks ();
4959*e4b17023SJohn Marino 
4960*e4b17023SJohn Marino   /* Delete all unreachable basic blocks.  */
4961*e4b17023SJohn Marino 
4962*e4b17023SJohn Marino   for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb)
4963*e4b17023SJohn Marino     {
4964*e4b17023SJohn Marino       next_bb = b->next_bb;
4965*e4b17023SJohn Marino 
4966*e4b17023SJohn Marino       if (!(b->flags & BB_REACHABLE))
4967*e4b17023SJohn Marino 	{
4968*e4b17023SJohn Marino           gimple_stmt_iterator bsi;
4969*e4b17023SJohn Marino 
4970*e4b17023SJohn Marino           for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi))
4971*e4b17023SJohn Marino 	    if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL)
4972*e4b17023SJohn Marino 	      {
4973*e4b17023SJohn Marino 	        struct cgraph_edge *e;
4974*e4b17023SJohn Marino 		struct cgraph_node *node;
4975*e4b17023SJohn Marino 
4976*e4b17023SJohn Marino 	        if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
4977*e4b17023SJohn Marino 		  {
4978*e4b17023SJohn Marino 		    if (!e->inline_failed)
4979*e4b17023SJohn Marino 		      cgraph_remove_node_and_inline_clones (e->callee);
4980*e4b17023SJohn Marino 		    else
4981*e4b17023SJohn Marino 	              cgraph_remove_edge (e);
4982*e4b17023SJohn Marino 		  }
4983*e4b17023SJohn Marino 		if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
4984*e4b17023SJohn Marino 		    && id->dst_node->clones)
4985*e4b17023SJohn Marino      		  for (node = id->dst_node->clones; node != id->dst_node;)
4986*e4b17023SJohn Marino 		    {
4987*e4b17023SJohn Marino 	              if ((e = cgraph_edge (node, gsi_stmt (bsi))) != NULL)
4988*e4b17023SJohn Marino 			{
4989*e4b17023SJohn Marino 		          if (!e->inline_failed)
4990*e4b17023SJohn Marino 		            cgraph_remove_node_and_inline_clones (e->callee);
4991*e4b17023SJohn Marino 			  else
4992*e4b17023SJohn Marino 	                    cgraph_remove_edge (e);
4993*e4b17023SJohn Marino 			}
4994*e4b17023SJohn Marino 
4995*e4b17023SJohn Marino 		      if (node->clones)
4996*e4b17023SJohn Marino 			node = node->clones;
4997*e4b17023SJohn Marino 		      else if (node->next_sibling_clone)
4998*e4b17023SJohn Marino 			node = node->next_sibling_clone;
4999*e4b17023SJohn Marino 		      else
5000*e4b17023SJohn Marino 			{
5001*e4b17023SJohn Marino 			  while (node != id->dst_node && !node->next_sibling_clone)
5002*e4b17023SJohn Marino 			    node = node->clone_of;
5003*e4b17023SJohn Marino 			  if (node != id->dst_node)
5004*e4b17023SJohn Marino 			    node = node->next_sibling_clone;
5005*e4b17023SJohn Marino 			}
5006*e4b17023SJohn Marino 		    }
5007*e4b17023SJohn Marino 	      }
5008*e4b17023SJohn Marino 	  delete_basic_block (b);
5009*e4b17023SJohn Marino 	  changed = true;
5010*e4b17023SJohn Marino 	}
5011*e4b17023SJohn Marino     }
5012*e4b17023SJohn Marino 
5013*e4b17023SJohn Marino   return changed;
5014*e4b17023SJohn Marino }
5015*e4b17023SJohn Marino 
5016*e4b17023SJohn Marino /* Update clone info after duplication.  */
5017*e4b17023SJohn Marino 
5018*e4b17023SJohn Marino static void
5019*e4b17023SJohn Marino update_clone_info (copy_body_data * id)
5020*e4b17023SJohn Marino {
5021*e4b17023SJohn Marino   struct cgraph_node *node;
5022*e4b17023SJohn Marino   if (!id->dst_node->clones)
5023*e4b17023SJohn Marino     return;
5024*e4b17023SJohn Marino   for (node = id->dst_node->clones; node != id->dst_node;)
5025*e4b17023SJohn Marino     {
5026*e4b17023SJohn Marino       /* First update replace maps to match the new body.  */
5027*e4b17023SJohn Marino       if (node->clone.tree_map)
5028*e4b17023SJohn Marino         {
5029*e4b17023SJohn Marino 	  unsigned int i;
5030*e4b17023SJohn Marino           for (i = 0; i < VEC_length (ipa_replace_map_p, node->clone.tree_map); i++)
5031*e4b17023SJohn Marino 	    {
5032*e4b17023SJohn Marino 	      struct ipa_replace_map *replace_info;
5033*e4b17023SJohn Marino 	      replace_info = VEC_index (ipa_replace_map_p, node->clone.tree_map, i);
5034*e4b17023SJohn Marino 	      walk_tree (&replace_info->old_tree, copy_tree_body_r, id, NULL);
5035*e4b17023SJohn Marino 	      walk_tree (&replace_info->new_tree, copy_tree_body_r, id, NULL);
5036*e4b17023SJohn Marino 	    }
5037*e4b17023SJohn Marino 	}
5038*e4b17023SJohn Marino       if (node->clones)
5039*e4b17023SJohn Marino 	node = node->clones;
5040*e4b17023SJohn Marino       else if (node->next_sibling_clone)
5041*e4b17023SJohn Marino 	node = node->next_sibling_clone;
5042*e4b17023SJohn Marino       else
5043*e4b17023SJohn Marino 	{
5044*e4b17023SJohn Marino 	  while (node != id->dst_node && !node->next_sibling_clone)
5045*e4b17023SJohn Marino 	    node = node->clone_of;
5046*e4b17023SJohn Marino 	  if (node != id->dst_node)
5047*e4b17023SJohn Marino 	    node = node->next_sibling_clone;
5048*e4b17023SJohn Marino 	}
5049*e4b17023SJohn Marino     }
5050*e4b17023SJohn Marino }
5051*e4b17023SJohn Marino 
5052*e4b17023SJohn Marino /* Create a copy of a function's tree.
5053*e4b17023SJohn Marino    OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes
5054*e4b17023SJohn Marino    of the original function and the new copied function
5055*e4b17023SJohn Marino    respectively.  In case we want to replace a DECL
5056*e4b17023SJohn Marino    tree with another tree while duplicating the function's
5057*e4b17023SJohn Marino    body, TREE_MAP represents the mapping between these
5058*e4b17023SJohn Marino    trees. If UPDATE_CLONES is set, the call_stmt fields
5059*e4b17023SJohn Marino    of edges of clones of the function will be updated.
5060*e4b17023SJohn Marino 
5061*e4b17023SJohn Marino    If non-NULL ARGS_TO_SKIP determine function parameters to remove
5062*e4b17023SJohn Marino    from new version.
5063*e4b17023SJohn Marino    If SKIP_RETURN is true, the new version will return void.
5064*e4b17023SJohn Marino    If non-NULL BLOCK_TO_COPY determine what basic blocks to copy.
5065*e4b17023SJohn Marino    If non_NULL NEW_ENTRY determine new entry BB of the clone.
5066*e4b17023SJohn Marino */
5067*e4b17023SJohn Marino void
5068*e4b17023SJohn Marino tree_function_versioning (tree old_decl, tree new_decl,
5069*e4b17023SJohn Marino 			  VEC(ipa_replace_map_p,gc)* tree_map,
5070*e4b17023SJohn Marino 			  bool update_clones, bitmap args_to_skip,
5071*e4b17023SJohn Marino 			  bool skip_return, bitmap blocks_to_copy,
5072*e4b17023SJohn Marino 			  basic_block new_entry)
5073*e4b17023SJohn Marino {
5074*e4b17023SJohn Marino   struct cgraph_node *old_version_node;
5075*e4b17023SJohn Marino   struct cgraph_node *new_version_node;
5076*e4b17023SJohn Marino   copy_body_data id;
5077*e4b17023SJohn Marino   tree p;
5078*e4b17023SJohn Marino   unsigned i;
5079*e4b17023SJohn Marino   struct ipa_replace_map *replace_info;
5080*e4b17023SJohn Marino   basic_block old_entry_block, bb;
5081*e4b17023SJohn Marino   VEC (gimple, heap) *init_stmts = VEC_alloc (gimple, heap, 10);
5082*e4b17023SJohn Marino 
5083*e4b17023SJohn Marino   tree old_current_function_decl = current_function_decl;
5084*e4b17023SJohn Marino   tree vars = NULL_TREE;
5085*e4b17023SJohn Marino 
5086*e4b17023SJohn Marino   gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL
5087*e4b17023SJohn Marino 	      && TREE_CODE (new_decl) == FUNCTION_DECL);
5088*e4b17023SJohn Marino   DECL_POSSIBLY_INLINED (old_decl) = 1;
5089*e4b17023SJohn Marino 
5090*e4b17023SJohn Marino   old_version_node = cgraph_get_node (old_decl);
5091*e4b17023SJohn Marino   gcc_checking_assert (old_version_node);
5092*e4b17023SJohn Marino   new_version_node = cgraph_get_node (new_decl);
5093*e4b17023SJohn Marino   gcc_checking_assert (new_version_node);
5094*e4b17023SJohn Marino 
5095*e4b17023SJohn Marino   /* Copy over debug args.  */
5096*e4b17023SJohn Marino   if (DECL_HAS_DEBUG_ARGS_P (old_decl))
5097*e4b17023SJohn Marino     {
5098*e4b17023SJohn Marino       VEC(tree, gc) **new_debug_args, **old_debug_args;
5099*e4b17023SJohn Marino       gcc_checking_assert (decl_debug_args_lookup (new_decl) == NULL);
5100*e4b17023SJohn Marino       DECL_HAS_DEBUG_ARGS_P (new_decl) = 0;
5101*e4b17023SJohn Marino       old_debug_args = decl_debug_args_lookup (old_decl);
5102*e4b17023SJohn Marino       if (old_debug_args)
5103*e4b17023SJohn Marino 	{
5104*e4b17023SJohn Marino 	  new_debug_args = decl_debug_args_insert (new_decl);
5105*e4b17023SJohn Marino 	  *new_debug_args = VEC_copy (tree, gc, *old_debug_args);
5106*e4b17023SJohn Marino 	}
5107*e4b17023SJohn Marino     }
5108*e4b17023SJohn Marino 
5109*e4b17023SJohn Marino   /* Output the inlining info for this abstract function, since it has been
5110*e4b17023SJohn Marino      inlined.  If we don't do this now, we can lose the information about the
5111*e4b17023SJohn Marino      variables in the function when the blocks get blown away as soon as we
5112*e4b17023SJohn Marino      remove the cgraph node.  */
5113*e4b17023SJohn Marino   (*debug_hooks->outlining_inline_function) (old_decl);
5114*e4b17023SJohn Marino 
5115*e4b17023SJohn Marino   DECL_ARTIFICIAL (new_decl) = 1;
5116*e4b17023SJohn Marino   DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
5117*e4b17023SJohn Marino   DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
5118*e4b17023SJohn Marino 
5119*e4b17023SJohn Marino   /* Prepare the data structures for the tree copy.  */
5120*e4b17023SJohn Marino   memset (&id, 0, sizeof (id));
5121*e4b17023SJohn Marino 
5122*e4b17023SJohn Marino   /* Generate a new name for the new version. */
5123*e4b17023SJohn Marino   id.statements_to_fold = pointer_set_create ();
5124*e4b17023SJohn Marino 
5125*e4b17023SJohn Marino   id.decl_map = pointer_map_create ();
5126*e4b17023SJohn Marino   id.debug_map = NULL;
5127*e4b17023SJohn Marino   id.src_fn = old_decl;
5128*e4b17023SJohn Marino   id.dst_fn = new_decl;
5129*e4b17023SJohn Marino   id.src_node = old_version_node;
5130*e4b17023SJohn Marino   id.dst_node = new_version_node;
5131*e4b17023SJohn Marino   id.src_cfun = DECL_STRUCT_FUNCTION (old_decl);
5132*e4b17023SJohn Marino   if (id.src_node->ipa_transforms_to_apply)
5133*e4b17023SJohn Marino     {
5134*e4b17023SJohn Marino       VEC(ipa_opt_pass,heap) * old_transforms_to_apply = id.dst_node->ipa_transforms_to_apply;
5135*e4b17023SJohn Marino       unsigned int i;
5136*e4b17023SJohn Marino 
5137*e4b17023SJohn Marino       id.dst_node->ipa_transforms_to_apply = VEC_copy (ipa_opt_pass, heap,
5138*e4b17023SJohn Marino 					               id.src_node->ipa_transforms_to_apply);
5139*e4b17023SJohn Marino       for (i = 0; i < VEC_length (ipa_opt_pass, old_transforms_to_apply); i++)
5140*e4b17023SJohn Marino         VEC_safe_push (ipa_opt_pass, heap, id.dst_node->ipa_transforms_to_apply,
5141*e4b17023SJohn Marino 		       VEC_index (ipa_opt_pass,
5142*e4b17023SJohn Marino 		       		  old_transforms_to_apply,
5143*e4b17023SJohn Marino 				  i));
5144*e4b17023SJohn Marino     }
5145*e4b17023SJohn Marino 
5146*e4b17023SJohn Marino   id.copy_decl = copy_decl_no_change;
5147*e4b17023SJohn Marino   id.transform_call_graph_edges
5148*e4b17023SJohn Marino     = update_clones ? CB_CGE_MOVE_CLONES : CB_CGE_MOVE;
5149*e4b17023SJohn Marino   id.transform_new_cfg = true;
5150*e4b17023SJohn Marino   id.transform_return_to_modify = false;
5151*e4b17023SJohn Marino   id.transform_lang_insert_block = NULL;
5152*e4b17023SJohn Marino 
5153*e4b17023SJohn Marino   current_function_decl = new_decl;
5154*e4b17023SJohn Marino   old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
5155*e4b17023SJohn Marino     (DECL_STRUCT_FUNCTION (old_decl));
5156*e4b17023SJohn Marino   initialize_cfun (new_decl, old_decl,
5157*e4b17023SJohn Marino 		   old_entry_block->count);
5158*e4b17023SJohn Marino   DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta
5159*e4b17023SJohn Marino     = id.src_cfun->gimple_df->ipa_pta;
5160*e4b17023SJohn Marino   push_cfun (DECL_STRUCT_FUNCTION (new_decl));
5161*e4b17023SJohn Marino 
5162*e4b17023SJohn Marino   /* Copy the function's static chain.  */
5163*e4b17023SJohn Marino   p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl;
5164*e4b17023SJohn Marino   if (p)
5165*e4b17023SJohn Marino     DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl =
5166*e4b17023SJohn Marino       copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl,
5167*e4b17023SJohn Marino 			 &id);
5168*e4b17023SJohn Marino 
5169*e4b17023SJohn Marino   /* If there's a tree_map, prepare for substitution.  */
5170*e4b17023SJohn Marino   if (tree_map)
5171*e4b17023SJohn Marino     for (i = 0; i < VEC_length (ipa_replace_map_p, tree_map); i++)
5172*e4b17023SJohn Marino       {
5173*e4b17023SJohn Marino 	gimple init;
5174*e4b17023SJohn Marino 	replace_info = VEC_index (ipa_replace_map_p, tree_map, i);
5175*e4b17023SJohn Marino 	if (replace_info->replace_p)
5176*e4b17023SJohn Marino 	  {
5177*e4b17023SJohn Marino 	    tree op = replace_info->new_tree;
5178*e4b17023SJohn Marino 	    if (!replace_info->old_tree)
5179*e4b17023SJohn Marino 	      {
5180*e4b17023SJohn Marino 		int i = replace_info->parm_num;
5181*e4b17023SJohn Marino 		tree parm;
5182*e4b17023SJohn Marino 		for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
5183*e4b17023SJohn Marino 		  i --;
5184*e4b17023SJohn Marino 		replace_info->old_tree = parm;
5185*e4b17023SJohn Marino 	      }
5186*e4b17023SJohn Marino 
5187*e4b17023SJohn Marino 
5188*e4b17023SJohn Marino 	    STRIP_NOPS (op);
5189*e4b17023SJohn Marino 
5190*e4b17023SJohn Marino 	    if (TREE_CODE (op) == VIEW_CONVERT_EXPR)
5191*e4b17023SJohn Marino 	      op = TREE_OPERAND (op, 0);
5192*e4b17023SJohn Marino 
5193*e4b17023SJohn Marino 	    if (TREE_CODE (op) == ADDR_EXPR)
5194*e4b17023SJohn Marino 	      {
5195*e4b17023SJohn Marino 		op = TREE_OPERAND (op, 0);
5196*e4b17023SJohn Marino 		while (handled_component_p (op))
5197*e4b17023SJohn Marino 		  op = TREE_OPERAND (op, 0);
5198*e4b17023SJohn Marino 		if (TREE_CODE (op) == VAR_DECL)
5199*e4b17023SJohn Marino 		  add_referenced_var (op);
5200*e4b17023SJohn Marino 	      }
5201*e4b17023SJohn Marino 	    gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL);
5202*e4b17023SJohn Marino 	    init = setup_one_parameter (&id, replace_info->old_tree,
5203*e4b17023SJohn Marino 	    			        replace_info->new_tree, id.src_fn,
5204*e4b17023SJohn Marino 				        NULL,
5205*e4b17023SJohn Marino 				        &vars);
5206*e4b17023SJohn Marino 	    if (init)
5207*e4b17023SJohn Marino 	      VEC_safe_push (gimple, heap, init_stmts, init);
5208*e4b17023SJohn Marino 	  }
5209*e4b17023SJohn Marino       }
5210*e4b17023SJohn Marino   /* Copy the function's arguments.  */
5211*e4b17023SJohn Marino   if (DECL_ARGUMENTS (old_decl) != NULL_TREE)
5212*e4b17023SJohn Marino     DECL_ARGUMENTS (new_decl) =
5213*e4b17023SJohn Marino       copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id,
5214*e4b17023SJohn Marino       				     args_to_skip, &vars);
5215*e4b17023SJohn Marino 
5216*e4b17023SJohn Marino   DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id);
5217*e4b17023SJohn Marino   BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl;
5218*e4b17023SJohn Marino 
5219*e4b17023SJohn Marino   declare_inline_vars (DECL_INITIAL (new_decl), vars);
5220*e4b17023SJohn Marino 
5221*e4b17023SJohn Marino   if (!VEC_empty (tree, DECL_STRUCT_FUNCTION (old_decl)->local_decls))
5222*e4b17023SJohn Marino     /* Add local vars.  */
5223*e4b17023SJohn Marino     add_local_variables (DECL_STRUCT_FUNCTION (old_decl), cfun, &id, false);
5224*e4b17023SJohn Marino 
5225*e4b17023SJohn Marino   if (DECL_RESULT (old_decl) == NULL_TREE)
5226*e4b17023SJohn Marino     ;
5227*e4b17023SJohn Marino   else if (skip_return && !VOID_TYPE_P (TREE_TYPE (DECL_RESULT (old_decl))))
5228*e4b17023SJohn Marino     {
5229*e4b17023SJohn Marino       DECL_RESULT (new_decl)
5230*e4b17023SJohn Marino 	= build_decl (DECL_SOURCE_LOCATION (DECL_RESULT (old_decl)),
5231*e4b17023SJohn Marino 		      RESULT_DECL, NULL_TREE, void_type_node);
5232*e4b17023SJohn Marino       DECL_CONTEXT (DECL_RESULT (new_decl)) = new_decl;
5233*e4b17023SJohn Marino       cfun->returns_struct = 0;
5234*e4b17023SJohn Marino       cfun->returns_pcc_struct = 0;
5235*e4b17023SJohn Marino     }
5236*e4b17023SJohn Marino   else
5237*e4b17023SJohn Marino     {
5238*e4b17023SJohn Marino       tree old_name;
5239*e4b17023SJohn Marino       DECL_RESULT (new_decl) = remap_decl (DECL_RESULT (old_decl), &id);
5240*e4b17023SJohn Marino       lang_hooks.dup_lang_specific_decl (DECL_RESULT (new_decl));
5241*e4b17023SJohn Marino       if (gimple_in_ssa_p (id.src_cfun)
5242*e4b17023SJohn Marino 	  && DECL_BY_REFERENCE (DECL_RESULT (old_decl))
5243*e4b17023SJohn Marino 	  && (old_name
5244*e4b17023SJohn Marino 	      = gimple_default_def (id.src_cfun, DECL_RESULT (old_decl))))
5245*e4b17023SJohn Marino 	{
5246*e4b17023SJohn Marino 	  tree new_name = make_ssa_name (DECL_RESULT (new_decl), NULL);
5247*e4b17023SJohn Marino 	  insert_decl_map (&id, old_name, new_name);
5248*e4b17023SJohn Marino 	  SSA_NAME_DEF_STMT (new_name) = gimple_build_nop ();
5249*e4b17023SJohn Marino 	  set_default_def (DECL_RESULT (new_decl), new_name);
5250*e4b17023SJohn Marino 	}
5251*e4b17023SJohn Marino     }
5252*e4b17023SJohn Marino 
5253*e4b17023SJohn Marino   /* Copy the Function's body.  */
5254*e4b17023SJohn Marino   copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE,
5255*e4b17023SJohn Marino 	     ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry);
5256*e4b17023SJohn Marino 
5257*e4b17023SJohn Marino   /* Renumber the lexical scoping (non-code) blocks consecutively.  */
5258*e4b17023SJohn Marino   number_blocks (new_decl);
5259*e4b17023SJohn Marino 
5260*e4b17023SJohn Marino   /* We want to create the BB unconditionally, so that the addition of
5261*e4b17023SJohn Marino      debug stmts doesn't affect BB count, which may in the end cause
5262*e4b17023SJohn Marino      codegen differences.  */
5263*e4b17023SJohn Marino   bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR));
5264*e4b17023SJohn Marino   while (VEC_length (gimple, init_stmts))
5265*e4b17023SJohn Marino     insert_init_stmt (&id, bb, VEC_pop (gimple, init_stmts));
5266*e4b17023SJohn Marino   update_clone_info (&id);
5267*e4b17023SJohn Marino 
5268*e4b17023SJohn Marino   /* Remap the nonlocal_goto_save_area, if any.  */
5269*e4b17023SJohn Marino   if (cfun->nonlocal_goto_save_area)
5270*e4b17023SJohn Marino     {
5271*e4b17023SJohn Marino       struct walk_stmt_info wi;
5272*e4b17023SJohn Marino 
5273*e4b17023SJohn Marino       memset (&wi, 0, sizeof (wi));
5274*e4b17023SJohn Marino       wi.info = &id;
5275*e4b17023SJohn Marino       walk_tree (&cfun->nonlocal_goto_save_area, remap_gimple_op_r, &wi, NULL);
5276*e4b17023SJohn Marino     }
5277*e4b17023SJohn Marino 
5278*e4b17023SJohn Marino   /* Clean up.  */
5279*e4b17023SJohn Marino   pointer_map_destroy (id.decl_map);
5280*e4b17023SJohn Marino   if (id.debug_map)
5281*e4b17023SJohn Marino     pointer_map_destroy (id.debug_map);
5282*e4b17023SJohn Marino   free_dominance_info (CDI_DOMINATORS);
5283*e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
5284*e4b17023SJohn Marino 
5285*e4b17023SJohn Marino   fold_marked_statements (0, id.statements_to_fold);
5286*e4b17023SJohn Marino   pointer_set_destroy (id.statements_to_fold);
5287*e4b17023SJohn Marino   fold_cond_expr_cond ();
5288*e4b17023SJohn Marino   delete_unreachable_blocks_update_callgraph (&id);
5289*e4b17023SJohn Marino   if (id.dst_node->analyzed)
5290*e4b17023SJohn Marino     cgraph_rebuild_references ();
5291*e4b17023SJohn Marino   update_ssa (TODO_update_ssa);
5292*e4b17023SJohn Marino 
5293*e4b17023SJohn Marino   /* After partial cloning we need to rescale frequencies, so they are
5294*e4b17023SJohn Marino      within proper range in the cloned function.  */
5295*e4b17023SJohn Marino   if (new_entry)
5296*e4b17023SJohn Marino     {
5297*e4b17023SJohn Marino       struct cgraph_edge *e;
5298*e4b17023SJohn Marino       rebuild_frequencies ();
5299*e4b17023SJohn Marino 
5300*e4b17023SJohn Marino       new_version_node->count = ENTRY_BLOCK_PTR->count;
5301*e4b17023SJohn Marino       for (e = new_version_node->callees; e; e = e->next_callee)
5302*e4b17023SJohn Marino 	{
5303*e4b17023SJohn Marino 	  basic_block bb = gimple_bb (e->call_stmt);
5304*e4b17023SJohn Marino 	  e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
5305*e4b17023SJohn Marino 							 bb);
5306*e4b17023SJohn Marino 	  e->count = bb->count;
5307*e4b17023SJohn Marino 	}
5308*e4b17023SJohn Marino       for (e = new_version_node->indirect_calls; e; e = e->next_callee)
5309*e4b17023SJohn Marino 	{
5310*e4b17023SJohn Marino 	  basic_block bb = gimple_bb (e->call_stmt);
5311*e4b17023SJohn Marino 	  e->frequency = compute_call_stmt_bb_frequency (current_function_decl,
5312*e4b17023SJohn Marino 							 bb);
5313*e4b17023SJohn Marino 	  e->count = bb->count;
5314*e4b17023SJohn Marino 	}
5315*e4b17023SJohn Marino     }
5316*e4b17023SJohn Marino 
5317*e4b17023SJohn Marino   free_dominance_info (CDI_DOMINATORS);
5318*e4b17023SJohn Marino   free_dominance_info (CDI_POST_DOMINATORS);
5319*e4b17023SJohn Marino 
5320*e4b17023SJohn Marino   gcc_assert (!id.debug_stmts);
5321*e4b17023SJohn Marino   VEC_free (gimple, heap, init_stmts);
5322*e4b17023SJohn Marino   pop_cfun ();
5323*e4b17023SJohn Marino   current_function_decl = old_current_function_decl;
5324*e4b17023SJohn Marino   gcc_assert (!current_function_decl
5325*e4b17023SJohn Marino 	      || DECL_STRUCT_FUNCTION (current_function_decl) == cfun);
5326*e4b17023SJohn Marino   return;
5327*e4b17023SJohn Marino }
5328*e4b17023SJohn Marino 
5329*e4b17023SJohn Marino /* EXP is CALL_EXPR present in a GENERIC expression tree.  Try to integrate
5330*e4b17023SJohn Marino    the callee and return the inlined body on success.  */
5331*e4b17023SJohn Marino 
5332*e4b17023SJohn Marino tree
5333*e4b17023SJohn Marino maybe_inline_call_in_expr (tree exp)
5334*e4b17023SJohn Marino {
5335*e4b17023SJohn Marino   tree fn = get_callee_fndecl (exp);
5336*e4b17023SJohn Marino 
5337*e4b17023SJohn Marino   /* We can only try to inline "const" functions.  */
5338*e4b17023SJohn Marino   if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn))
5339*e4b17023SJohn Marino     {
5340*e4b17023SJohn Marino       struct pointer_map_t *decl_map = pointer_map_create ();
5341*e4b17023SJohn Marino       call_expr_arg_iterator iter;
5342*e4b17023SJohn Marino       copy_body_data id;
5343*e4b17023SJohn Marino       tree param, arg, t;
5344*e4b17023SJohn Marino 
5345*e4b17023SJohn Marino       /* Remap the parameters.  */
5346*e4b17023SJohn Marino       for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
5347*e4b17023SJohn Marino 	   param;
5348*e4b17023SJohn Marino 	   param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
5349*e4b17023SJohn Marino 	*pointer_map_insert (decl_map, param) = arg;
5350*e4b17023SJohn Marino 
5351*e4b17023SJohn Marino       memset (&id, 0, sizeof (id));
5352*e4b17023SJohn Marino       id.src_fn = fn;
5353*e4b17023SJohn Marino       id.dst_fn = current_function_decl;
5354*e4b17023SJohn Marino       id.src_cfun = DECL_STRUCT_FUNCTION (fn);
5355*e4b17023SJohn Marino       id.decl_map = decl_map;
5356*e4b17023SJohn Marino 
5357*e4b17023SJohn Marino       id.copy_decl = copy_decl_no_change;
5358*e4b17023SJohn Marino       id.transform_call_graph_edges = CB_CGE_DUPLICATE;
5359*e4b17023SJohn Marino       id.transform_new_cfg = false;
5360*e4b17023SJohn Marino       id.transform_return_to_modify = true;
5361*e4b17023SJohn Marino       id.transform_lang_insert_block = NULL;
5362*e4b17023SJohn Marino 
5363*e4b17023SJohn Marino       /* Make sure not to unshare trees behind the front-end's back
5364*e4b17023SJohn Marino 	 since front-end specific mechanisms may rely on sharing.  */
5365*e4b17023SJohn Marino       id.regimplify = false;
5366*e4b17023SJohn Marino       id.do_not_unshare = true;
5367*e4b17023SJohn Marino 
5368*e4b17023SJohn Marino       /* We're not inside any EH region.  */
5369*e4b17023SJohn Marino       id.eh_lp_nr = 0;
5370*e4b17023SJohn Marino 
5371*e4b17023SJohn Marino       t = copy_tree_body (&id);
5372*e4b17023SJohn Marino       pointer_map_destroy (decl_map);
5373*e4b17023SJohn Marino 
5374*e4b17023SJohn Marino       /* We can only return something suitable for use in a GENERIC
5375*e4b17023SJohn Marino 	 expression tree.  */
5376*e4b17023SJohn Marino       if (TREE_CODE (t) == MODIFY_EXPR)
5377*e4b17023SJohn Marino 	return TREE_OPERAND (t, 1);
5378*e4b17023SJohn Marino     }
5379*e4b17023SJohn Marino 
5380*e4b17023SJohn Marino    return NULL_TREE;
5381*e4b17023SJohn Marino }
5382*e4b17023SJohn Marino 
5383*e4b17023SJohn Marino /* Duplicate a type, fields and all.  */
5384*e4b17023SJohn Marino 
5385*e4b17023SJohn Marino tree
5386*e4b17023SJohn Marino build_duplicate_type (tree type)
5387*e4b17023SJohn Marino {
5388*e4b17023SJohn Marino   struct copy_body_data id;
5389*e4b17023SJohn Marino 
5390*e4b17023SJohn Marino   memset (&id, 0, sizeof (id));
5391*e4b17023SJohn Marino   id.src_fn = current_function_decl;
5392*e4b17023SJohn Marino   id.dst_fn = current_function_decl;
5393*e4b17023SJohn Marino   id.src_cfun = cfun;
5394*e4b17023SJohn Marino   id.decl_map = pointer_map_create ();
5395*e4b17023SJohn Marino   id.debug_map = NULL;
5396*e4b17023SJohn Marino   id.copy_decl = copy_decl_no_change;
5397*e4b17023SJohn Marino 
5398*e4b17023SJohn Marino   type = remap_type_1 (type, &id);
5399*e4b17023SJohn Marino 
5400*e4b17023SJohn Marino   pointer_map_destroy (id.decl_map);
5401*e4b17023SJohn Marino   if (id.debug_map)
5402*e4b17023SJohn Marino     pointer_map_destroy (id.debug_map);
5403*e4b17023SJohn Marino 
5404*e4b17023SJohn Marino   TYPE_CANONICAL (type) = type;
5405*e4b17023SJohn Marino 
5406*e4b17023SJohn Marino   return type;
5407*e4b17023SJohn Marino }
5408