optimize.c (inlinable_function_p): Allow only smaller single functions.
[platform/upstream/gcc.git] / gcc / cp / optimize.c
1 /* Perform optimizations on tree structure.
2    Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3    Written by Mark Michell (mark@codesourcery.com).
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "tree.h"
25 #include "cp-tree.h"
26 #include "rtl.h"
27 #include "insn-config.h"
28 #include "input.h"
29 #include "integrate.h"
30 #include "toplev.h"
31 #include "varray.h"
32 #include "ggc.h"
33 #include "params.h"
34 #include "hashtab.h"
35 #include "debug.h"
36
37 /* To Do:
38
39    o In order to make inlining-on-trees work, we pessimized
40      function-local static constants.  In particular, they are now
41      always output, even when not addressed.  Fix this by treating
42      function-local static constants just like global static
43      constants; the back-end already knows not to output them if they
44      are not needed.
45
46    o Provide heuristics to clamp inlining of recursive template
47      calls?  */
48
49 /* Data required for function inlining.  */
50
51 typedef struct inline_data
52 {
53   /* A stack of the functions we are inlining.  For example, if we are
54      compiling `f', which calls `g', which calls `h', and we are
55      inlining the body of `h', the stack will contain, `h', followed
56      by `g', followed by `f'.  The first few elements of the stack may
57      contain other functions that we know we should not recurse into,
58      even though they are not directly being inlined.  */
59   varray_type fns;
60   /* The index of the first element of FNS that really represents an
61      inlined function.  */
62   unsigned first_inlined_fn;
63   /* The label to jump to when a return statement is encountered.  If
64      this value is NULL, then return statements will simply be
65      remapped as return statements, rather than as jumps.  */
66   tree ret_label;
67   /* The map from local declarations in the inlined function to
68      equivalents in the function into which it is being inlined.  */
69   splay_tree decl_map;
70   /* Nonzero if we are currently within the cleanup for a
71      TARGET_EXPR.  */
72   int in_target_cleanup_p;
73   /* A stack of the TARGET_EXPRs that we are currently processing.  */
74   varray_type target_exprs;
75   /* A list of the functions current function has inlined.  */
76   varray_type inlined_fns;
77   /* The approximate number of statements we have inlined in the
78      current call stack.  */
79   int inlined_stmts;
80   /* We use the same mechanism to build clones that we do to perform
81      inlining.  However, there are a few places where we need to
82      distinguish between those two situations.  This flag is true if
83      we are cloning, rather than inlining.  */
84   bool cloning_p;
85   /* Hash table used to prevent walk_tree from visiting the same node
86      umpteen million times.  */
87   htab_t tree_pruner;
88 } inline_data;
89
90 /* Prototypes.  */
91
92 static tree initialize_inlined_parameters PARAMS ((inline_data *, tree, tree));
93 static tree declare_return_variable PARAMS ((inline_data *, tree *));
94 static tree copy_body_r PARAMS ((tree *, int *, void *));
95 static tree copy_body PARAMS ((inline_data *));
96 static tree expand_call_inline PARAMS ((tree *, int *, void *));
97 static void expand_calls_inline PARAMS ((tree *, inline_data *));
98 static int inlinable_function_p PARAMS ((tree, inline_data *));
99 static tree remap_decl PARAMS ((tree, inline_data *));
100 static void remap_block PARAMS ((tree, tree, inline_data *));
101 static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *));
102 static void optimize_inline_calls PARAMS ((tree));
103 static tree calls_setjmp_r PARAMS ((tree *, int *, void *));
104 static void update_cloned_parm PARAMS ((tree, tree));
105 static void dump_function PARAMS ((enum tree_dump_index, tree));
106
107 /* The approximate number of instructions per statement.  This number
108    need not be particularly accurate; it is used only to make
109    decisions about when a function is too big to inline.  */
110 #define INSNS_PER_STMT (10)
111
112 /* Remap DECL during the copying of the BLOCK tree for the function.  */
113
114 static tree
115 remap_decl (decl, id)
116      tree decl;
117      inline_data *id;
118 {
119   splay_tree_node n;
120   tree fn;
121
122   /* We only remap local variables in the current function.  */
123   fn = VARRAY_TOP_TREE (id->fns);
124   if (!nonstatic_local_decl_p (decl) || DECL_CONTEXT (decl) != fn)
125     return NULL_TREE;
126
127   /* See if we have remapped this declaration.  */
128   n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
129   /* If we didn't already have an equivalent for this declaration,
130      create one now.  */
131   if (!n)
132     {
133       tree t;
134
135       /* Make a copy of the variable or label.  */
136       t = copy_decl_for_inlining (decl, fn,
137                                   VARRAY_TREE (id->fns, 0));
138
139       /* The decl T could be a dynamic array or other variable size type,
140          in which case some fields need to be remapped because they may
141          contain SAVE_EXPRs.  */
142       walk_tree (&DECL_SIZE (t), copy_body_r, id, NULL);
143       walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
144       if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
145           && TYPE_DOMAIN (TREE_TYPE (t)))
146         {
147           TREE_TYPE (t) = copy_node (TREE_TYPE (t));
148           TYPE_DOMAIN (TREE_TYPE (t))
149             = copy_node (TYPE_DOMAIN (TREE_TYPE (t)));
150           walk_tree (&TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t))),
151                      copy_body_r, id, NULL);
152         }
153
154       if (!DECL_NAME (t) && TREE_TYPE (t)
155           && ANON_AGGR_TYPE_P (TREE_TYPE ((t))))
156         {
157           /* For a VAR_DECL of anonymous type, we must also copy the
158              member VAR_DECLS here and rechain the
159              DECL_ANON_UNION_ELEMS. */
160           tree members = NULL;
161           tree src;
162           
163           for (src = DECL_ANON_UNION_ELEMS (t); src;
164                src = TREE_CHAIN (src))
165             {
166               tree member = remap_decl (TREE_VALUE (src), id);
167
168               my_friendly_assert (!TREE_PURPOSE (src), 20010529);
169               members = tree_cons (NULL, member, members);
170             }
171           DECL_ANON_UNION_ELEMS (t) = nreverse (members);
172         }
173       
174       /* Remember it, so that if we encounter this local entity
175          again we can reuse this copy.  */
176       n = splay_tree_insert (id->decl_map,
177                              (splay_tree_key) decl,
178                              (splay_tree_value) t);
179     }
180
181   return (tree) n->value;
182 }
183
184 /* Copy the SCOPE_STMT_BLOCK associated with SCOPE_STMT to contain
185    remapped versions of the variables therein.  And hook the new block
186    into the block-tree.  If non-NULL, the DECLS are declarations to
187    add to use instead of the BLOCK_VARS in the old block.  */
188
189 static void
190 remap_block (scope_stmt, decls, id)
191      tree scope_stmt;
192      tree decls;
193      inline_data *id;
194 {
195   /* We cannot do this in the cleanup for a TARGET_EXPR since we do
196      not know whether or not expand_expr will actually write out the
197      code we put there.  If it does not, then we'll have more BLOCKs
198      than block-notes, and things will go awry.  At some point, we
199      should make the back-end handle BLOCK notes in a tidier way,
200      without requiring a strict correspondence to the block-tree; then
201      this check can go.  */
202   if (id->in_target_cleanup_p)
203     {
204       SCOPE_STMT_BLOCK (scope_stmt) = NULL_TREE;
205       return;
206     }
207
208   /* If this is the beginning of a scope, remap the associated BLOCK.  */
209   if (SCOPE_BEGIN_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
210     {
211       tree old_block;
212       tree new_block;
213       tree old_var;
214       tree fn;
215
216       /* Make the new block.  */
217       old_block = SCOPE_STMT_BLOCK (scope_stmt);
218       new_block = make_node (BLOCK);
219       TREE_USED (new_block) = TREE_USED (old_block);
220       BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
221       SCOPE_STMT_BLOCK (scope_stmt) = new_block;
222
223       /* Remap its variables.  */
224       for (old_var = decls ? decls : BLOCK_VARS (old_block);
225            old_var;
226            old_var = TREE_CHAIN (old_var))
227         {
228           tree new_var;
229
230           /* Remap the variable.  */
231           new_var = remap_decl (old_var, id);
232           /* If we didn't remap this variable, so we can't mess with
233              its TREE_CHAIN.  If we remapped this variable to
234              something other than a declaration (say, if we mapped it
235              to a constant), then we must similarly omit any mention
236              of it here.  */
237           if (!new_var || !DECL_P (new_var))
238             ;
239           else
240             {
241               TREE_CHAIN (new_var) = BLOCK_VARS (new_block);
242               BLOCK_VARS (new_block) = new_var;
243             }
244         }
245       /* We put the BLOCK_VARS in reverse order; fix that now.  */
246       BLOCK_VARS (new_block) = nreverse (BLOCK_VARS (new_block));
247       fn = VARRAY_TREE (id->fns, 0);
248       if (id->cloning_p)
249         /* We're building a clone; DECL_INITIAL is still
250            error_mark_node, and current_binding_level is the parm
251            binding level.  */
252         insert_block (new_block);
253       else
254         {
255           /* Attach this new block after the DECL_INITIAL block for the
256              function into which this block is being inlined.  In
257              rest_of_compilation we will straighten out the BLOCK tree.  */
258           tree *first_block;
259           if (DECL_INITIAL (fn))
260             first_block = &BLOCK_CHAIN (DECL_INITIAL (fn));
261           else
262             first_block = &DECL_INITIAL (fn);
263           BLOCK_CHAIN (new_block) = *first_block;
264           *first_block = new_block;
265         }
266       /* Remember the remapped block.  */
267       splay_tree_insert (id->decl_map,
268                          (splay_tree_key) old_block,
269                          (splay_tree_value) new_block);
270     }
271   /* If this is the end of a scope, set the SCOPE_STMT_BLOCK to be the
272      remapped block.  */
273   else if (SCOPE_END_P (scope_stmt) && SCOPE_STMT_BLOCK (scope_stmt))
274     {
275       splay_tree_node n;
276
277       /* Find this block in the table of remapped things.  */
278       n = splay_tree_lookup (id->decl_map,
279                              (splay_tree_key) SCOPE_STMT_BLOCK (scope_stmt));
280       my_friendly_assert (n != NULL, 19991203);
281       SCOPE_STMT_BLOCK (scope_stmt) = (tree) n->value;
282     }
283 }
284
285 /* Copy the SCOPE_STMT pointed to by TP.  */
286
287 static void
288 copy_scope_stmt (tp, walk_subtrees, id)
289      tree *tp;
290      int *walk_subtrees;
291      inline_data *id;
292 {
293   tree block;
294
295   /* Remember whether or not this statement was nullified.  When
296      making a copy, copy_tree_r always sets SCOPE_NULLIFIED_P (and
297      doesn't copy the SCOPE_STMT_BLOCK) to free callers from having to
298      deal with copying BLOCKs if they do not wish to do so.  */
299   block = SCOPE_STMT_BLOCK (*tp);
300   /* Copy (and replace) the statement.  */
301   copy_tree_r (tp, walk_subtrees, NULL);
302   /* Restore the SCOPE_STMT_BLOCK.  */
303   SCOPE_STMT_BLOCK (*tp) = block;
304
305   /* Remap the associated block.  */
306   remap_block (*tp, NULL_TREE, id);
307 }
308
309 /* Called from copy_body via walk_tree.  DATA is really an
310    `inline_data *'.  */
311
312 static tree
313 copy_body_r (tp, walk_subtrees, data)
314      tree *tp;
315      int *walk_subtrees;
316      void *data;
317 {
318   inline_data* id;
319   tree fn;
320
321   /* Set up.  */
322   id = (inline_data *) data;
323   fn = VARRAY_TOP_TREE (id->fns);
324
325   /* All automatic variables should have a DECL_CONTEXT indicating
326      what function they come from.  */
327   if ((TREE_CODE (*tp) == VAR_DECL || TREE_CODE (*tp) == LABEL_DECL)
328       && DECL_NAMESPACE_SCOPE_P (*tp))
329     my_friendly_assert (DECL_EXTERNAL (*tp) || TREE_STATIC (*tp),
330                         19991113);
331
332   /* If this is a RETURN_STMT, change it into an EXPR_STMT and a
333      GOTO_STMT with the RET_LABEL as its target.  */
334   if (TREE_CODE (*tp) == RETURN_STMT && id->ret_label)
335     {
336       tree return_stmt = *tp;
337       tree goto_stmt;
338
339       /* Build the GOTO_STMT.  */
340       goto_stmt = build_stmt (GOTO_STMT, id->ret_label);
341       TREE_CHAIN (goto_stmt) = TREE_CHAIN (return_stmt);
342
343       /* If we're returning something, just turn that into an
344          assignment into the equivalent of the original
345          RESULT_DECL.  */
346       if (RETURN_EXPR (return_stmt))
347         {
348           *tp = build_stmt (EXPR_STMT,
349                             RETURN_EXPR (return_stmt));
350           STMT_IS_FULL_EXPR_P (*tp) = 1;
351           /* And then jump to the end of the function.  */
352           TREE_CHAIN (*tp) = goto_stmt;
353         }
354       /* If we're not returning anything just do the jump.  */
355       else
356         *tp = goto_stmt;
357     }
358   /* Local variables and labels need to be replaced by equivalent
359      variables.  We don't want to copy static variables; there's only
360      one of those, no matter how many times we inline the containing
361      function.  */
362   else if (nonstatic_local_decl_p (*tp) && DECL_CONTEXT (*tp) == fn)
363     {
364       tree new_decl;
365
366       /* Remap the declaration.  */
367       new_decl = remap_decl (*tp, id);
368       my_friendly_assert (new_decl != NULL_TREE, 19991203);
369       /* Replace this variable with the copy.  */
370       STRIP_TYPE_NOPS (new_decl);
371       *tp = new_decl;
372     }
373   else if (nonstatic_local_decl_p (*tp)
374            && DECL_CONTEXT (*tp) != VARRAY_TREE (id->fns, 0))
375     my_friendly_abort (0);
376   else if (TREE_CODE (*tp) == SAVE_EXPR)
377     remap_save_expr (tp, id->decl_map, VARRAY_TREE (id->fns, 0),
378                      walk_subtrees);
379   else if (TREE_CODE (*tp) == UNSAVE_EXPR)
380     /* UNSAVE_EXPRs should not be generated until expansion time.  */
381     my_friendly_abort (19991113);
382   /* For a SCOPE_STMT, we must copy the associated block so that we
383      can write out debugging information for the inlined variables.  */
384   else if (TREE_CODE (*tp) == SCOPE_STMT && !id->in_target_cleanup_p)
385     copy_scope_stmt (tp, walk_subtrees, id);
386   /* Otherwise, just copy the node.  Note that copy_tree_r already
387      knows not to copy VAR_DECLs, etc., so this is safe.  */
388   else
389     {
390       copy_tree_r (tp, walk_subtrees, NULL);
391
392       /* The copied TARGET_EXPR has never been expanded, even if the
393          original node was expanded already.  */
394       if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3))
395         {
396           TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3);
397           TREE_OPERAND (*tp, 3) = NULL_TREE;
398         }
399       else if (TREE_CODE (*tp) == MODIFY_EXPR
400                && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1)
401                && nonstatic_local_decl_p (TREE_OPERAND (*tp, 0))
402                && DECL_CONTEXT (TREE_OPERAND (*tp, 0)) == fn)
403         {
404           /* Some assignments VAR = VAR; don't generate any rtl code
405              and thus don't count as variable modification.  Avoid
406              keeping bogosities like 0 = 0.  */
407           tree decl = TREE_OPERAND (*tp, 0), value;
408           splay_tree_node n;
409
410           n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
411           if (n)
412             {
413               value = (tree) n->value;
414               STRIP_TYPE_NOPS (value);
415               if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
416                 *tp = value;
417             }
418         }
419     }
420
421   /* Keep iterating.  */
422   return NULL_TREE;
423 }
424
425 /* Make a copy of the body of FN so that it can be inserted inline in
426    another function.  */
427
428 static tree
429 copy_body (id)
430      inline_data *id;
431 {
432   tree body;
433
434   body = DECL_SAVED_TREE (VARRAY_TOP_TREE (id->fns));
435   walk_tree (&body, copy_body_r, id, NULL);
436
437   return body;
438 }
439
440 /* Generate code to initialize the parameters of the function at the
441    top of the stack in ID from the ARGS (presented as a TREE_LIST).  */
442
443 static tree
444 initialize_inlined_parameters (id, args, fn)
445      inline_data *id;
446      tree args;
447      tree fn;
448 {
449   tree init_stmts;
450   tree parms;
451   tree a;
452   tree p;
453
454   /* Figure out what the parameters are.  */
455   parms = DECL_ARGUMENTS (fn);
456
457   /* Start with no initializations whatsoever.  */
458   init_stmts = NULL_TREE;
459
460   /* Loop through the parameter declarations, replacing each with an
461      equivalent VAR_DECL, appropriately initialized.  */
462   for (p = parms, a = args; p; a = TREE_CHAIN (a), p = TREE_CHAIN (p))
463     {
464       tree init_stmt;
465       tree var;
466       tree value;
467
468       /* Find the initializer.  */
469       value = TREE_VALUE (a);
470       /* If the parameter is never assigned to, we may not need to
471          create a new variable here at all.  Instead, we may be able
472          to just use the argument value.  */
473       if (TREE_READONLY (p)
474           && !TREE_ADDRESSABLE (p)
475           && !TREE_SIDE_EFFECTS (value))
476         {
477           /* Simplify the value, if possible.  */
478           value = fold (decl_constant_value (value));
479
480           /* We can't risk substituting complex expressions.  They
481              might contain variables that will be assigned to later.
482              Theoretically, we could check the expression to see if
483              all of the variables that determine its value are
484              read-only, but we don't bother.  */
485           if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
486             {
487               /* If this is a declaration, wrap it a NOP_EXPR so that
488                  we don't try to put the VALUE on the list of
489                  BLOCK_VARS.  */
490               if (DECL_P (value))
491                 value = build1 (NOP_EXPR, TREE_TYPE (value), value);
492
493               splay_tree_insert (id->decl_map,
494                                  (splay_tree_key) p,
495                                  (splay_tree_value) value);
496               continue;
497             }
498         }
499
500       /* Make an equivalent VAR_DECL.  */
501       var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
502       /* Register the VAR_DECL as the equivalent for the PARM_DECL;
503          that way, when the PARM_DECL is encountered, it will be
504          automatically replaced by the VAR_DECL.  */
505       splay_tree_insert (id->decl_map,
506                          (splay_tree_key) p,
507                          (splay_tree_value) var);
508
509       /* Declare this new variable.  */
510       init_stmt = build_stmt (DECL_STMT, var);
511       TREE_CHAIN (init_stmt) = init_stmts;
512       init_stmts = init_stmt;
513
514       /* Initialize this VAR_DECL from the equivalent argument.  If
515          the argument is an object, created via a constructor or copy,
516          this will not result in an extra copy: the TARGET_EXPR
517          representing the argument will be bound to VAR, and the
518          object will be constructed in VAR.  */
519       if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
520         DECL_INITIAL (var) = value;
521       else
522         {
523           /* Even if P was TREE_READONLY, the new VAR should not be.
524              In the original code, we would have constructed a
525              temporary, and then the function body would have never
526              changed the value of P.  However, now, we will be
527              constructing VAR directly.  The constructor body may
528              change its value multiple times as it is being
529              constructed.  Therefore, it must not be TREE_READONLY;
530              the back-end assumes that TREE_READONLY variable is
531              assigned to only once.  */
532           TREE_READONLY (var) = 0;
533
534           /* Build a run-time initialization.  */
535           init_stmt = build_stmt (EXPR_STMT,
536                                   build (INIT_EXPR, TREE_TYPE (p),
537                                          var, value));
538           /* Add this initialization to the list.  Note that we want the
539              declaration *after* the initialization because we are going
540              to reverse all the initialization statements below.  */
541           TREE_CHAIN (init_stmt) = init_stmts;
542           init_stmts = init_stmt;
543         }
544     }
545
546   /* The initialization statements have been built up in reverse
547      order.  Straighten them out now.  */
548   return nreverse (init_stmts);
549 }
550
551 /* Declare a return variable to replace the RESULT_DECL for the
552    function we are calling.  An appropriate DECL_STMT is returned.
553    The USE_STMT is filled in to contain a use of the declaration to
554    indicate the return value of the function.  */
555
556 static tree
557 declare_return_variable (id, use_stmt)
558      struct inline_data *id;
559      tree *use_stmt;
560 {
561   tree fn = VARRAY_TOP_TREE (id->fns);
562   tree result = DECL_RESULT (fn);
563   tree var;
564   int aggregate_return_p;
565
566   /* We don't need to do anything for functions that don't return
567      anything.  */
568   if (!result || VOID_TYPE_P (TREE_TYPE (result)))
569     {
570       *use_stmt = NULL_TREE;
571       return NULL_TREE;
572     }
573
574   /* Figure out whether or not FN returns an aggregate.  */
575   aggregate_return_p = IS_AGGR_TYPE (TREE_TYPE (result));
576
577   /* If FN returns an aggregate then the caller will always create the
578      temporary (using a TARGET_EXPR) and the call will be the
579      initializing expression for the TARGET_EXPR.  If we were just to
580      create a new VAR_DECL here, then the result of this function
581      would be copied (bitwise) into the variable initialized by the
582      TARGET_EXPR.  That's incorrect, so we must transform any
583      references to the RESULT into references to the target.  */
584   if (aggregate_return_p)
585     {
586       my_friendly_assert (VARRAY_ACTIVE_SIZE (id->target_exprs) != 0,
587                           20000430);
588       var = TREE_OPERAND (VARRAY_TOP_TREE (id->target_exprs), 0);
589       my_friendly_assert
590         (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (var),
591                                                     TREE_TYPE (result)),
592          20000430);
593     }
594   /* Otherwise, make an appropriate copy.  */
595   else
596     var = copy_decl_for_inlining (result, fn, VARRAY_TREE (id->fns, 0));
597
598   /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
599      way, when the RESULT_DECL is encountered, it will be
600      automatically replaced by the VAR_DECL.  */
601   splay_tree_insert (id->decl_map,
602                      (splay_tree_key) result,
603                      (splay_tree_value) var);
604
605   if (DECL_SAVED_FUNCTION_DATA (fn))
606     {
607       tree nrv = DECL_SAVED_FUNCTION_DATA (fn)->x_return_value;
608       if (nrv)
609         {
610           /* We have a named return value; copy the name and source
611              position so we can get reasonable debugging information, and
612              register the return variable as its equivalent.  */
613           DECL_NAME (var) = DECL_NAME (nrv);
614           DECL_SOURCE_FILE (var) = DECL_SOURCE_FILE (nrv);
615           DECL_SOURCE_LINE (var) = DECL_SOURCE_LINE (nrv);
616           splay_tree_insert (id->decl_map,
617                              (splay_tree_key) nrv,
618                              (splay_tree_value) var);
619         }
620     }
621
622   /* Build the USE_STMT.  */
623   *use_stmt = build_stmt (EXPR_STMT, var);
624
625   /* Build the declaration statement if FN does not return an
626      aggregate.  */
627   if (!aggregate_return_p)
628     return build_stmt (DECL_STMT, var);
629   /* If FN does return an aggregate, there's no need to declare the
630      return variable; we're using a variable in our caller's frame.  */
631   else
632     return NULL_TREE;
633 }
634
635 /* Returns non-zero if FN is a function that can be inlined.  */
636
637 static int
638 inlinable_function_p (fn, id)
639      tree fn;
640      inline_data *id;
641 {
642   int inlinable;
643
644   /* If we've already decided this function shouldn't be inlined,
645      there's no need to check again.  */
646   if (DECL_UNINLINABLE (fn))
647     return 0;
648
649   /* Assume it is not inlinable.  */
650   inlinable = 0;
651
652   /* If we're not inlining things, then nothing is inlinable.  */
653   if (!flag_inline_trees)
654     ;
655   /* If the function was not declared `inline', then we don't inline
656      it.  */
657   else if (!DECL_INLINE (fn))
658     ;
659   /* We can't inline varargs functions.  */
660   else if (varargs_function_p (fn))
661     ;
662   /* We can't inline functions that are too big.
663    * Only allow a single function to eat up half of our budget. */
664   else if (DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2)
665     ;
666   /* All is well.  We can inline this function.  Traditionally, GCC
667      has refused to inline functions using alloca, or functions whose
668      values are returned in a PARALLEL, and a few other such obscure
669      conditions.  We are not equally constrained at the tree level.  */
670   else
671     inlinable = 1;
672
673   /* Squirrel away the result so that we don't have to check again.  */
674   DECL_UNINLINABLE (fn) = !inlinable;
675
676   /* Even if this function is not itself too big to inline, it might
677      be that we've done so much inlining already that we don't want to
678      risk too much inlining any more and thus halve the acceptable size. */
679   if ((DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT
680       > MAX_INLINE_INSNS
681       && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4)
682     inlinable = 0;
683
684   /* We can inline a template instantiation only if it's fully
685      instantiated.  */
686   if (inlinable
687       && DECL_TEMPLATE_INFO (fn)
688       && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
689     {
690       fn = instantiate_decl (fn, /*defer_ok=*/0);
691       inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
692     }
693
694   /* If we don't have the function body available, we can't inline
695      it.  */
696   if (!DECL_SAVED_TREE (fn))
697     inlinable = 0;
698
699   /* Don't do recursive inlining, either.  We don't record this in
700      DECL_UNINLINABLE; we may be able to inline this function later.  */
701   if (inlinable)
702     {
703       size_t i;
704
705       for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
706         if (VARRAY_TREE (id->fns, i) == fn)
707           return 0;
708
709       if (inlinable && DECL_LANG_SPECIFIC (fn) && DECL_INLINED_FNS (fn))
710         {
711           int j;
712           tree inlined_fns = DECL_INLINED_FNS (fn);
713
714           for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
715             if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
716               return 0;
717         }
718     }
719
720   /* Return the result.  */
721   return inlinable;
722 }
723
724 /* If *TP is a CALL_EXPR, replace it with its inline expansion.  */
725
726 static tree
727 expand_call_inline (tp, walk_subtrees, data)
728      tree *tp;
729      int *walk_subtrees;
730      void *data;
731 {
732   inline_data *id;
733   tree t;
734   tree expr;
735   tree chain;
736   tree fn;
737   tree scope_stmt;
738   tree use_stmt;
739   tree arg_inits;
740   tree *inlined_body;
741   splay_tree st;
742
743   /* See what we've got.  */
744   id = (inline_data *) data;
745   t = *tp;
746
747   /* Recurse, but letting recursive invocations know that we are
748      inside the body of a TARGET_EXPR.  */
749   if (TREE_CODE (*tp) == TARGET_EXPR)
750     {
751       int i, len = first_rtl_op (TARGET_EXPR);
752
753       /* We're walking our own subtrees.  */
754       *walk_subtrees = 0;
755
756       /* Push *TP on the stack of pending TARGET_EXPRs.  */
757       VARRAY_PUSH_TREE (id->target_exprs, *tp);
758
759       /* Actually walk over them.  This loop is the body of
760          walk_trees, omitting the case where the TARGET_EXPR
761          itself is handled.  */
762       for (i = 0; i < len; ++i)
763         {
764           if (i == 2)
765             ++id->in_target_cleanup_p;
766           walk_tree (&TREE_OPERAND (*tp, i), expand_call_inline, data,
767                      id->tree_pruner);
768           if (i == 2)
769             --id->in_target_cleanup_p;
770         }
771
772       /* We're done with this TARGET_EXPR now.  */
773       VARRAY_POP (id->target_exprs);
774
775       return NULL_TREE;
776     }
777
778   if (TYPE_P (t))
779     /* Because types were not copied in copy_body, CALL_EXPRs beneath
780        them should not be expanded.  This can happen if the type is a
781        dynamic array type, for example.  */
782     *walk_subtrees = 0;
783
784   /* From here on, we're only interested in CALL_EXPRs.  */
785   if (TREE_CODE (t) != CALL_EXPR)
786     return NULL_TREE;
787
788   /* First, see if we can figure out what function is being called.
789      If we cannot, then there is no hope of inlining the function.  */
790   fn = get_callee_fndecl (t);
791   if (!fn)
792     return NULL_TREE;
793
794   /* Don't try to inline functions that are not well-suited to
795      inlining.  */
796   if (!inlinable_function_p (fn, id))
797     return NULL_TREE;
798
799   /* Set the current filename and line number to the function we are
800      inlining so that when we create new _STMT nodes here they get
801      line numbers corresponding to the function we are calling.  We
802      wrap the whole inlined body in an EXPR_WITH_FILE_AND_LINE as well
803      because individual statements don't record the filename.  */
804   push_srcloc (fn->decl.filename, fn->decl.linenum);
805
806   /* Build a statement-expression containing code to initialize the
807      arguments, the actual inline expansion of the body, and a label
808      for the return statements within the function to jump to.  The
809      type of the statement expression is the return type of the
810      function call.  */
811   expr = build_min (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE);
812
813   /* Local declarations will be replaced by their equivalents in this
814      map.  */
815   st = id->decl_map;
816   id->decl_map = splay_tree_new (splay_tree_compare_pointers,
817                                  NULL, NULL);
818
819   /* Initialize the parameters.  */
820   arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn);
821   /* Expand any inlined calls in the initializers.  Do this before we
822      push FN on the stack of functions we are inlining; we want to
823      inline calls to FN that appear in the initializers for the
824      parameters.  */
825   expand_calls_inline (&arg_inits, id);
826   /* And add them to the tree.  */
827   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits);
828
829   /* Record the function we are about to inline so that we can avoid
830      recursing into it.  */
831   VARRAY_PUSH_TREE (id->fns, fn);
832
833   /* Record the function we are about to inline if optimize_function
834      has not been called on it yet and we don't have it in the list.  */
835   if (DECL_LANG_SPECIFIC (fn) && !DECL_INLINED_FNS (fn))
836     {
837       int i;
838
839       for (i = VARRAY_ACTIVE_SIZE (id->inlined_fns) - 1; i >= 0; i--)
840         if (VARRAY_TREE (id->inlined_fns, i) == fn)
841           break;
842       if (i < 0)
843         VARRAY_PUSH_TREE (id->inlined_fns, fn);
844     }
845
846   /* Return statements in the function body will be replaced by jumps
847      to the RET_LABEL.  */
848   id->ret_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
849   DECL_CONTEXT (id->ret_label) = VARRAY_TREE (id->fns, 0);
850
851   /* Create a block to put the parameters in.  We have to do this
852      after the parameters have been remapped because remapping
853      parameters is different from remapping ordinary variables.  */
854   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
855   SCOPE_BEGIN_P (scope_stmt) = 1;
856   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
857   remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
858   TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr);
859   STMT_EXPR_STMT (expr) = scope_stmt;
860
861   /* Tell the debugging backends that this block represents the
862      outermost scope of the inlined function.  */
863   if (SCOPE_STMT_BLOCK (scope_stmt))
864     BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
865
866   /* Declare the return variable for the function.  */
867   STMT_EXPR_STMT (expr)
868     = chainon (STMT_EXPR_STMT (expr),
869                declare_return_variable (id, &use_stmt));
870
871   /* After we've initialized the parameters, we insert the body of the
872      function itself.  */
873   inlined_body = &STMT_EXPR_STMT (expr);
874   while (*inlined_body)
875     inlined_body = &TREE_CHAIN (*inlined_body);
876   *inlined_body = copy_body (id);
877
878   /* Close the block for the parameters.  */
879   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
880   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
881   my_friendly_assert (DECL_INITIAL (fn)
882                       && TREE_CODE (DECL_INITIAL (fn)) == BLOCK,
883                       19991203);
884   remap_block (scope_stmt, NULL_TREE, id);
885   STMT_EXPR_STMT (expr)
886     = chainon (STMT_EXPR_STMT (expr), scope_stmt);
887
888   /* After the body of the function comes the RET_LABEL.  This must come
889      before we evaluate the returned value below, because that evalulation
890      may cause RTL to be generated.  */
891   STMT_EXPR_STMT (expr)
892     = chainon (STMT_EXPR_STMT (expr),
893                build_stmt (LABEL_STMT, id->ret_label));
894
895   /* Finally, mention the returned value so that the value of the
896      statement-expression is the returned value of the function.  */
897   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt);
898
899   /* Clean up.  */
900   splay_tree_delete (id->decl_map);
901   id->decl_map = st;
902
903   /* The new expression has side-effects if the old one did.  */
904   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (t);
905
906   /* Replace the call by the inlined body.  Wrap it in an
907      EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes
908      pointing to the right place.  */
909   chain = TREE_CHAIN (*tp);
910   *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
911                         /*col=*/0);
912   EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
913   TREE_CHAIN (*tp) = chain;
914   pop_srcloc ();
915
916   /* If the value of the new expression is ignored, that's OK.  We
917      don't warn about this for CALL_EXPRs, so we shouldn't warn about
918      the equivalent inlined version either.  */
919   TREE_USED (*tp) = 1;
920
921   /* Our function now has more statements than it did before.  */
922   DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn);
923   id->inlined_stmts += DECL_NUM_STMTS (fn);
924
925   /* Recurse into the body of the just inlined function.  */
926   expand_calls_inline (inlined_body, id);
927   VARRAY_POP (id->fns);
928
929   /* If we've returned to the top level, clear out the record of how
930      much inlining has been done.  */
931   if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn)
932     id->inlined_stmts = 0;
933
934   /* Don't walk into subtrees.  We've already handled them above.  */
935   *walk_subtrees = 0;
936
937   /* Keep iterating.  */
938   return NULL_TREE;
939 }
940
941 /* Walk over the entire tree *TP, replacing CALL_EXPRs with inline
942    expansions as appropriate.  */
943
944 static void
945 expand_calls_inline (tp, id)
946      tree *tp;
947      inline_data *id;
948 {
949   /* Search through *TP, replacing all calls to inline functions by
950      appropriate equivalents.  Use walk_tree in no-duplicates mode
951      to avoid exponential time complexity.  (We can't just use
952      walk_tree_without_duplicates, because of the special TARGET_EXPR
953      handling in expand_calls.  The hash table is set up in
954      optimize_function.  */
955   walk_tree (tp, expand_call_inline, id, id->tree_pruner);
956 }
957
958 /* Expand calls to inline functions in the body of FN.  */
959
960 static void
961 optimize_inline_calls (fn)
962      tree fn;
963 {
964   inline_data id;
965   tree prev_fn;
966   struct saved_scope *s;
967   
968   /* Clear out ID.  */
969   memset (&id, 0, sizeof (id));
970
971   /* Don't allow recursion into FN.  */
972   VARRAY_TREE_INIT (id.fns, 32, "fns");
973   VARRAY_PUSH_TREE (id.fns, fn);
974   /* Or any functions that aren't finished yet.  */
975   prev_fn = NULL_TREE;
976   if (current_function_decl)
977     {
978       VARRAY_PUSH_TREE (id.fns, current_function_decl);
979       prev_fn = current_function_decl;
980     }
981   for (s = scope_chain; s; s = s->prev)
982     if (s->function_decl && s->function_decl != prev_fn)
983       {
984         VARRAY_PUSH_TREE (id.fns, s->function_decl);
985         prev_fn = s->function_decl;
986       }
987   
988   /* Create the stack of TARGET_EXPRs.  */
989   VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs");
990
991   /* Create the list of functions this call will inline.  */
992   VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns");
993
994   /* Keep track of the low-water mark, i.e., the point where the first
995      real inlining is represented in ID.FNS.  */
996   id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns);
997
998   /* Replace all calls to inline functions with the bodies of those
999      functions.  */
1000   id.tree_pruner = htab_create (37, htab_hash_pointer,
1001                                 htab_eq_pointer, NULL);
1002   expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
1003
1004   /* Clean up.  */
1005   htab_delete (id.tree_pruner);
1006   VARRAY_FREE (id.fns);
1007   VARRAY_FREE (id.target_exprs);
1008   if (DECL_LANG_SPECIFIC (fn))
1009     {
1010       tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns));
1011       
1012       memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0),
1013               VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree));
1014       DECL_INLINED_FNS (fn) = ifn;
1015     }
1016   VARRAY_FREE (id.inlined_fns);
1017   
1018   dump_function (TDI_inlined, fn);
1019 }
1020
1021 /* Optimize the body of FN. */
1022
1023 void
1024 optimize_function (fn)
1025      tree fn;
1026 {
1027   dump_function (TDI_original, fn);
1028
1029   /* While in this function, we may choose to go off and compile
1030      another function.  For example, we might instantiate a function
1031      in the hopes of inlining it.  Normally, that wouldn't trigger any
1032      actual RTL code-generation -- but it will if the template is
1033      actually needed.  (For example, if it's address is taken, or if
1034      some other function already refers to the template.)  If
1035      code-generation occurs, then garbage collection will occur, so we
1036      must protect ourselves, just as we do while building up the body
1037      of the function.  */
1038   ++function_depth;
1039
1040   if (flag_inline_trees
1041       /* We do not inline thunks, as (a) the backend tries to optimize
1042          the call to the thunkee, (b) tree based inlining breaks that
1043          optimization, (c) virtual functions are rarely inlineable,
1044          and (d) ASM_OUTPUT_MI_THUNK is there to DTRT anyway.  */
1045       && !DECL_THUNK_P (fn))
1046     optimize_inline_calls (fn);
1047   
1048   /* Undo the call to ggc_push_context above.  */
1049   --function_depth;
1050   
1051   dump_function (TDI_optimized, fn);
1052 }
1053
1054 /* Called from calls_setjmp_p via walk_tree.  */
1055
1056 static tree
1057 calls_setjmp_r (tp, walk_subtrees, data)
1058      tree *tp;
1059      int *walk_subtrees ATTRIBUTE_UNUSED;
1060      void *data ATTRIBUTE_UNUSED;
1061 {
1062   /* We're only interested in FUNCTION_DECLS.  */
1063   if (TREE_CODE (*tp) != FUNCTION_DECL)
1064     return NULL_TREE;
1065
1066   return setjmp_call_p (*tp) ? *tp : NULL_TREE;
1067 }
1068
1069 /* Returns non-zero if FN calls `setjmp' or some other function that
1070    can return more than once.  This function is conservative; it may
1071    occasionally return a non-zero value even when FN does not actually
1072    call `setjmp'.  */
1073
1074 int
1075 calls_setjmp_p (fn)
1076      tree fn;
1077 {
1078   return walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
1079                                        calls_setjmp_r,
1080                                        NULL) != NULL_TREE;
1081 }
1082
1083 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
1084    or destructor.  Update it to ensure that the source-position for
1085    the cloned parameter matches that for the original, and that the
1086    debugging generation code will be able to find the original PARM.  */
1087
1088 static void
1089 update_cloned_parm (parm, cloned_parm)
1090      tree parm;
1091      tree cloned_parm;
1092 {
1093   DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
1094
1095   /* We may have taken its address. */
1096   TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
1097
1098   /* The definition might have different constness. */
1099   TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
1100   
1101   TREE_USED (cloned_parm) = TREE_USED (parm);
1102   
1103   /* The name may have changed from the declaration. */
1104   DECL_NAME (cloned_parm) = DECL_NAME (parm);
1105   DECL_SOURCE_FILE (cloned_parm) = DECL_SOURCE_FILE (parm);
1106   DECL_SOURCE_LINE (cloned_parm) = DECL_SOURCE_LINE (parm);
1107 }
1108
1109 /* FN is a function that has a complete body.  Clone the body as
1110    necessary.  Returns non-zero if there's no longer any need to
1111    process the main body.  */
1112
1113 int
1114 maybe_clone_body (fn)
1115      tree fn;
1116 {
1117   inline_data id;
1118   tree clone;
1119   int first = 1;
1120
1121   /* We only clone constructors and destructors.  */
1122   if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
1123       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
1124     return 0;
1125
1126   /* Emit the DWARF1 abstract instance.  */
1127   (*debug_hooks->deferred_inline_function) (fn);
1128
1129   /* We know that any clones immediately follow FN in the TYPE_METHODS
1130      list.  */
1131   for (clone = TREE_CHAIN (fn);
1132        clone && DECL_CLONED_FUNCTION_P (clone);
1133        clone = TREE_CHAIN (clone), first = 0)
1134     {
1135       tree parm;
1136       tree clone_parm;
1137       int parmno;
1138
1139       /* Update CLONE's source position information to match FN's.  */
1140       DECL_SOURCE_FILE (clone) = DECL_SOURCE_FILE (fn);
1141       DECL_SOURCE_LINE (clone) = DECL_SOURCE_LINE (fn);
1142       DECL_INLINE (clone) = DECL_INLINE (fn);
1143       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
1144       DECL_COMDAT (clone) = DECL_COMDAT (fn);
1145       DECL_WEAK (clone) = DECL_WEAK (fn);
1146       DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
1147       DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
1148       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
1149       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
1150       DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
1151       DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
1152       TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
1153
1154       /* Adjust the parameter names and locations. */
1155       parm = DECL_ARGUMENTS (fn);
1156       clone_parm = DECL_ARGUMENTS (clone);
1157       /* Update the `this' parameter, which is always first.
1158          Sometimes, we end update the `this' parameter twice because
1159          we process it again in the loop below.  That is harmless.  */
1160       update_cloned_parm (parm, clone_parm);
1161       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1162         parm = TREE_CHAIN (parm);
1163       if (DECL_HAS_VTT_PARM_P (fn))
1164         parm = TREE_CHAIN (parm);
1165       if (DECL_HAS_VTT_PARM_P (clone))
1166         clone_parm = TREE_CHAIN (clone_parm);
1167       for (; parm;
1168            parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
1169         {
1170           /* Update this paramter.  */
1171           update_cloned_parm (parm, clone_parm);
1172           /* We should only give unused information for one clone. */
1173           if (!first)
1174             TREE_USED (clone_parm) = 1;
1175         }
1176
1177       /* Start processing the function.  */
1178       push_to_top_level ();
1179       start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED);
1180
1181       /* Just clone the body, as if we were making an inline call.
1182          But, remap the parameters in the callee to the parameters of
1183          caller.  If there's an in-charge parameter, map it to an
1184          appropriate constant.  */
1185       memset (&id, 0, sizeof (id));
1186       VARRAY_TREE_INIT (id.fns, 2, "fns");
1187       VARRAY_PUSH_TREE (id.fns, clone);
1188       VARRAY_PUSH_TREE (id.fns, fn);
1189
1190       /* Cloning is treated slightly differently from inlining.  Set
1191          CLONING_P so that its clear which operation we're performing.  */
1192       id.cloning_p = true;
1193
1194       /* Remap the parameters.  */
1195       id.decl_map = splay_tree_new (splay_tree_compare_pointers,
1196                                     NULL, NULL);
1197       for (parmno = 0,
1198              parm = DECL_ARGUMENTS (fn),
1199              clone_parm = DECL_ARGUMENTS (clone);
1200            parm;
1201            ++parmno,
1202              parm = TREE_CHAIN (parm))
1203         {
1204           /* Map the in-charge parameter to an appropriate constant.  */
1205           if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
1206             {
1207               tree in_charge;
1208               in_charge = in_charge_arg_for_name (DECL_NAME (clone));
1209               splay_tree_insert (id.decl_map,
1210                                  (splay_tree_key) parm,
1211                                  (splay_tree_value) in_charge);
1212             }
1213           else if (DECL_ARTIFICIAL (parm)
1214                    && DECL_NAME (parm) == vtt_parm_identifier)
1215             {
1216               /* For a subobject constructor or destructor, the next
1217                  argument is the VTT parameter.  Remap the VTT_PARM
1218                  from the CLONE to this parameter.  */
1219               if (DECL_HAS_VTT_PARM_P (clone))
1220                 {
1221                   DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
1222                   splay_tree_insert (id.decl_map,
1223                                      (splay_tree_key) parm,
1224                                      (splay_tree_value) clone_parm);
1225                   clone_parm = TREE_CHAIN (clone_parm);
1226                 }
1227               /* Otherwise, map the VTT parameter to `NULL'.  */
1228               else
1229                 {
1230                   splay_tree_insert (id.decl_map,
1231                                      (splay_tree_key) parm,
1232                                      (splay_tree_value) null_pointer_node);
1233                 }
1234             }
1235           /* Map other parameters to their equivalents in the cloned
1236              function.  */
1237           else
1238             {
1239               splay_tree_insert (id.decl_map,
1240                                  (splay_tree_key) parm,
1241                                  (splay_tree_value) clone_parm);
1242               clone_parm = TREE_CHAIN (clone_parm);
1243             }
1244         }
1245
1246       /* Actually copy the body.  */
1247       TREE_CHAIN (DECL_SAVED_TREE (clone)) = copy_body (&id);
1248
1249       /* There are as many statements in the clone as in the
1250          original.  */
1251       DECL_NUM_STMTS (clone) = DECL_NUM_STMTS (fn);
1252
1253       /* Clean up.  */
1254       splay_tree_delete (id.decl_map);
1255       VARRAY_FREE (id.fns);
1256
1257       /* Now, expand this function into RTL, if appropriate.  */
1258       finish_function (0);
1259       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
1260       expand_body (clone);
1261       pop_from_top_level ();
1262     }
1263
1264   /* We don't need to process the original function any further.  */
1265   return 1;
1266 }
1267
1268 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1269
1270 static void
1271 dump_function (phase, fn)
1272      enum tree_dump_index phase;
1273      tree fn;
1274 {
1275   FILE *stream;
1276   int flags;
1277
1278   stream = dump_begin (phase, &flags);
1279   if (stream)
1280     {
1281       fprintf (stream, "\n;; Function %s",
1282                decl_as_string (fn, TFF_DECL_SPECIFIERS));
1283       fprintf (stream, " (%s)\n",
1284                decl_as_string (DECL_ASSEMBLER_NAME (fn), 0));
1285       fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
1286       fprintf (stream, "\n");
1287       
1288       dump_node (fn, TDF_SLIM | flags, stream);
1289       dump_end (phase, stream);
1290     }
1291 }