OSDN Git Service

2001-07-30 H.J. Lu (hjl@gnu.org)
[pf3gnuchains/gcc-fork.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   /* Build the USE_STMT.  */
606   *use_stmt = build_stmt (EXPR_STMT, var);
607
608   /* Build the declaration statement if FN does not return an
609      aggregate.  */
610   if (!aggregate_return_p)
611     return build_stmt (DECL_STMT, var);
612   /* If FN does return an aggregate, there's no need to declare the
613      return variable; we're using a variable in our caller's frame.  */
614   else
615     return NULL_TREE;
616 }
617
618 /* Returns non-zero if FN is a function that can be inlined.  */
619
620 static int
621 inlinable_function_p (fn, id)
622      tree fn;
623      inline_data *id;
624 {
625   int inlinable;
626
627   /* If we've already decided this function shouldn't be inlined,
628      there's no need to check again.  */
629   if (DECL_UNINLINABLE (fn))
630     return 0;
631
632   /* Assume it is not inlinable.  */
633   inlinable = 0;
634
635   /* If we're not inlining things, then nothing is inlinable.  */
636   if (!flag_inline_trees)
637     ;
638   /* If the function was not declared `inline', then we don't inline
639      it.  */
640   else if (!DECL_INLINE (fn))
641     ;
642   /* We can't inline varargs functions.  */
643   else if (varargs_function_p (fn))
644     ;
645   /* We can't inline functions that are too big.  */
646   else if (DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS)
647     ;
648   /* All is well.  We can inline this function.  Traditionally, GCC
649      has refused to inline functions using alloca, or functions whose
650      values are returned in a PARALLEL, and a few other such obscure
651      conditions.  We are not equally constrained at the tree level.  */
652   else
653     inlinable = 1;
654
655   /* Squirrel away the result so that we don't have to check again.  */
656   DECL_UNINLINABLE (fn) = !inlinable;
657
658   /* Even if this function is not itself too big to inline, it might
659      be that we've done so much inlining already that we don't want to
660      risk inlining any more.  */
661   if ((DECL_NUM_STMTS (fn) + id->inlined_stmts) * INSNS_PER_STMT 
662       > MAX_INLINE_INSNS)
663     inlinable = 0;
664
665   /* We can inline a template instantiation only if it's fully
666      instantiated.  */
667   if (inlinable
668       && DECL_TEMPLATE_INFO (fn)
669       && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
670     {
671       fn = instantiate_decl (fn, /*defer_ok=*/0);
672       inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
673     }
674
675   /* If we don't have the function body available, we can't inline
676      it.  */
677   if (!DECL_SAVED_TREE (fn))
678     inlinable = 0;
679
680   /* Don't do recursive inlining, either.  We don't record this in
681      DECL_UNINLINABLE; we may be able to inline this function later.  */
682   if (inlinable)
683     {
684       size_t i;
685
686       for (i = 0; i < VARRAY_ACTIVE_SIZE (id->fns); ++i)
687         if (VARRAY_TREE (id->fns, i) == fn)
688           return 0;
689
690       if (inlinable && DECL_LANG_SPECIFIC (fn) && DECL_INLINED_FNS (fn))
691         {
692           int j;
693           tree inlined_fns = DECL_INLINED_FNS (fn);
694
695           for (j = 0; j < TREE_VEC_LENGTH (inlined_fns); ++j)
696             if (TREE_VEC_ELT (inlined_fns, j) == VARRAY_TREE (id->fns, 0))
697               return 0;
698         }
699     }
700
701   /* Return the result.  */
702   return inlinable;
703 }
704
705 /* If *TP is a CALL_EXPR, replace it with its inline expansion.  */
706
707 static tree
708 expand_call_inline (tp, walk_subtrees, data)
709      tree *tp;
710      int *walk_subtrees;
711      void *data;
712 {
713   inline_data *id;
714   tree t;
715   tree expr;
716   tree chain;
717   tree fn;
718   tree scope_stmt;
719   tree use_stmt;
720   tree arg_inits;
721   tree *inlined_body;
722   splay_tree st;
723
724   /* See what we've got.  */
725   id = (inline_data *) data;
726   t = *tp;
727
728   /* Recurse, but letting recursive invocations know that we are
729      inside the body of a TARGET_EXPR.  */
730   if (TREE_CODE (*tp) == TARGET_EXPR)
731     {
732       int i, len = first_rtl_op (TARGET_EXPR);
733
734       /* We're walking our own subtrees.  */
735       *walk_subtrees = 0;
736
737       /* Push *TP on the stack of pending TARGET_EXPRs.  */
738       VARRAY_PUSH_TREE (id->target_exprs, *tp);
739
740       /* Actually walk over them.  This loop is the body of
741          walk_trees, omitting the case where the TARGET_EXPR
742          itself is handled.  */
743       for (i = 0; i < len; ++i)
744         {
745           if (i == 2)
746             ++id->in_target_cleanup_p;
747           walk_tree (&TREE_OPERAND (*tp, i), expand_call_inline, data,
748                      id->tree_pruner);
749           if (i == 2)
750             --id->in_target_cleanup_p;
751         }
752
753       /* We're done with this TARGET_EXPR now.  */
754       VARRAY_POP (id->target_exprs);
755
756       return NULL_TREE;
757     }
758
759   if (TYPE_P (t))
760     /* Because types were not copied in copy_body, CALL_EXPRs beneath
761        them should not be expanded.  This can happen if the type is a
762        dynamic array type, for example.  */
763     *walk_subtrees = 0;
764
765   /* From here on, we're only interested in CALL_EXPRs.  */
766   if (TREE_CODE (t) != CALL_EXPR)
767     return NULL_TREE;
768
769   /* First, see if we can figure out what function is being called.
770      If we cannot, then there is no hope of inlining the function.  */
771   fn = get_callee_fndecl (t);
772   if (!fn)
773     return NULL_TREE;
774
775   /* Don't try to inline functions that are not well-suited to
776      inlining.  */
777   if (!inlinable_function_p (fn, id))
778     return NULL_TREE;
779
780   /* Set the current filename and line number to the function we are
781      inlining so that when we create new _STMT nodes here they get
782      line numbers corresponding to the function we are calling.  We
783      wrap the whole inlined body in an EXPR_WITH_FILE_AND_LINE as well
784      because individual statements don't record the filename.  */
785   push_srcloc (fn->decl.filename, fn->decl.linenum);
786
787   /* Build a statement-expression containing code to initialize the
788      arguments, the actual inline expansion of the body, and a label
789      for the return statements within the function to jump to.  The
790      type of the statement expression is the return type of the
791      function call.  */
792   expr = build_min (STMT_EXPR, TREE_TYPE (TREE_TYPE (fn)), NULL_TREE);
793
794   /* Local declarations will be replaced by their equivalents in this
795      map.  */
796   st = id->decl_map;
797   id->decl_map = splay_tree_new (splay_tree_compare_pointers,
798                                  NULL, NULL);
799
800   /* Initialize the parameters.  */
801   arg_inits = initialize_inlined_parameters (id, TREE_OPERAND (t, 1), fn);
802   /* Expand any inlined calls in the initializers.  Do this before we
803      push FN on the stack of functions we are inlining; we want to
804      inline calls to FN that appear in the initializers for the
805      parameters.  */
806   expand_calls_inline (&arg_inits, id);
807   /* And add them to the tree.  */
808   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), arg_inits);
809
810   /* Record the function we are about to inline so that we can avoid
811      recursing into it.  */
812   VARRAY_PUSH_TREE (id->fns, fn);
813
814   /* Record the function we are about to inline if optimize_function
815      has not been called on it yet and we don't have it in the list.  */
816   if (DECL_LANG_SPECIFIC (fn) && !DECL_INLINED_FNS (fn))
817     {
818       int i;
819
820       for (i = VARRAY_ACTIVE_SIZE (id->inlined_fns) - 1; i >= 0; i--)
821         if (VARRAY_TREE (id->inlined_fns, i) == fn)
822           break;
823       if (i < 0)
824         VARRAY_PUSH_TREE (id->inlined_fns, fn);
825     }
826
827   /* Return statements in the function body will be replaced by jumps
828      to the RET_LABEL.  */
829   id->ret_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
830   DECL_CONTEXT (id->ret_label) = VARRAY_TREE (id->fns, 0);
831
832   /* Create a block to put the parameters in.  We have to do this
833      after the parameters have been remapped because remapping
834      parameters is different from remapping ordinary variables.  */
835   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
836   SCOPE_BEGIN_P (scope_stmt) = 1;
837   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
838   remap_block (scope_stmt, DECL_ARGUMENTS (fn), id);
839   TREE_CHAIN (scope_stmt) = STMT_EXPR_STMT (expr);
840   STMT_EXPR_STMT (expr) = scope_stmt;
841
842   /* Tell the debugging backends that this block represents the
843      outermost scope of the inlined function.  */
844   if (SCOPE_STMT_BLOCK (scope_stmt))
845     BLOCK_ABSTRACT_ORIGIN (SCOPE_STMT_BLOCK (scope_stmt)) = DECL_ORIGIN (fn);
846
847   /* Declare the return variable for the function.  */
848   STMT_EXPR_STMT (expr)
849     = chainon (STMT_EXPR_STMT (expr),
850                declare_return_variable (id, &use_stmt));
851
852   /* After we've initialized the parameters, we insert the body of the
853      function itself.  */
854   inlined_body = &STMT_EXPR_STMT (expr);
855   while (*inlined_body)
856     inlined_body = &TREE_CHAIN (*inlined_body);
857   *inlined_body = copy_body (id);
858
859   /* Close the block for the parameters.  */
860   scope_stmt = build_stmt (SCOPE_STMT, DECL_INITIAL (fn));
861   SCOPE_NO_CLEANUPS_P (scope_stmt) = 1;
862   my_friendly_assert (DECL_INITIAL (fn)
863                       && TREE_CODE (DECL_INITIAL (fn)) == BLOCK,
864                       19991203);
865   remap_block (scope_stmt, NULL_TREE, id);
866   STMT_EXPR_STMT (expr)
867     = chainon (STMT_EXPR_STMT (expr), scope_stmt);
868
869   /* After the body of the function comes the RET_LABEL.  This must come
870      before we evaluate the returned value below, because that evalulation
871      may cause RTL to be generated.  */
872   STMT_EXPR_STMT (expr)
873     = chainon (STMT_EXPR_STMT (expr),
874                build_stmt (LABEL_STMT, id->ret_label));
875
876   /* Finally, mention the returned value so that the value of the
877      statement-expression is the returned value of the function.  */
878   STMT_EXPR_STMT (expr) = chainon (STMT_EXPR_STMT (expr), use_stmt);
879
880   /* Clean up.  */
881   splay_tree_delete (id->decl_map);
882   id->decl_map = st;
883
884   /* The new expression has side-effects if the old one did.  */
885   TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (t);
886
887   /* Replace the call by the inlined body.  Wrap it in an
888      EXPR_WITH_FILE_LOCATION so that we'll get debugging line notes
889      pointing to the right place.  */
890   chain = TREE_CHAIN (*tp);
891   *tp = build_expr_wfl (expr, DECL_SOURCE_FILE (fn), DECL_SOURCE_LINE (fn),
892                         /*col=*/0);
893   EXPR_WFL_EMIT_LINE_NOTE (*tp) = 1;
894   TREE_CHAIN (*tp) = chain;
895   pop_srcloc ();
896
897   /* If the value of the new expression is ignored, that's OK.  We
898      don't warn about this for CALL_EXPRs, so we shouldn't warn about
899      the equivalent inlined version either.  */
900   TREE_USED (*tp) = 1;
901
902   /* Our function now has more statements than it did before.  */
903   DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn);
904   id->inlined_stmts += DECL_NUM_STMTS (fn);
905
906   /* Recurse into the body of the just inlined function.  */
907   expand_calls_inline (inlined_body, id);
908   VARRAY_POP (id->fns);
909
910   /* If we've returned to the top level, clear out the record of how
911      much inlining has been done.  */
912   if (VARRAY_ACTIVE_SIZE (id->fns) == id->first_inlined_fn)
913     id->inlined_stmts = 0;
914
915   /* Don't walk into subtrees.  We've already handled them above.  */
916   *walk_subtrees = 0;
917
918   /* Keep iterating.  */
919   return NULL_TREE;
920 }
921
922 /* Walk over the entire tree *TP, replacing CALL_EXPRs with inline
923    expansions as appropriate.  */
924
925 static void
926 expand_calls_inline (tp, id)
927      tree *tp;
928      inline_data *id;
929 {
930   /* Search through *TP, replacing all calls to inline functions by
931      appropriate equivalents.  Use walk_tree in no-duplicates mode
932      to avoid exponential time complexity.  (We can't just use
933      walk_tree_without_duplicates, because of the special TARGET_EXPR
934      handling in expand_calls.  The hash table is set up in
935      optimize_function.  */
936   walk_tree (tp, expand_call_inline, id, id->tree_pruner);
937 }
938
939 /* Expand calls to inline functions in the body of FN.  */
940
941 static void
942 optimize_inline_calls (fn)
943      tree fn;
944 {
945   inline_data id;
946   tree prev_fn;
947   struct saved_scope *s;
948   
949   /* Clear out ID.  */
950   memset (&id, 0, sizeof (id));
951
952   /* Don't allow recursion into FN.  */
953   VARRAY_TREE_INIT (id.fns, 32, "fns");
954   VARRAY_PUSH_TREE (id.fns, fn);
955   /* Or any functions that aren't finished yet.  */
956   prev_fn = NULL_TREE;
957   if (current_function_decl)
958     {
959       VARRAY_PUSH_TREE (id.fns, current_function_decl);
960       prev_fn = current_function_decl;
961     }
962   for (s = scope_chain; s; s = s->prev)
963     if (s->function_decl && s->function_decl != prev_fn)
964       {
965         VARRAY_PUSH_TREE (id.fns, s->function_decl);
966         prev_fn = s->function_decl;
967       }
968   
969   /* Create the stack of TARGET_EXPRs.  */
970   VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs");
971
972   /* Create the list of functions this call will inline.  */
973   VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns");
974
975   /* Keep track of the low-water mark, i.e., the point where the first
976      real inlining is represented in ID.FNS.  */
977   id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns);
978
979   /* Replace all calls to inline functions with the bodies of those
980      functions.  */
981   id.tree_pruner = htab_create (37, htab_hash_pointer,
982                                 htab_eq_pointer, NULL);
983   expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
984
985   /* Clean up.  */
986   htab_delete (id.tree_pruner);
987   VARRAY_FREE (id.fns);
988   VARRAY_FREE (id.target_exprs);
989   if (DECL_LANG_SPECIFIC (fn))
990     {
991       tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns));
992       
993       memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0),
994               VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree));
995       DECL_INLINED_FNS (fn) = ifn;
996     }
997   VARRAY_FREE (id.inlined_fns);
998   
999   dump_function (TDI_inlined, fn);
1000 }
1001
1002 /* Optimize the body of FN. */
1003
1004 void
1005 optimize_function (fn)
1006      tree fn;
1007 {
1008   dump_function (TDI_original, fn);
1009
1010   /* While in this function, we may choose to go off and compile
1011      another function.  For example, we might instantiate a function
1012      in the hopes of inlining it.  Normally, that wouldn't trigger any
1013      actual RTL code-generation -- but it will if the template is
1014      actually needed.  (For example, if it's address is taken, or if
1015      some other function already refers to the template.)  If
1016      code-generation occurs, then garbage collection will occur, so we
1017      must protect ourselves, just as we do while building up the body
1018      of the function.  */
1019   ++function_depth;
1020
1021   if (flag_inline_trees
1022       /* We do not inline thunks, as (a) the backend tries to optimize
1023          the call to the thunkee, (b) tree based inlining breaks that
1024          optimization, (c) virtual functions are rarely inlineable,
1025          and (d) ASM_OUTPUT_MI_THUNK is there to DTRT anyway.  */
1026       && !DECL_THUNK_P (fn))
1027     optimize_inline_calls (fn);
1028   
1029   /* Undo the call to ggc_push_context above.  */
1030   --function_depth;
1031   
1032   dump_function (TDI_optimized, fn);
1033 }
1034
1035 /* Called from calls_setjmp_p via walk_tree.  */
1036
1037 static tree
1038 calls_setjmp_r (tp, walk_subtrees, data)
1039      tree *tp;
1040      int *walk_subtrees ATTRIBUTE_UNUSED;
1041      void *data ATTRIBUTE_UNUSED;
1042 {
1043   /* We're only interested in FUNCTION_DECLS.  */
1044   if (TREE_CODE (*tp) != FUNCTION_DECL)
1045     return NULL_TREE;
1046
1047   return setjmp_call_p (*tp) ? *tp : NULL_TREE;
1048 }
1049
1050 /* Returns non-zero if FN calls `setjmp' or some other function that
1051    can return more than once.  This function is conservative; it may
1052    occasionally return a non-zero value even when FN does not actually
1053    call `setjmp'.  */
1054
1055 int
1056 calls_setjmp_p (fn)
1057      tree fn;
1058 {
1059   return walk_tree_without_duplicates (&DECL_SAVED_TREE (fn),
1060                                        calls_setjmp_r,
1061                                        NULL) != NULL_TREE;
1062 }
1063
1064 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor
1065    or destructor.  Update it to ensure that the source-position for
1066    the cloned parameter matches that for the original, and that the
1067    debugging generation code will be able to find the original PARM.  */
1068
1069 static void
1070 update_cloned_parm (parm, cloned_parm)
1071      tree parm;
1072      tree cloned_parm;
1073 {
1074   DECL_ABSTRACT_ORIGIN (cloned_parm) = parm;
1075
1076   /* We may have taken its address. */
1077   TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm);
1078
1079   /* The definition might have different constness. */
1080   TREE_READONLY (cloned_parm) = TREE_READONLY (parm);
1081   
1082   TREE_USED (cloned_parm) = TREE_USED (parm);
1083   
1084   /* The name may have changed from the declaration. */
1085   DECL_NAME (cloned_parm) = DECL_NAME (parm);
1086   DECL_SOURCE_FILE (cloned_parm) = DECL_SOURCE_FILE (parm);
1087   DECL_SOURCE_LINE (cloned_parm) = DECL_SOURCE_LINE (parm);
1088 }
1089
1090 /* FN is a function that has a complete body.  Clone the body as
1091    necessary.  Returns non-zero if there's no longer any need to
1092    process the main body.  */
1093
1094 int
1095 maybe_clone_body (fn)
1096      tree fn;
1097 {
1098   inline_data id;
1099   tree clone;
1100   int first = 1;
1101
1102   /* We only clone constructors and destructors.  */
1103   if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn)
1104       && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn))
1105     return 0;
1106
1107   /* Emit the DWARF1 abstract instance.  */
1108   (*debug_hooks->deferred_inline_function) (fn);
1109
1110   /* We know that any clones immediately follow FN in the TYPE_METHODS
1111      list.  */
1112   for (clone = TREE_CHAIN (fn);
1113        clone && DECL_CLONED_FUNCTION_P (clone);
1114        clone = TREE_CHAIN (clone), first = 0)
1115     {
1116       tree parm;
1117       tree clone_parm;
1118       int parmno;
1119
1120       /* Update CLONE's source position information to match FN's.  */
1121       DECL_SOURCE_FILE (clone) = DECL_SOURCE_FILE (fn);
1122       DECL_SOURCE_LINE (clone) = DECL_SOURCE_LINE (fn);
1123       DECL_INLINE (clone) = DECL_INLINE (fn);
1124       DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
1125       DECL_COMDAT (clone) = DECL_COMDAT (fn);
1126       DECL_WEAK (clone) = DECL_WEAK (fn);
1127       DECL_ONE_ONLY (clone) = DECL_ONE_ONLY (fn);
1128       DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn);
1129       DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn);
1130       DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn);
1131       DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn);
1132       DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn);
1133       TREE_PUBLIC (clone) = TREE_PUBLIC (fn);
1134
1135       /* Adjust the parameter names and locations. */
1136       parm = DECL_ARGUMENTS (fn);
1137       clone_parm = DECL_ARGUMENTS (clone);
1138       /* Update the `this' parameter, which is always first.
1139          Sometimes, we end update the `this' parameter twice because
1140          we process it again in the loop below.  That is harmless.  */
1141       update_cloned_parm (parm, clone_parm);
1142       if (DECL_HAS_IN_CHARGE_PARM_P (fn))
1143         parm = TREE_CHAIN (parm);
1144       if (DECL_HAS_VTT_PARM_P (fn))
1145         parm = TREE_CHAIN (parm);
1146       if (DECL_HAS_VTT_PARM_P (clone))
1147         clone_parm = TREE_CHAIN (clone_parm);
1148       for (; parm;
1149            parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm))
1150         {
1151           /* Update this paramter.  */
1152           update_cloned_parm (parm, clone_parm);
1153           /* We should only give unused information for one clone. */
1154           if (!first)
1155             TREE_USED (clone_parm) = 1;
1156         }
1157
1158       /* Start processing the function.  */
1159       push_to_top_level ();
1160       start_function (NULL_TREE, clone, NULL_TREE, SF_PRE_PARSED);
1161
1162       /* Just clone the body, as if we were making an inline call.
1163          But, remap the parameters in the callee to the parameters of
1164          caller.  If there's an in-charge parameter, map it to an
1165          appropriate constant.  */
1166       memset (&id, 0, sizeof (id));
1167       VARRAY_TREE_INIT (id.fns, 2, "fns");
1168       VARRAY_PUSH_TREE (id.fns, clone);
1169       VARRAY_PUSH_TREE (id.fns, fn);
1170
1171       /* Cloning is treated slightly differently from inlining.  Set
1172          CLONING_P so that its clear which operation we're performing.  */
1173       id.cloning_p = true;
1174
1175       /* Remap the parameters.  */
1176       id.decl_map = splay_tree_new (splay_tree_compare_pointers,
1177                                     NULL, NULL);
1178       for (parmno = 0,
1179              parm = DECL_ARGUMENTS (fn),
1180              clone_parm = DECL_ARGUMENTS (clone);
1181            parm;
1182            ++parmno,
1183              parm = TREE_CHAIN (parm))
1184         {
1185           /* Map the in-charge parameter to an appropriate constant.  */
1186           if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1)
1187             {
1188               tree in_charge;
1189               in_charge = in_charge_arg_for_name (DECL_NAME (clone));
1190               splay_tree_insert (id.decl_map,
1191                                  (splay_tree_key) parm,
1192                                  (splay_tree_value) in_charge);
1193             }
1194           else if (DECL_ARTIFICIAL (parm)
1195                    && DECL_NAME (parm) == vtt_parm_identifier)
1196             {
1197               /* For a subobject constructor or destructor, the next
1198                  argument is the VTT parameter.  Remap the VTT_PARM
1199                  from the CLONE to this parameter.  */
1200               if (DECL_HAS_VTT_PARM_P (clone))
1201                 {
1202                   DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
1203                   splay_tree_insert (id.decl_map,
1204                                      (splay_tree_key) parm,
1205                                      (splay_tree_value) clone_parm);
1206                   clone_parm = TREE_CHAIN (clone_parm);
1207                 }
1208               /* Otherwise, map the VTT parameter to `NULL'.  */
1209               else
1210                 {
1211                   splay_tree_insert (id.decl_map,
1212                                      (splay_tree_key) parm,
1213                                      (splay_tree_value) null_pointer_node);
1214                 }
1215             }
1216           /* Map other parameters to their equivalents in the cloned
1217              function.  */
1218           else
1219             {
1220               splay_tree_insert (id.decl_map,
1221                                  (splay_tree_key) parm,
1222                                  (splay_tree_value) clone_parm);
1223               clone_parm = TREE_CHAIN (clone_parm);
1224             }
1225         }
1226
1227       /* Actually copy the body.  */
1228       TREE_CHAIN (DECL_SAVED_TREE (clone)) = copy_body (&id);
1229
1230       /* There are as many statements in the clone as in the
1231          original.  */
1232       DECL_NUM_STMTS (clone) = DECL_NUM_STMTS (fn);
1233
1234       /* Clean up.  */
1235       splay_tree_delete (id.decl_map);
1236       VARRAY_FREE (id.fns);
1237
1238       /* Now, expand this function into RTL, if appropriate.  */
1239       finish_function (0);
1240       BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn);
1241       expand_body (clone);
1242       pop_from_top_level ();
1243     }
1244
1245   /* We don't need to process the original function any further.  */
1246   return 1;
1247 }
1248
1249 /* Dump FUNCTION_DECL FN as tree dump PHASE. */
1250
1251 static void
1252 dump_function (phase, fn)
1253      enum tree_dump_index phase;
1254      tree fn;
1255 {
1256   FILE *stream;
1257   int flags;
1258
1259   stream = dump_begin (phase, &flags);
1260   if (stream)
1261     {
1262       fprintf (stream, "\n;; Function %s",
1263                decl_as_string (fn, TFF_DECL_SPECIFIERS));
1264       fprintf (stream, " (%s)\n",
1265                decl_as_string (DECL_ASSEMBLER_NAME (fn), 0));
1266       fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
1267       fprintf (stream, "\n");
1268       
1269       dump_node (fn, TDF_SLIM | flags, stream);
1270       dump_end (phase, stream);
1271     }
1272 }