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