|
|
1.1 root 1: /* Procedure integration for GNU CC.
2: Copyright (C) 1988, 1991, 1993 Free Software Foundation, Inc.
3: Contributed by Michael Tiemann ([email protected])
4:
5: This file is part of GNU CC.
6:
7: GNU CC is free software; you can redistribute it and/or modify
8: it 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,
13: but WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: GNU 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
19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20:
21:
22: #include <stdio.h>
23:
24: #include "config.h"
25: #include "rtl.h"
26: #include "tree.h"
27: #include "flags.h"
28: #include "insn-config.h"
29: #include "insn-flags.h"
30: #include "expr.h"
31: #include "output.h"
32: #include "integrate.h"
33: #include "real.h"
34: #include "function.h"
35: #include "bytecode.h"
36:
37: #include "obstack.h"
38: #define obstack_chunk_alloc xmalloc
39: #define obstack_chunk_free free
40:
41: extern struct obstack *function_maybepermanent_obstack;
42:
43: extern tree pushdecl ();
44: extern tree poplevel ();
45:
46: /* Similar, but round to the next highest integer that meets the
47: alignment. */
48: #define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
49:
50: /* Default max number of insns a function can have and still be inline.
51: This is overridden on RISC machines. */
52: #ifndef INTEGRATE_THRESHOLD
53: #define INTEGRATE_THRESHOLD(DECL) \
54: (8 * (8 + list_length (DECL_ARGUMENTS (DECL))))
55: #endif
56:
57: /* Save any constant pool constants in an insn. */
58: static void save_constants ();
59:
60: /* Note when parameter registers are the destination of a SET. */
61: static void note_modified_parmregs ();
62:
63: /* Copy an rtx for save_for_inline_copying. */
64: static rtx copy_for_inline ();
65:
66: /* Make copies of MEMs in DECL_RTLs. */
67: static void copy_decl_rtls ();
68:
69: static tree copy_decl_tree ();
70: static tree copy_decl_list ();
71:
72: static void integrate_parm_decls ();
73: static void integrate_decl_tree ();
74:
75: static void subst_constants ();
76:
77: /* Zero if the current function (whose FUNCTION_DECL is FNDECL)
78: is safe and reasonable to integrate into other functions.
79: Nonzero means value is a warning message with a single %s
80: for the function's name. */
81:
82: char *
83: function_cannot_inline_p (fndecl)
84: register tree fndecl;
85: {
86: register rtx insn;
87: tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
88: int max_insns = INTEGRATE_THRESHOLD (fndecl);
89: register int ninsns = 0;
90: register tree parms;
91:
92: /* No inlines with varargs. `grokdeclarator' gives a warning
93: message about that if `inline' is specified. This code
94: it put in to catch the volunteers. */
95: if ((last && TREE_VALUE (last) != void_type_node)
96: || (DECL_ARGUMENTS (fndecl) && DECL_NAME (DECL_ARGUMENTS (fndecl))
97: && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (DECL_ARGUMENTS (fndecl))),
98: "__builtin_va_alist")))
99: return "varargs function cannot be inline";
100:
101: if (current_function_calls_alloca)
102: return "function using alloca cannot be inline";
103:
104: if (current_function_contains_functions)
105: return "function with nested functions cannot be inline";
106:
107: /* If its not even close, don't even look. */
108: if (!DECL_INLINE (fndecl) && get_max_uid () > 3 * max_insns)
109: return "function too large to be inline";
110:
111: #if 0
112: /* Large stacks are OK now that inlined functions can share them. */
113: /* Don't inline functions with large stack usage,
114: since they can make other recursive functions burn up stack. */
115: if (!DECL_INLINE (fndecl) && get_frame_size () > 100)
116: return "function stack frame for inlining";
117: #endif
118:
119: #if 0
120: /* Don't inline functions which do not specify a function prototype and
121: have BLKmode argument or take the address of a parameter. */
122: for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
123: {
124: if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
125: TREE_ADDRESSABLE (parms) = 1;
126: if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
127: return "no prototype, and parameter address used; cannot be inline";
128: }
129: #endif
130:
131: /* We can't inline functions that return structures
132: the old-fashioned PCC way, copying into a static block. */
133: if (current_function_returns_pcc_struct)
134: return "inline functions not supported for this return value type";
135:
136: /* We can't inline functions that return structures of varying size. */
137: if (int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
138: return "function with varying-size return value cannot be inline";
139:
140: /* Cannot inline a function with a varying size argument. */
141: for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
142: if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
143: return "function with varying-size parameter cannot be inline";
144:
145: if (!DECL_INLINE (fndecl) && get_max_uid () > max_insns)
146: {
147: for (ninsns = 0, insn = get_first_nonparm_insn (); insn && ninsns < max_insns;
148: insn = NEXT_INSN (insn))
149: {
150: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
151: ninsns++;
152: }
153:
154: if (ninsns >= max_insns)
155: return "function too large to be inline";
156: }
157:
158: /* We cannot inline this function if forced_labels is non-zero. This
159: implies that a label in this function was used as an initializer.
160: Because labels can not be duplicated, all labels in the function
161: will be renamed when it is inlined. However, there is no way to find
162: and fix all variables initialized with addresses of labels in this
163: function, hence inlining is impossible. */
164:
165: if (forced_labels)
166: return "function with label addresses used in initializers cannot inline";
167:
168: /* We cannot inline a nested function that jumps to a nonlocal label. */
169: if (current_function_has_nonlocal_goto)
170: return "function with nonlocal goto cannot be inline";
171:
172: return 0;
173: }
174:
175: /* Variables used within save_for_inline. */
176:
177: /* Mapping from old pseudo-register to new pseudo-registers.
178: The first element of this map is reg_map[FIRST_PSEUDO_REGISTER].
179: It is allocated in `save_for_inline' and `expand_inline_function',
180: and deallocated on exit from each of those routines. */
181: static rtx *reg_map;
182:
183: /* Mapping from old code-labels to new code-labels.
184: The first element of this map is label_map[min_labelno].
185: It is allocated in `save_for_inline' and `expand_inline_function',
186: and deallocated on exit from each of those routines. */
187: static rtx *label_map;
188:
189: /* Mapping from old insn uid's to copied insns.
190: It is allocated in `save_for_inline' and `expand_inline_function',
191: and deallocated on exit from each of those routines. */
192: static rtx *insn_map;
193:
194: /* Map pseudo reg number into the PARM_DECL for the parm living in the reg.
195: Zero for a reg that isn't a parm's home.
196: Only reg numbers less than max_parm_reg are mapped here. */
197: static tree *parmdecl_map;
198:
199: /* Keep track of first pseudo-register beyond those that are parms. */
200: static int max_parm_reg;
201:
202: /* When an insn is being copied by copy_for_inline,
203: this is nonzero if we have copied an ASM_OPERANDS.
204: In that case, it is the original input-operand vector. */
205: static rtvec orig_asm_operands_vector;
206:
207: /* When an insn is being copied by copy_for_inline,
208: this is nonzero if we have copied an ASM_OPERANDS.
209: In that case, it is the copied input-operand vector. */
210: static rtvec copy_asm_operands_vector;
211:
212: /* Likewise, this is the copied constraints vector. */
213: static rtvec copy_asm_constraints_vector;
214:
215: /* In save_for_inline, nonzero if past the parm-initialization insns. */
216: static int in_nonparm_insns;
217:
218: /* Subroutine for `save_for_inline{copying,nocopy}'. Performs initialization
219: needed to save FNDECL's insns and info for future inline expansion. */
220:
221: static rtx
222: initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy)
223: tree fndecl;
224: int min_labelno;
225: int max_labelno;
226: int max_reg;
227: int copy;
228: {
229: int function_flags, i;
230: rtvec arg_vector;
231: tree parms;
232:
233: /* Compute the values of any flags we must restore when inlining this. */
234:
235: function_flags
236: = (current_function_calls_alloca * FUNCTION_FLAGS_CALLS_ALLOCA
237: + current_function_calls_setjmp * FUNCTION_FLAGS_CALLS_SETJMP
238: + current_function_calls_longjmp * FUNCTION_FLAGS_CALLS_LONGJMP
239: + current_function_returns_struct * FUNCTION_FLAGS_RETURNS_STRUCT
240: + current_function_returns_pcc_struct * FUNCTION_FLAGS_RETURNS_PCC_STRUCT
241: + current_function_needs_context * FUNCTION_FLAGS_NEEDS_CONTEXT
242: + current_function_has_nonlocal_label * FUNCTION_FLAGS_HAS_NONLOCAL_LABEL
243: + current_function_returns_pointer * FUNCTION_FLAGS_RETURNS_POINTER
244: + current_function_uses_const_pool * FUNCTION_FLAGS_USES_CONST_POOL
245: + current_function_uses_pic_offset_table * FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE);
246:
247: /* Clear out PARMDECL_MAP. It was allocated in the caller's frame. */
248: bzero (parmdecl_map, max_parm_reg * sizeof (tree));
249: arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
250:
251: for (parms = DECL_ARGUMENTS (fndecl), i = 0;
252: parms;
253: parms = TREE_CHAIN (parms), i++)
254: {
255: rtx p = DECL_RTL (parms);
256:
257: if (GET_CODE (p) == MEM && copy)
258: {
259: /* Copy the rtl so that modifications of the addresses
260: later in compilation won't affect this arg_vector.
261: Virtual register instantiation can screw the address
262: of the rtl. */
263: rtx new = copy_rtx (p);
264:
265: /* Don't leave the old copy anywhere in this decl. */
266: if (DECL_RTL (parms) == DECL_INCOMING_RTL (parms)
267: || (GET_CODE (DECL_RTL (parms)) == MEM
268: && GET_CODE (DECL_INCOMING_RTL (parms)) == MEM
269: && (XEXP (DECL_RTL (parms), 0)
270: == XEXP (DECL_INCOMING_RTL (parms), 0))))
271: DECL_INCOMING_RTL (parms) = new;
272: DECL_RTL (parms) = new;
273: }
274:
275: RTVEC_ELT (arg_vector, i) = p;
276:
277: if (GET_CODE (p) == REG)
278: parmdecl_map[REGNO (p)] = parms;
279: else if (GET_CODE (p) == CONCAT)
280: {
281: rtx preal = gen_realpart (GET_MODE (XEXP (p, 0)), p);
282: rtx pimag = gen_imagpart (GET_MODE (preal), p);
283:
284: if (GET_CODE (preal) == REG)
285: parmdecl_map[REGNO (preal)] = parms;
286: if (GET_CODE (pimag) == REG)
287: parmdecl_map[REGNO (pimag)] = parms;
288: }
289:
290: /* This flag is cleared later
291: if the function ever modifies the value of the parm. */
292: TREE_READONLY (parms) = 1;
293: }
294:
295: /* Assume we start out in the insns that set up the parameters. */
296: in_nonparm_insns = 0;
297:
298: /* The list of DECL_SAVED_INSNS, starts off with a header which
299: contains the following information:
300:
301: the first insn of the function (not including the insns that copy
302: parameters into registers).
303: the first parameter insn of the function,
304: the first label used by that function,
305: the last label used by that function,
306: the highest register number used for parameters,
307: the total number of registers used,
308: the size of the incoming stack area for parameters,
309: the number of bytes popped on return,
310: the stack slot list,
311: some flags that are used to restore compiler globals,
312: the value of current_function_outgoing_args_size,
313: the original argument vector,
314: and the original DECL_INITIAL. */
315:
316: return gen_inline_header_rtx (NULL_RTX, NULL_RTX, min_labelno, max_labelno,
317: max_parm_reg, max_reg,
318: current_function_args_size,
319: current_function_pops_args,
320: stack_slot_list, function_flags,
321: current_function_outgoing_args_size,
322: arg_vector, (rtx) DECL_INITIAL (fndecl));
323: }
324:
325: /* Subroutine for `save_for_inline{copying,nocopy}'. Finishes up the
326: things that must be done to make FNDECL expandable as an inline function.
327: HEAD contains the chain of insns to which FNDECL will expand. */
328:
329: static void
330: finish_inline (fndecl, head)
331: tree fndecl;
332: rtx head;
333: {
334: NEXT_INSN (head) = get_first_nonparm_insn ();
335: FIRST_PARM_INSN (head) = get_insns ();
336: DECL_SAVED_INSNS (fndecl) = head;
337: DECL_FRAME_SIZE (fndecl) = get_frame_size ();
338: DECL_INLINE (fndecl) = 1;
339: }
340:
341: /* Adjust the BLOCK_END_NOTE pointers in a given copied DECL tree so that
342: they all point to the new (copied) rtxs. */
343:
344: static void
345: adjust_copied_decl_tree (block)
346: register tree block;
347: {
348: register tree subblock;
349: register rtx original_end;
350:
351: original_end = BLOCK_END_NOTE (block);
352: if (original_end)
353: {
354: BLOCK_END_NOTE (block) = (rtx) NOTE_SOURCE_FILE (original_end);
355: NOTE_SOURCE_FILE (original_end) = 0;
356: }
357:
358: /* Process all subblocks. */
359: for (subblock = BLOCK_SUBBLOCKS (block);
360: subblock;
361: subblock = TREE_CHAIN (subblock))
362: adjust_copied_decl_tree (subblock);
363: }
364:
365: /* Make the insns and PARM_DECLs of the current function permanent
366: and record other information in DECL_SAVED_INSNS to allow inlining
367: of this function in subsequent calls.
368:
369: This function is called when we are going to immediately compile
370: the insns for FNDECL. The insns in maybepermanent_obstack cannot be
371: modified by the compilation process, so we copy all of them to
372: new storage and consider the new insns to be the insn chain to be
373: compiled. Our caller (rest_of_compilation) saves the original
374: DECL_INITIAL and DECL_ARGUMENTS; here we copy them. */
375:
376: void
377: save_for_inline_copying (fndecl)
378: tree fndecl;
379: {
380: rtx first_insn, last_insn, insn;
381: rtx head, copy;
382: int max_labelno, min_labelno, i, len;
383: int max_reg;
384: int max_uid;
385: rtx first_nonparm_insn;
386:
387: /* Make and emit a return-label if we have not already done so.
388: Do this before recording the bounds on label numbers. */
389:
390: if (return_label == 0)
391: {
392: return_label = gen_label_rtx ();
393: emit_label (return_label);
394: }
395:
396: /* Get some bounds on the labels and registers used. */
397:
398: max_labelno = max_label_num ();
399: min_labelno = get_first_label_num ();
400: max_reg = max_reg_num ();
401:
402: /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
403: Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
404: Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
405: for the parms, prior to elimination of virtual registers.
406: These values are needed for substituting parms properly. */
407:
408: max_parm_reg = max_parm_reg_num ();
409: parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree));
410:
411: head = initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, 1);
412:
413: if (current_function_uses_const_pool)
414: {
415: /* Replace any constant pool references with the actual constant. We
416: will put the constants back in the copy made below. */
417: for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
418: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
419: {
420: save_constants (&PATTERN (insn));
421: if (REG_NOTES (insn))
422: save_constants (®_NOTES (insn));
423: }
424:
425: /* Clear out the constant pool so that we can recreate it with the
426: copied constants below. */
427: init_const_rtx_hash_table ();
428: clear_const_double_mem ();
429: }
430:
431: max_uid = INSN_UID (head);
432:
433: /* We have now allocated all that needs to be allocated permanently
434: on the rtx obstack. Set our high-water mark, so that we
435: can free the rest of this when the time comes. */
436:
437: preserve_data ();
438:
439: /* Copy the chain insns of this function.
440: Install the copied chain as the insns of this function,
441: for continued compilation;
442: the original chain is recorded as the DECL_SAVED_INSNS
443: for inlining future calls. */
444:
445: /* If there are insns that copy parms from the stack into pseudo registers,
446: those insns are not copied. `expand_inline_function' must
447: emit the correct code to handle such things. */
448:
449: insn = get_insns ();
450: if (GET_CODE (insn) != NOTE)
451: abort ();
452: first_insn = rtx_alloc (NOTE);
453: NOTE_SOURCE_FILE (first_insn) = NOTE_SOURCE_FILE (insn);
454: NOTE_LINE_NUMBER (first_insn) = NOTE_LINE_NUMBER (insn);
455: INSN_UID (first_insn) = INSN_UID (insn);
456: PREV_INSN (first_insn) = NULL;
457: NEXT_INSN (first_insn) = NULL;
458: last_insn = first_insn;
459:
460: /* Each pseudo-reg in the old insn chain must have a unique rtx in the copy.
461: Make these new rtx's now, and install them in regno_reg_rtx, so they
462: will be the official pseudo-reg rtx's for the rest of compilation. */
463:
464: reg_map = (rtx *) alloca ((max_reg + 1) * sizeof (rtx));
465:
466: len = sizeof (struct rtx_def) + (GET_RTX_LENGTH (REG) - 1) * sizeof (rtunion);
467: for (i = max_reg - 1; i > LAST_VIRTUAL_REGISTER; i--)
468: reg_map[i] = (rtx)obstack_copy (function_maybepermanent_obstack,
469: regno_reg_rtx[i], len);
470:
471: bcopy (reg_map + LAST_VIRTUAL_REGISTER + 1,
472: regno_reg_rtx + LAST_VIRTUAL_REGISTER + 1,
473: (max_reg - (LAST_VIRTUAL_REGISTER + 1)) * sizeof (rtx));
474:
475: /* Likewise each label rtx must have a unique rtx as its copy. */
476:
477: label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
478: label_map -= min_labelno;
479:
480: for (i = min_labelno; i < max_labelno; i++)
481: label_map[i] = gen_label_rtx ();
482:
483: /* Record the mapping of old insns to copied insns. */
484:
485: insn_map = (rtx *) alloca (max_uid * sizeof (rtx));
486: bzero (insn_map, max_uid * sizeof (rtx));
487:
488: /* Get the insn which signals the end of parameter setup code. */
489: first_nonparm_insn = get_first_nonparm_insn ();
490:
491: /* Copy any entries in regno_reg_rtx or DECL_RTLs that reference MEM
492: (the former occurs when a variable has its address taken)
493: since these may be shared and can be changed by virtual
494: register instantiation. DECL_RTL values for our arguments
495: have already been copied by initialize_for_inline. */
496: for (i = LAST_VIRTUAL_REGISTER + 1; i < max_reg; i++)
497: if (GET_CODE (regno_reg_rtx[i]) == MEM)
498: XEXP (regno_reg_rtx[i], 0)
499: = copy_for_inline (XEXP (regno_reg_rtx[i], 0));
500:
501: /* Copy the tree of subblocks of the function, and the decls in them.
502: We will use the copy for compiling this function, then restore the original
503: subblocks and decls for use when inlining this function.
504:
505: Several parts of the compiler modify BLOCK trees. In particular,
506: instantiate_virtual_regs will instantiate any virtual regs
507: mentioned in the DECL_RTLs of the decls, and loop
508: unrolling will replicate any BLOCK trees inside an unrolled loop.
509:
510: The modified subblocks or DECL_RTLs would be incorrect for the original rtl
511: which we will use for inlining. The rtl might even contain pseudoregs
512: whose space has been freed. */
513:
514: DECL_INITIAL (fndecl) = copy_decl_tree (DECL_INITIAL (fndecl));
515: DECL_ARGUMENTS (fndecl) = copy_decl_list (DECL_ARGUMENTS (fndecl));
516:
517: /* Now copy each DECL_RTL which is a MEM,
518: so it is safe to modify their addresses. */
519: copy_decl_rtls (DECL_INITIAL (fndecl));
520:
521: /* The fndecl node acts as its own progenitor, so mark it as such. */
522: DECL_ABSTRACT_ORIGIN (fndecl) = fndecl;
523:
524: /* Now copy the chain of insns. Do this twice. The first copy the insn
525: itself and its body. The second time copy of REG_NOTES. This is because
526: a REG_NOTE may have a forward pointer to another insn. */
527:
528: for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
529: {
530: orig_asm_operands_vector = 0;
531:
532: if (insn == first_nonparm_insn)
533: in_nonparm_insns = 1;
534:
535: switch (GET_CODE (insn))
536: {
537: case NOTE:
538: /* No need to keep these. */
539: if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
540: continue;
541:
542: copy = rtx_alloc (NOTE);
543: NOTE_LINE_NUMBER (copy) = NOTE_LINE_NUMBER (insn);
544: if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END)
545: NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
546: else
547: {
548: NOTE_SOURCE_FILE (insn) = (char *) copy;
549: NOTE_SOURCE_FILE (copy) = 0;
550: }
551: break;
552:
553: case INSN:
554: case CALL_INSN:
555: case JUMP_INSN:
556: copy = rtx_alloc (GET_CODE (insn));
557: PATTERN (copy) = copy_for_inline (PATTERN (insn));
558: INSN_CODE (copy) = -1;
559: LOG_LINKS (copy) = NULL;
560: RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
561: break;
562:
563: case CODE_LABEL:
564: copy = label_map[CODE_LABEL_NUMBER (insn)];
565: LABEL_NAME (copy) = LABEL_NAME (insn);
566: break;
567:
568: case BARRIER:
569: copy = rtx_alloc (BARRIER);
570: break;
571:
572: default:
573: abort ();
574: }
575: INSN_UID (copy) = INSN_UID (insn);
576: insn_map[INSN_UID (insn)] = copy;
577: NEXT_INSN (last_insn) = copy;
578: PREV_INSN (copy) = last_insn;
579: last_insn = copy;
580: }
581:
582: adjust_copied_decl_tree (DECL_INITIAL (fndecl));
583:
584: /* Now copy the REG_NOTES. */
585: for (insn = NEXT_INSN (get_insns ()); insn; insn = NEXT_INSN (insn))
586: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
587: && insn_map[INSN_UID(insn)])
588: REG_NOTES (insn_map[INSN_UID (insn)])
589: = copy_for_inline (REG_NOTES (insn));
590:
591: NEXT_INSN (last_insn) = NULL;
592:
593: finish_inline (fndecl, head);
594:
595: set_new_first_and_last_insn (first_insn, last_insn);
596: }
597:
598: /* Return a copy of a chain of nodes, chained through the TREE_CHAIN field.
599: For example, this can copy a list made of TREE_LIST nodes. While copying,
600: for each node copied which doesn't already have is DECL_ABSTRACT_ORIGIN
601: set to some non-zero value, set the DECL_ABSTRACT_ORIGIN of the copy to
602: point to the corresponding (abstract) original node. */
603:
604: static tree
605: copy_decl_list (list)
606: tree list;
607: {
608: tree head;
609: register tree prev, next;
610:
611: if (list == 0)
612: return 0;
613:
614: head = prev = copy_node (list);
615: if (DECL_ABSTRACT_ORIGIN (head) == NULL_TREE)
616: DECL_ABSTRACT_ORIGIN (head) = list;
617: next = TREE_CHAIN (list);
618: while (next)
619: {
620: register tree copy;
621:
622: copy = copy_node (next);
623: if (DECL_ABSTRACT_ORIGIN (copy) == NULL_TREE)
624: DECL_ABSTRACT_ORIGIN (copy) = next;
625: TREE_CHAIN (prev) = copy;
626: prev = copy;
627: next = TREE_CHAIN (next);
628: }
629: return head;
630: }
631:
632: /* Make a copy of the entire tree of blocks BLOCK, and return it. */
633:
634: static tree
635: copy_decl_tree (block)
636: tree block;
637: {
638: tree t, vars, subblocks;
639:
640: vars = copy_decl_list (BLOCK_VARS (block));
641: subblocks = 0;
642:
643: /* Process all subblocks. */
644: for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
645: {
646: tree copy = copy_decl_tree (t);
647: TREE_CHAIN (copy) = subblocks;
648: subblocks = copy;
649: }
650:
651: t = copy_node (block);
652: BLOCK_VARS (t) = vars;
653: BLOCK_SUBBLOCKS (t) = nreverse (subblocks);
654: /* If the BLOCK being cloned is already marked as having been instantiated
655: from something else, then leave that `origin' marking alone. Elsewise,
656: mark the clone as having originated from the BLOCK we are cloning. */
657: if (BLOCK_ABSTRACT_ORIGIN (t) == NULL_TREE)
658: BLOCK_ABSTRACT_ORIGIN (t) = block;
659: return t;
660: }
661:
662: /* Copy DECL_RTLs in all decls in the given BLOCK node. */
663:
664: static void
665: copy_decl_rtls (block)
666: tree block;
667: {
668: tree t;
669:
670: for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
671: if (DECL_RTL (t) && GET_CODE (DECL_RTL (t)) == MEM)
672: DECL_RTL (t) = copy_for_inline (DECL_RTL (t));
673:
674: /* Process all subblocks. */
675: for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
676: copy_decl_rtls (t);
677: }
678:
679: /* Make the insns and PARM_DECLs of the current function permanent
680: and record other information in DECL_SAVED_INSNS to allow inlining
681: of this function in subsequent calls.
682:
683: This routine need not copy any insns because we are not going
684: to immediately compile the insns in the insn chain. There
685: are two cases when we would compile the insns for FNDECL:
686: (1) when FNDECL is expanded inline, and (2) when FNDECL needs to
687: be output at the end of other compilation, because somebody took
688: its address. In the first case, the insns of FNDECL are copied
689: as it is expanded inline, so FNDECL's saved insns are not
690: modified. In the second case, FNDECL is used for the last time,
691: so modifying the rtl is not a problem.
692:
693: ??? Actually, we do not verify that FNDECL is not inline expanded
694: by other functions which must also be written down at the end
695: of compilation. We could set flag_no_inline to nonzero when
696: the time comes to write down such functions. */
697:
698: void
699: save_for_inline_nocopy (fndecl)
700: tree fndecl;
701: {
702: rtx insn;
703: rtx head, copy;
704: tree parms;
705: int max_labelno, min_labelno, i, len;
706: int max_reg;
707: int max_uid;
708: rtx first_nonparm_insn;
709: int function_flags;
710:
711: /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
712: Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
713: Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
714: for the parms, prior to elimination of virtual registers.
715: These values are needed for substituting parms properly. */
716:
717: max_parm_reg = max_parm_reg_num ();
718: parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree));
719:
720: /* Make and emit a return-label if we have not already done so. */
721:
722: if (return_label == 0)
723: {
724: return_label = gen_label_rtx ();
725: emit_label (return_label);
726: }
727:
728: head = initialize_for_inline (fndecl, get_first_label_num (),
729: max_label_num (), max_reg_num (), 0);
730:
731: /* If there are insns that copy parms from the stack into pseudo registers,
732: those insns are not copied. `expand_inline_function' must
733: emit the correct code to handle such things. */
734:
735: insn = get_insns ();
736: if (GET_CODE (insn) != NOTE)
737: abort ();
738:
739: /* Get the insn which signals the end of parameter setup code. */
740: first_nonparm_insn = get_first_nonparm_insn ();
741:
742: /* Now just scan the chain of insns to see what happens to our
743: PARM_DECLs. If a PARM_DECL is used but never modified, we
744: can substitute its rtl directly when expanding inline (and
745: perform constant folding when its incoming value is constant).
746: Otherwise, we have to copy its value into a new register and track
747: the new register's life. */
748:
749: for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
750: {
751: if (insn == first_nonparm_insn)
752: in_nonparm_insns = 1;
753:
754: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
755: {
756: if (current_function_uses_const_pool)
757: {
758: /* Replace any constant pool references with the actual constant.
759: We will put the constant back if we need to write the
760: function out after all. */
761: save_constants (&PATTERN (insn));
762: if (REG_NOTES (insn))
763: save_constants (®_NOTES (insn));
764: }
765:
766: /* Record what interesting things happen to our parameters. */
767: note_stores (PATTERN (insn), note_modified_parmregs);
768: }
769: }
770:
771: /* We have now allocated all that needs to be allocated permanently
772: on the rtx obstack. Set our high-water mark, so that we
773: can free the rest of this when the time comes. */
774:
775: preserve_data ();
776:
777: finish_inline (fndecl, head);
778: }
779:
780: /* Given PX, a pointer into an insn, search for references to the constant
781: pool. Replace each with a CONST that has the mode of the original
782: constant, contains the constant, and has RTX_INTEGRATED_P set.
783: Similarly, constant pool addresses not enclosed in a MEM are replaced
784: with an ADDRESS rtx which also gives the constant, mode, and has
785: RTX_INTEGRATED_P set. */
786:
787: static void
788: save_constants (px)
789: rtx *px;
790: {
791: rtx x;
792: int i, j;
793:
794: again:
795: x = *px;
796:
797: /* If this is a CONST_DOUBLE, don't try to fix things up in
798: CONST_DOUBLE_MEM, because this is an infinite recursion. */
799: if (GET_CODE (x) == CONST_DOUBLE)
800: return;
801: else if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
802: && CONSTANT_POOL_ADDRESS_P (XEXP (x,0)))
803: {
804: enum machine_mode const_mode = get_pool_mode (XEXP (x, 0));
805: rtx new = gen_rtx (CONST, const_mode, get_pool_constant (XEXP (x, 0)));
806: RTX_INTEGRATED_P (new) = 1;
807:
808: /* If the MEM was in a different mode than the constant (perhaps we
809: were only looking at the low-order part), surround it with a
810: SUBREG so we can save both modes. */
811:
812: if (GET_MODE (x) != const_mode)
813: {
814: new = gen_rtx (SUBREG, GET_MODE (x), new, 0);
815: RTX_INTEGRATED_P (new) = 1;
816: }
817:
818: *px = new;
819: save_constants (&XEXP (*px, 0));
820: }
821: else if (GET_CODE (x) == SYMBOL_REF
822: && CONSTANT_POOL_ADDRESS_P (x))
823: {
824: *px = gen_rtx (ADDRESS, get_pool_mode (x), get_pool_constant (x));
825: save_constants (&XEXP (*px, 0));
826: RTX_INTEGRATED_P (*px) = 1;
827: }
828:
829: else
830: {
831: char *fmt = GET_RTX_FORMAT (GET_CODE (x));
832: int len = GET_RTX_LENGTH (GET_CODE (x));
833:
834: for (i = len-1; i >= 0; i--)
835: {
836: switch (fmt[i])
837: {
838: case 'E':
839: for (j = 0; j < XVECLEN (x, i); j++)
840: save_constants (&XVECEXP (x, i, j));
841: break;
842:
843: case 'e':
844: if (XEXP (x, i) == 0)
845: continue;
846: if (i == 0)
847: {
848: /* Hack tail-recursion here. */
849: px = &XEXP (x, 0);
850: goto again;
851: }
852: save_constants (&XEXP (x, i));
853: break;
854: }
855: }
856: }
857: }
858:
859: /* Note whether a parameter is modified or not. */
860:
861: static void
862: note_modified_parmregs (reg, x)
863: rtx reg;
864: rtx x;
865: {
866: if (GET_CODE (reg) == REG && in_nonparm_insns
867: && REGNO (reg) < max_parm_reg
868: && REGNO (reg) >= FIRST_PSEUDO_REGISTER
869: && parmdecl_map[REGNO (reg)] != 0)
870: TREE_READONLY (parmdecl_map[REGNO (reg)]) = 0;
871: }
872:
873: /* Copy the rtx ORIG recursively, replacing pseudo-regs and labels
874: according to `reg_map' and `label_map'. The original rtl insns
875: will be saved for inlining; this is used to make a copy
876: which is used to finish compiling the inline function itself.
877:
878: If we find a "saved" constant pool entry, one which was replaced with
879: the value of the constant, convert it back to a constant pool entry.
880: Since the pool wasn't touched, this should simply restore the old
881: address.
882:
883: All other kinds of rtx are copied except those that can never be
884: changed during compilation. */
885:
886: static rtx
887: copy_for_inline (orig)
888: rtx orig;
889: {
890: register rtx x = orig;
891: register int i;
892: register enum rtx_code code;
893: register char *format_ptr;
894:
895: if (x == 0)
896: return x;
897:
898: code = GET_CODE (x);
899:
900: /* These types may be freely shared. */
901:
902: switch (code)
903: {
904: case QUEUED:
905: case CONST_INT:
906: case SYMBOL_REF:
907: case PC:
908: case CC0:
909: return x;
910:
911: case CONST_DOUBLE:
912: /* We have to make a new CONST_DOUBLE to ensure that we account for
913: it correctly. Using the old CONST_DOUBLE_MEM data is wrong. */
914: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
915: {
916: REAL_VALUE_TYPE d;
917:
918: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
919: return immed_real_const_1 (d, GET_MODE (x));
920: }
921: else
922: return immed_double_const (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
923: VOIDmode);
924:
925: case CONST:
926: /* Get constant pool entry for constant in the pool. */
927: if (RTX_INTEGRATED_P (x))
928: return validize_mem (force_const_mem (GET_MODE (x),
929: copy_for_inline (XEXP (x, 0))));
930: break;
931:
932: case SUBREG:
933: /* Get constant pool entry, but access in different mode. */
934: if (RTX_INTEGRATED_P (x))
935: {
936: rtx new
937: = force_const_mem (GET_MODE (SUBREG_REG (x)),
938: copy_for_inline (XEXP (SUBREG_REG (x), 0)));
939:
940: PUT_MODE (new, GET_MODE (x));
941: return validize_mem (new);
942: }
943: break;
944:
945: case ADDRESS:
946: /* If not special for constant pool error. Else get constant pool
947: address. */
948: if (! RTX_INTEGRATED_P (x))
949: abort ();
950:
951: return XEXP (force_const_mem (GET_MODE (x),
952: copy_for_inline (XEXP (x, 0))), 0);
953:
954: case ASM_OPERANDS:
955: /* If a single asm insn contains multiple output operands
956: then it contains multiple ASM_OPERANDS rtx's that share operand 3.
957: We must make sure that the copied insn continues to share it. */
958: if (orig_asm_operands_vector == XVEC (orig, 3))
959: {
960: x = rtx_alloc (ASM_OPERANDS);
961: x->volatil = orig->volatil;
962: XSTR (x, 0) = XSTR (orig, 0);
963: XSTR (x, 1) = XSTR (orig, 1);
964: XINT (x, 2) = XINT (orig, 2);
965: XVEC (x, 3) = copy_asm_operands_vector;
966: XVEC (x, 4) = copy_asm_constraints_vector;
967: XSTR (x, 5) = XSTR (orig, 5);
968: XINT (x, 6) = XINT (orig, 6);
969: return x;
970: }
971: break;
972:
973: case MEM:
974: /* A MEM is usually allowed to be shared if its address is constant
975: or is a constant plus one of the special registers.
976:
977: We do not allow sharing of addresses that are either a special
978: register or the sum of a constant and a special register because
979: it is possible for unshare_all_rtl to copy the address, into memory
980: that won't be saved. Although the MEM can safely be shared, and
981: won't be copied there, the address itself cannot be shared, and may
982: need to be copied.
983:
984: There are also two exceptions with constants: The first is if the
985: constant is a LABEL_REF or the sum of the LABEL_REF
986: and an integer. This case can happen if we have an inline
987: function that supplies a constant operand to the call of another
988: inline function that uses it in a switch statement. In this case,
989: we will be replacing the LABEL_REF, so we have to replace this MEM
990: as well.
991:
992: The second case is if we have a (const (plus (address ..) ...)).
993: In that case we need to put back the address of the constant pool
994: entry. */
995:
996: if (CONSTANT_ADDRESS_P (XEXP (x, 0))
997: && GET_CODE (XEXP (x, 0)) != LABEL_REF
998: && ! (GET_CODE (XEXP (x, 0)) == CONST
999: && (GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
1000: && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
1001: == LABEL_REF)
1002: || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
1003: == ADDRESS)))))
1004: return x;
1005: break;
1006:
1007: case LABEL_REF:
1008: /* If this is a non-local label, just make a new LABEL_REF.
1009: Otherwise, use the new label as well. */
1010: x = gen_rtx (LABEL_REF, GET_MODE (orig),
1011: LABEL_REF_NONLOCAL_P (orig) ? XEXP (orig, 0)
1012: : label_map[CODE_LABEL_NUMBER (XEXP (orig, 0))]);
1013: LABEL_REF_NONLOCAL_P (x) = LABEL_REF_NONLOCAL_P (orig);
1014: LABEL_OUTSIDE_LOOP_P (x) = LABEL_OUTSIDE_LOOP_P (orig);
1015: return x;
1016:
1017: case REG:
1018: if (REGNO (x) > LAST_VIRTUAL_REGISTER)
1019: return reg_map [REGNO (x)];
1020: else
1021: return x;
1022:
1023: case SET:
1024: /* If a parm that gets modified lives in a pseudo-reg,
1025: clear its TREE_READONLY to prevent certain optimizations. */
1026: {
1027: rtx dest = SET_DEST (x);
1028:
1029: while (GET_CODE (dest) == STRICT_LOW_PART
1030: || GET_CODE (dest) == ZERO_EXTRACT
1031: || GET_CODE (dest) == SUBREG)
1032: dest = XEXP (dest, 0);
1033:
1034: if (GET_CODE (dest) == REG
1035: && REGNO (dest) < max_parm_reg
1036: && REGNO (dest) >= FIRST_PSEUDO_REGISTER
1037: && parmdecl_map[REGNO (dest)] != 0
1038: /* The insn to load an arg pseudo from a stack slot
1039: does not count as modifying it. */
1040: && in_nonparm_insns)
1041: TREE_READONLY (parmdecl_map[REGNO (dest)]) = 0;
1042: }
1043: break;
1044:
1045: #if 0 /* This is a good idea, but here is the wrong place for it. */
1046: /* Arrange that CONST_INTs always appear as the second operand
1047: if they appear, and that `frame_pointer_rtx' or `arg_pointer_rtx'
1048: always appear as the first. */
1049: case PLUS:
1050: if (GET_CODE (XEXP (x, 0)) == CONST_INT
1051: || (XEXP (x, 1) == frame_pointer_rtx
1052: || (ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
1053: && XEXP (x, 1) == arg_pointer_rtx)))
1054: {
1055: rtx t = XEXP (x, 0);
1056: XEXP (x, 0) = XEXP (x, 1);
1057: XEXP (x, 1) = t;
1058: }
1059: break;
1060: #endif
1061: }
1062:
1063: /* Replace this rtx with a copy of itself. */
1064:
1065: x = rtx_alloc (code);
1066: bcopy (orig, x, (sizeof (*x) - sizeof (x->fld)
1067: + sizeof (x->fld[0]) * GET_RTX_LENGTH (code)));
1068:
1069: /* Now scan the subexpressions recursively.
1070: We can store any replaced subexpressions directly into X
1071: since we know X is not shared! Any vectors in X
1072: must be copied if X was copied. */
1073:
1074: format_ptr = GET_RTX_FORMAT (code);
1075:
1076: for (i = 0; i < GET_RTX_LENGTH (code); i++)
1077: {
1078: switch (*format_ptr++)
1079: {
1080: case 'e':
1081: XEXP (x, i) = copy_for_inline (XEXP (x, i));
1082: break;
1083:
1084: case 'u':
1085: /* Change any references to old-insns to point to the
1086: corresponding copied insns. */
1087: XEXP (x, i) = insn_map[INSN_UID (XEXP (x, i))];
1088: break;
1089:
1090: case 'E':
1091: if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
1092: {
1093: register int j;
1094:
1095: XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0));
1096: for (j = 0; j < XVECLEN (x, i); j++)
1097: XVECEXP (x, i, j)
1098: = copy_for_inline (XVECEXP (x, i, j));
1099: }
1100: break;
1101: }
1102: }
1103:
1104: if (code == ASM_OPERANDS && orig_asm_operands_vector == 0)
1105: {
1106: orig_asm_operands_vector = XVEC (orig, 3);
1107: copy_asm_operands_vector = XVEC (x, 3);
1108: copy_asm_constraints_vector = XVEC (x, 4);
1109: }
1110:
1111: return x;
1112: }
1113:
1114: /* Unfortunately, we need a global copy of const_equiv map for communication
1115: with a function called from note_stores. Be *very* careful that this
1116: is used properly in the presence of recursion. */
1117:
1118: rtx *global_const_equiv_map;
1119: int global_const_equiv_map_size;
1120:
1121: #define FIXED_BASE_PLUS_P(X) \
1122: (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
1123: && GET_CODE (XEXP (X, 0)) == REG \
1124: && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER \
1125: && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER)
1126:
1127: /* Integrate the procedure defined by FNDECL. Note that this function
1128: may wind up calling itself. Since the static variables are not
1129: reentrant, we do not assign them until after the possibility
1130: of recursion is eliminated.
1131:
1132: If IGNORE is nonzero, do not produce a value.
1133: Otherwise store the value in TARGET if it is nonzero and that is convenient.
1134:
1135: Value is:
1136: (rtx)-1 if we could not substitute the function
1137: 0 if we substituted it and it does not produce a value
1138: else an rtx for where the value is stored. */
1139:
1140: rtx
1141: expand_inline_function (fndecl, parms, target, ignore, type, structure_value_addr)
1142: tree fndecl, parms;
1143: rtx target;
1144: int ignore;
1145: tree type;
1146: rtx structure_value_addr;
1147: {
1148: tree formal, actual, block;
1149: rtx header = DECL_SAVED_INSNS (fndecl);
1150: rtx insns = FIRST_FUNCTION_INSN (header);
1151: rtx parm_insns = FIRST_PARM_INSN (header);
1152: tree *arg_trees;
1153: rtx *arg_vals;
1154: rtx insn;
1155: int max_regno;
1156: register int i;
1157: int min_labelno = FIRST_LABELNO (header);
1158: int max_labelno = LAST_LABELNO (header);
1159: int nargs;
1160: rtx local_return_label = 0;
1161: rtx loc;
1162: rtx temp;
1163: struct inline_remap *map;
1164: rtx cc0_insn = 0;
1165: rtvec arg_vector = ORIGINAL_ARG_VECTOR (header);
1166: rtx static_chain_value = 0;
1167:
1168: /* Allow for equivalences of the pseudos we make for virtual fp and ap. */
1169: max_regno = MAX_REGNUM (header) + 3;
1170: if (max_regno < FIRST_PSEUDO_REGISTER)
1171: abort ();
1172:
1173: nargs = list_length (DECL_ARGUMENTS (fndecl));
1174:
1175: /* We expect PARMS to have the right length; don't crash if not. */
1176: if (list_length (parms) != nargs)
1177: return (rtx) (HOST_WIDE_INT) -1;
1178: /* Also check that the parms type match. Since the appropriate
1179: conversions or default promotions have already been applied,
1180: the machine modes should match exactly. */
1181: for (formal = DECL_ARGUMENTS (fndecl),
1182: actual = parms;
1183: formal;
1184: formal = TREE_CHAIN (formal),
1185: actual = TREE_CHAIN (actual))
1186: {
1187: tree arg = TREE_VALUE (actual);
1188: enum machine_mode mode = TYPE_MODE (DECL_ARG_TYPE (formal));
1189: if (mode != TYPE_MODE (TREE_TYPE (arg)))
1190: return (rtx) (HOST_WIDE_INT) -1;
1191: /* If they are block mode, the types should match exactly.
1192: They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
1193: which could happen if the parameter has incomplete type. */
1194: if (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal))
1195: return (rtx) (HOST_WIDE_INT) -1;
1196: }
1197:
1198: /* Make a binding contour to keep inline cleanups called at
1199: outer function-scope level from looking like they are shadowing
1200: parameter declarations. */
1201: pushlevel (0);
1202:
1203: /* Make a fresh binding contour that we can easily remove. */
1204: pushlevel (0);
1205: expand_start_bindings (0);
1206: if (GET_CODE (parm_insns) == NOTE
1207: && NOTE_LINE_NUMBER (parm_insns) > 0)
1208: {
1209: rtx note = emit_note (NOTE_SOURCE_FILE (parm_insns),
1210: NOTE_LINE_NUMBER (parm_insns));
1211: if (note)
1212: RTX_INTEGRATED_P (note) = 1;
1213: }
1214:
1215: /* Expand the function arguments. Do this first so that any
1216: new registers get created before we allocate the maps. */
1217:
1218: arg_vals = (rtx *) alloca (nargs * sizeof (rtx));
1219: arg_trees = (tree *) alloca (nargs * sizeof (tree));
1220:
1221: for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
1222: formal;
1223: formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual), i++)
1224: {
1225: /* Actual parameter, converted to the type of the argument within the
1226: function. */
1227: tree arg = convert (TREE_TYPE (formal), TREE_VALUE (actual));
1228: /* Mode of the variable used within the function. */
1229: enum machine_mode mode = TYPE_MODE (TREE_TYPE (formal));
1230: /* Where parameter is located in the function. */
1231: rtx copy;
1232:
1233: /* Make sure this formal has some correspondence in the users code
1234: * before emitting any line notes for it. */
1235: if (DECL_SOURCE_LINE (formal))
1236: {
1237: rtx note = emit_note (DECL_SOURCE_FILE (formal),
1238: DECL_SOURCE_LINE (formal));
1239: if (note)
1240: RTX_INTEGRATED_P (note) = 1;
1241: }
1242:
1243: arg_trees[i] = arg;
1244: loc = RTVEC_ELT (arg_vector, i);
1245:
1246: /* If this is an object passed by invisible reference, we copy the
1247: object into a stack slot and save its address. If this will go
1248: into memory, we do nothing now. Otherwise, we just expand the
1249: argument. */
1250: if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
1251: && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
1252: {
1253: rtx stack_slot
1254: = assign_stack_temp (TYPE_MODE (TREE_TYPE (arg)),
1255: int_size_in_bytes (TREE_TYPE (arg)), 1);
1256:
1257: store_expr (arg, stack_slot, 0);
1258:
1259: arg_vals[i] = XEXP (stack_slot, 0);
1260: }
1261: else if (GET_CODE (loc) != MEM)
1262: {
1263: if (GET_MODE (loc) != TYPE_MODE (TREE_TYPE (arg)))
1264: /* The mode if LOC and ARG can differ if LOC was a variable
1265: that had its mode promoted via PROMOTED_MODE. */
1266: arg_vals[i] = convert_modes (GET_MODE (loc),
1267: TYPE_MODE (TREE_TYPE (arg)),
1268: expand_expr (arg, NULL_RTX, mode,
1269: EXPAND_SUM),
1270: TREE_UNSIGNED (TREE_TYPE (formal)));
1271: else
1272: arg_vals[i] = expand_expr (arg, NULL_RTX, mode, EXPAND_SUM);
1273: }
1274: else
1275: arg_vals[i] = 0;
1276:
1277: if (arg_vals[i] != 0
1278: && (! TREE_READONLY (formal)
1279: /* If the parameter is not read-only, copy our argument through
1280: a register. Also, we cannot use ARG_VALS[I] if it overlaps
1281: TARGET in any way. In the inline function, they will likely
1282: be two different pseudos, and `safe_from_p' will make all
1283: sorts of smart assumptions about their not conflicting.
1284: But if ARG_VALS[I] overlaps TARGET, these assumptions are
1285: wrong, so put ARG_VALS[I] into a fresh register. */
1286: || (target != 0
1287: && (GET_CODE (arg_vals[i]) == REG
1288: || GET_CODE (arg_vals[i]) == SUBREG
1289: || GET_CODE (arg_vals[i]) == MEM)
1290: && reg_overlap_mentioned_p (arg_vals[i], target))
1291: /* ??? We must always copy a SUBREG into a REG, because it might
1292: get substituted into an address, and not all ports correctly
1293: handle SUBREGs in addresses. */
1294: || (GET_CODE (arg_vals[i]) == SUBREG)))
1295: arg_vals[i] = copy_to_mode_reg (GET_MODE (loc), arg_vals[i]);
1296: }
1297:
1298: /* Allocate the structures we use to remap things. */
1299:
1300: map = (struct inline_remap *) alloca (sizeof (struct inline_remap));
1301: map->fndecl = fndecl;
1302:
1303: map->reg_map = (rtx *) alloca (max_regno * sizeof (rtx));
1304: bzero (map->reg_map, max_regno * sizeof (rtx));
1305:
1306: map->label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
1307: map->label_map -= min_labelno;
1308:
1309: map->insn_map = (rtx *) alloca (INSN_UID (header) * sizeof (rtx));
1310: bzero (map->insn_map, INSN_UID (header) * sizeof (rtx));
1311: map->min_insnno = 0;
1312: map->max_insnno = INSN_UID (header);
1313:
1314: map->integrating = 1;
1315:
1316: /* const_equiv_map maps pseudos in our routine to constants, so it needs to
1317: be large enough for all our pseudos. This is the number we are currently
1318: using plus the number in the called routine, plus 15 for each arg,
1319: five to compute the virtual frame pointer, and five for the return value.
1320: This should be enough for most cases. We do not reference entries
1321: outside the range of the map.
1322:
1323: ??? These numbers are quite arbitrary and were obtained by
1324: experimentation. At some point, we should try to allocate the
1325: table after all the parameters are set up so we an more accurately
1326: estimate the number of pseudos we will need. */
1327:
1328: map->const_equiv_map_size
1329: = max_reg_num () + (max_regno - FIRST_PSEUDO_REGISTER) + 15 * nargs + 10;
1330:
1331: map->const_equiv_map
1332: = (rtx *)alloca (map->const_equiv_map_size * sizeof (rtx));
1333: bzero (map->const_equiv_map, map->const_equiv_map_size * sizeof (rtx));
1334:
1335: map->const_age_map
1336: = (unsigned *)alloca (map->const_equiv_map_size * sizeof (unsigned));
1337: bzero (map->const_age_map, map->const_equiv_map_size * sizeof (unsigned));
1338: map->const_age = 0;
1339:
1340: /* Record the current insn in case we have to set up pointers to frame
1341: and argument memory blocks. */
1342: map->insns_at_start = get_last_insn ();
1343:
1344: /* Update the outgoing argument size to allow for those in the inlined
1345: function. */
1346: if (OUTGOING_ARGS_SIZE (header) > current_function_outgoing_args_size)
1347: current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (header);
1348:
1349: /* If the inline function needs to make PIC references, that means
1350: that this function's PIC offset table must be used. */
1351: if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
1352: current_function_uses_pic_offset_table = 1;
1353:
1354: /* If this function needs a context, set it up. */
1355: if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_NEEDS_CONTEXT)
1356: static_chain_value = lookup_static_chain (fndecl);
1357:
1358: /* Process each argument. For each, set up things so that the function's
1359: reference to the argument will refer to the argument being passed.
1360: We only replace REG with REG here. Any simplifications are done
1361: via const_equiv_map.
1362:
1363: We make two passes: In the first, we deal with parameters that will
1364: be placed into registers, since we need to ensure that the allocated
1365: register number fits in const_equiv_map. Then we store all non-register
1366: parameters into their memory location. */
1367:
1368: /* Don't try to free temp stack slots here, because we may put one of the
1369: parameters into a temp stack slot. */
1370:
1371: for (i = 0; i < nargs; i++)
1372: {
1373: rtx copy = arg_vals[i];
1374:
1375: loc = RTVEC_ELT (arg_vector, i);
1376:
1377: /* There are three cases, each handled separately. */
1378: if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
1379: && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
1380: {
1381: /* This must be an object passed by invisible reference (it could
1382: also be a variable-sized object, but we forbid inlining functions
1383: with variable-sized arguments). COPY is the address of the
1384: actual value (this computation will cause it to be copied). We
1385: map that address for the register, noting the actual address as
1386: an equivalent in case it can be substituted into the insns. */
1387:
1388: if (GET_CODE (copy) != REG)
1389: {
1390: temp = copy_addr_to_reg (copy);
1391: if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
1392: && REGNO (temp) < map->const_equiv_map_size)
1393: {
1394: map->const_equiv_map[REGNO (temp)] = copy;
1395: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1396: }
1397: copy = temp;
1398: }
1399: map->reg_map[REGNO (XEXP (loc, 0))] = copy;
1400: }
1401: else if (GET_CODE (loc) == MEM)
1402: {
1403: /* This is the case of a parameter that lives in memory.
1404: It will live in the block we allocate in the called routine's
1405: frame that simulates the incoming argument area. Do nothing
1406: now; we will call store_expr later. */
1407: ;
1408: }
1409: else if (GET_CODE (loc) == REG)
1410: {
1411: /* This is the good case where the parameter is in a register.
1412: If it is read-only and our argument is a constant, set up the
1413: constant equivalence.
1414:
1415: If LOC is REG_USERVAR_P, the usual case, COPY must also have
1416: that flag set if it is a register.
1417:
1418: Also, don't allow hard registers here; they might not be valid
1419: when substituted into insns. */
1420:
1421: if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
1422: || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
1423: && ! REG_USERVAR_P (copy))
1424: || (GET_CODE (copy) == REG
1425: && REGNO (copy) < FIRST_PSEUDO_REGISTER))
1426: {
1427: temp = copy_to_mode_reg (GET_MODE (loc), copy);
1428: REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
1429: if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
1430: && REGNO (temp) < map->const_equiv_map_size)
1431: {
1432: map->const_equiv_map[REGNO (temp)] = copy;
1433: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1434: }
1435: copy = temp;
1436: }
1437: map->reg_map[REGNO (loc)] = copy;
1438: }
1439: else if (GET_CODE (loc) == CONCAT)
1440: {
1441: /* This is the good case where the parameter is in a
1442: pair of separate pseudos.
1443: If it is read-only and our argument is a constant, set up the
1444: constant equivalence.
1445:
1446: If LOC is REG_USERVAR_P, the usual case, COPY must also have
1447: that flag set if it is a register.
1448:
1449: Also, don't allow hard registers here; they might not be valid
1450: when substituted into insns. */
1451: rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
1452: rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
1453: rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
1454: rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
1455:
1456: if ((GET_CODE (copyreal) != REG && GET_CODE (copyreal) != SUBREG)
1457: || (GET_CODE (copyreal) == REG && REG_USERVAR_P (locreal)
1458: && ! REG_USERVAR_P (copyreal))
1459: || (GET_CODE (copyreal) == REG
1460: && REGNO (copyreal) < FIRST_PSEUDO_REGISTER))
1461: {
1462: temp = copy_to_mode_reg (GET_MODE (locreal), copyreal);
1463: REG_USERVAR_P (temp) = REG_USERVAR_P (locreal);
1464: if ((CONSTANT_P (copyreal) || FIXED_BASE_PLUS_P (copyreal))
1465: && REGNO (temp) < map->const_equiv_map_size)
1466: {
1467: map->const_equiv_map[REGNO (temp)] = copyreal;
1468: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1469: }
1470: copyreal = temp;
1471: }
1472: map->reg_map[REGNO (locreal)] = copyreal;
1473:
1474: if ((GET_CODE (copyimag) != REG && GET_CODE (copyimag) != SUBREG)
1475: || (GET_CODE (copyimag) == REG && REG_USERVAR_P (locimag)
1476: && ! REG_USERVAR_P (copyimag))
1477: || (GET_CODE (copyimag) == REG
1478: && REGNO (copyimag) < FIRST_PSEUDO_REGISTER))
1479: {
1480: temp = copy_to_mode_reg (GET_MODE (locimag), copyimag);
1481: REG_USERVAR_P (temp) = REG_USERVAR_P (locimag);
1482: if ((CONSTANT_P (copyimag) || FIXED_BASE_PLUS_P (copyimag))
1483: && REGNO (temp) < map->const_equiv_map_size)
1484: {
1485: map->const_equiv_map[REGNO (temp)] = copyimag;
1486: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1487: }
1488: copyimag = temp;
1489: }
1490: map->reg_map[REGNO (locimag)] = copyimag;
1491: }
1492: else
1493: abort ();
1494: }
1495:
1496: /* Now do the parameters that will be placed in memory. */
1497:
1498: for (formal = DECL_ARGUMENTS (fndecl), i = 0;
1499: formal; formal = TREE_CHAIN (formal), i++)
1500: {
1501: rtx copy = arg_vals[i];
1502:
1503: loc = RTVEC_ELT (arg_vector, i);
1504:
1505: if (GET_CODE (loc) == MEM
1506: /* Exclude case handled above. */
1507: && ! (GET_CODE (XEXP (loc, 0)) == REG
1508: && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
1509: {
1510: rtx note = emit_note (DECL_SOURCE_FILE (formal),
1511: DECL_SOURCE_LINE (formal));
1512: if (note)
1513: RTX_INTEGRATED_P (note) = 1;
1514:
1515: /* Compute the address in the area we reserved and store the
1516: value there. */
1517: temp = copy_rtx_and_substitute (loc, map);
1518: subst_constants (&temp, NULL_RTX, map);
1519: apply_change_group ();
1520: if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
1521: temp = change_address (temp, VOIDmode, XEXP (temp, 0));
1522: store_expr (arg_trees[i], temp, 0);
1523: }
1524: }
1525:
1526: /* Deal with the places that the function puts its result.
1527: We are driven by what is placed into DECL_RESULT.
1528:
1529: Initially, we assume that we don't have anything special handling for
1530: REG_FUNCTION_RETURN_VALUE_P. */
1531:
1532: map->inline_target = 0;
1533: loc = DECL_RTL (DECL_RESULT (fndecl));
1534: if (TYPE_MODE (type) == VOIDmode)
1535: /* There is no return value to worry about. */
1536: ;
1537: else if (GET_CODE (loc) == MEM)
1538: {
1539: if (! structure_value_addr || ! aggregate_value_p (DECL_RESULT (fndecl)))
1540: abort ();
1541:
1542: /* Pass the function the address in which to return a structure value.
1543: Note that a constructor can cause someone to call us with
1544: STRUCTURE_VALUE_ADDR, but the initialization takes place
1545: via the first parameter, rather than the struct return address.
1546:
1547: We have two cases: If the address is a simple register indirect,
1548: use the mapping mechanism to point that register to our structure
1549: return address. Otherwise, store the structure return value into
1550: the place that it will be referenced from. */
1551:
1552: if (GET_CODE (XEXP (loc, 0)) == REG)
1553: {
1554: temp = force_reg (Pmode, structure_value_addr);
1555: map->reg_map[REGNO (XEXP (loc, 0))] = temp;
1556: if ((CONSTANT_P (structure_value_addr)
1557: || (GET_CODE (structure_value_addr) == PLUS
1558: && XEXP (structure_value_addr, 0) == virtual_stack_vars_rtx
1559: && GET_CODE (XEXP (structure_value_addr, 1)) == CONST_INT))
1560: && REGNO (temp) < map->const_equiv_map_size)
1561: {
1562: map->const_equiv_map[REGNO (temp)] = structure_value_addr;
1563: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1564: }
1565: }
1566: else
1567: {
1568: temp = copy_rtx_and_substitute (loc, map);
1569: subst_constants (&temp, NULL_RTX, map);
1570: apply_change_group ();
1571: emit_move_insn (temp, structure_value_addr);
1572: }
1573: }
1574: else if (ignore)
1575: /* We will ignore the result value, so don't look at its structure.
1576: Note that preparations for an aggregate return value
1577: do need to be made (above) even if it will be ignored. */
1578: ;
1579: else if (GET_CODE (loc) == REG)
1580: {
1581: /* The function returns an object in a register and we use the return
1582: value. Set up our target for remapping. */
1583:
1584: /* Machine mode function was declared to return. */
1585: enum machine_mode departing_mode = TYPE_MODE (type);
1586: /* (Possibly wider) machine mode it actually computes
1587: (for the sake of callers that fail to declare it right). */
1588: enum machine_mode arriving_mode
1589: = TYPE_MODE (TREE_TYPE (DECL_RESULT (fndecl)));
1590: rtx reg_to_map;
1591:
1592: /* Don't use MEMs as direct targets because on some machines
1593: substituting a MEM for a REG makes invalid insns.
1594: Let the combiner substitute the MEM if that is valid. */
1595: if (target == 0 || GET_CODE (target) != REG
1596: || GET_MODE (target) != departing_mode)
1597: target = gen_reg_rtx (departing_mode);
1598:
1599: /* If function's value was promoted before return,
1600: avoid machine mode mismatch when we substitute INLINE_TARGET.
1601: But TARGET is what we will return to the caller. */
1602: if (arriving_mode != departing_mode)
1603: reg_to_map = gen_rtx (SUBREG, arriving_mode, target, 0);
1604: else
1605: reg_to_map = target;
1606:
1607: /* Usually, the result value is the machine's return register.
1608: Sometimes it may be a pseudo. Handle both cases. */
1609: if (REG_FUNCTION_VALUE_P (loc))
1610: map->inline_target = reg_to_map;
1611: else
1612: map->reg_map[REGNO (loc)] = reg_to_map;
1613: }
1614:
1615: /* Make new label equivalences for the labels in the called function. */
1616: for (i = min_labelno; i < max_labelno; i++)
1617: map->label_map[i] = gen_label_rtx ();
1618:
1619: /* Perform postincrements before actually calling the function. */
1620: emit_queue ();
1621:
1622: /* Clean up stack so that variables might have smaller offsets. */
1623: do_pending_stack_adjust ();
1624:
1625: /* Save a copy of the location of const_equiv_map for mark_stores, called
1626: via note_stores. */
1627: global_const_equiv_map = map->const_equiv_map;
1628: global_const_equiv_map_size = map->const_equiv_map_size;
1629:
1630: /* Now copy the insns one by one. Do this in two passes, first the insns and
1631: then their REG_NOTES, just like save_for_inline. */
1632:
1633: /* This loop is very similar to the loop in copy_loop_body in unroll.c. */
1634:
1635: for (insn = insns; insn; insn = NEXT_INSN (insn))
1636: {
1637: rtx copy, pattern;
1638:
1639: map->orig_asm_operands_vector = 0;
1640:
1641: switch (GET_CODE (insn))
1642: {
1643: case INSN:
1644: pattern = PATTERN (insn);
1645: copy = 0;
1646: if (GET_CODE (pattern) == USE
1647: && GET_CODE (XEXP (pattern, 0)) == REG
1648: && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
1649: /* The (USE (REG n)) at return from the function should
1650: be ignored since we are changing (REG n) into
1651: inline_target. */
1652: break;
1653:
1654: /* Ignore setting a function value that we don't want to use. */
1655: if (map->inline_target == 0
1656: && GET_CODE (pattern) == SET
1657: && GET_CODE (SET_DEST (pattern)) == REG
1658: && REG_FUNCTION_VALUE_P (SET_DEST (pattern)))
1659: {
1660: if (volatile_refs_p (SET_SRC (pattern)))
1661: {
1662: /* If we must not delete the source,
1663: load it into a new temporary. */
1664: copy = emit_insn (copy_rtx_and_substitute (pattern, map));
1665: SET_DEST (PATTERN (copy))
1666: = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (copy))));
1667: }
1668: else
1669: break;
1670: }
1671: /* If this is setting the static chain pseudo, set it from
1672: the value we want to give it instead. */
1673: else if (static_chain_value != 0
1674: && GET_CODE (pattern) == SET
1675: && rtx_equal_p (SET_SRC (pattern),
1676: static_chain_incoming_rtx))
1677: {
1678: rtx newdest = copy_rtx_and_substitute (SET_DEST (pattern), map);
1679:
1680: copy = emit_insn (gen_rtx (SET, VOIDmode, newdest,
1681: static_chain_value));
1682:
1683: static_chain_value = 0;
1684: }
1685: else
1686: copy = emit_insn (copy_rtx_and_substitute (pattern, map));
1687: /* REG_NOTES will be copied later. */
1688:
1689: #ifdef HAVE_cc0
1690: /* If this insn is setting CC0, it may need to look at
1691: the insn that uses CC0 to see what type of insn it is.
1692: In that case, the call to recog via validate_change will
1693: fail. So don't substitute constants here. Instead,
1694: do it when we emit the following insn.
1695:
1696: For example, see the pyr.md file. That machine has signed and
1697: unsigned compares. The compare patterns must check the
1698: following branch insn to see which what kind of compare to
1699: emit.
1700:
1701: If the previous insn set CC0, substitute constants on it as
1702: well. */
1703: if (sets_cc0_p (PATTERN (copy)) != 0)
1704: cc0_insn = copy;
1705: else
1706: {
1707: if (cc0_insn)
1708: try_constants (cc0_insn, map);
1709: cc0_insn = 0;
1710: try_constants (copy, map);
1711: }
1712: #else
1713: try_constants (copy, map);
1714: #endif
1715: break;
1716:
1717: case JUMP_INSN:
1718: if (GET_CODE (PATTERN (insn)) == RETURN)
1719: {
1720: if (local_return_label == 0)
1721: local_return_label = gen_label_rtx ();
1722: pattern = gen_jump (local_return_label);
1723: }
1724: else
1725: pattern = copy_rtx_and_substitute (PATTERN (insn), map);
1726:
1727: copy = emit_jump_insn (pattern);
1728:
1729: #ifdef HAVE_cc0
1730: if (cc0_insn)
1731: try_constants (cc0_insn, map);
1732: cc0_insn = 0;
1733: #endif
1734: try_constants (copy, map);
1735:
1736: /* If this used to be a conditional jump insn but whose branch
1737: direction is now know, we must do something special. */
1738: if (condjump_p (insn) && ! simplejump_p (insn) && map->last_pc_value)
1739: {
1740: #ifdef HAVE_cc0
1741: /* The previous insn set cc0 for us. So delete it. */
1742: delete_insn (PREV_INSN (copy));
1743: #endif
1744:
1745: /* If this is now a no-op, delete it. */
1746: if (map->last_pc_value == pc_rtx)
1747: {
1748: delete_insn (copy);
1749: copy = 0;
1750: }
1751: else
1752: /* Otherwise, this is unconditional jump so we must put a
1753: BARRIER after it. We could do some dead code elimination
1754: here, but jump.c will do it just as well. */
1755: emit_barrier ();
1756: }
1757: break;
1758:
1759: case CALL_INSN:
1760: pattern = copy_rtx_and_substitute (PATTERN (insn), map);
1761: copy = emit_call_insn (pattern);
1762:
1763: #ifdef HAVE_cc0
1764: if (cc0_insn)
1765: try_constants (cc0_insn, map);
1766: cc0_insn = 0;
1767: #endif
1768: try_constants (copy, map);
1769:
1770: /* Be lazy and assume CALL_INSNs clobber all hard registers. */
1771: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1772: map->const_equiv_map[i] = 0;
1773: break;
1774:
1775: case CODE_LABEL:
1776: copy = emit_label (map->label_map[CODE_LABEL_NUMBER (insn)]);
1777: LABEL_NAME (copy) = LABEL_NAME (insn);
1778: map->const_age++;
1779: break;
1780:
1781: case BARRIER:
1782: copy = emit_barrier ();
1783: break;
1784:
1785: case NOTE:
1786: /* It is important to discard function-end and function-beg notes,
1787: so we have only one of each in the current function.
1788: Also, NOTE_INSN_DELETED notes aren't useful (save_for_inline
1789: deleted these in the copy used for continuing compilation,
1790: not the copy used for inlining). */
1791: if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
1792: && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
1793: && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
1794: copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
1795: else
1796: copy = 0;
1797: break;
1798:
1799: default:
1800: abort ();
1801: break;
1802: }
1803:
1804: if (copy)
1805: RTX_INTEGRATED_P (copy) = 1;
1806:
1807: map->insn_map[INSN_UID (insn)] = copy;
1808: }
1809:
1810: /* Now copy the REG_NOTES. Increment const_age, so that only constants
1811: from parameters can be substituted in. These are the only ones that
1812: are valid across the entire function. */
1813: map->const_age++;
1814: for (insn = insns; insn; insn = NEXT_INSN (insn))
1815: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
1816: && map->insn_map[INSN_UID (insn)]
1817: && REG_NOTES (insn))
1818: {
1819: rtx tem = copy_rtx_and_substitute (REG_NOTES (insn), map);
1820: /* We must also do subst_constants, in case one of our parameters
1821: has const type and constant value. */
1822: subst_constants (&tem, NULL_RTX, map);
1823: apply_change_group ();
1824: REG_NOTES (map->insn_map[INSN_UID (insn)]) = tem;
1825: }
1826:
1827: if (local_return_label)
1828: emit_label (local_return_label);
1829:
1830: /* Make copies of the decls of the symbols in the inline function, so that
1831: the copies of the variables get declared in the current function. Set
1832: up things so that lookup_static_chain knows that to interpret registers
1833: in SAVE_EXPRs for TYPE_SIZEs as local. */
1834:
1835: inline_function_decl = fndecl;
1836: integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
1837: integrate_decl_tree ((tree) ORIGINAL_DECL_INITIAL (header), 0, map);
1838: inline_function_decl = 0;
1839:
1840: /* End the scope containing the copied formal parameter variables
1841: and copied LABEL_DECLs. */
1842:
1843: expand_end_bindings (getdecls (), 1, 1);
1844: block = poplevel (1, 1, 0);
1845: BLOCK_ABSTRACT_ORIGIN (block) = (DECL_ABSTRACT_ORIGIN (fndecl) == NULL
1846: ? fndecl : DECL_ABSTRACT_ORIGIN (fndecl));
1847: poplevel (0, 0, 0);
1848: emit_line_note (input_filename, lineno);
1849:
1850: if (structure_value_addr)
1851: {
1852: target = gen_rtx (MEM, TYPE_MODE (type),
1853: memory_address (TYPE_MODE (type), structure_value_addr));
1854: MEM_IN_STRUCT_P (target) = 1;
1855: }
1856: return target;
1857: }
1858:
1859: /* Given a chain of PARM_DECLs, ARGS, copy each decl into a VAR_DECL,
1860: push all of those decls and give each one the corresponding home. */
1861:
1862: static void
1863: integrate_parm_decls (args, map, arg_vector)
1864: tree args;
1865: struct inline_remap *map;
1866: rtvec arg_vector;
1867: {
1868: register tree tail;
1869: register int i;
1870:
1871: for (tail = args, i = 0; tail; tail = TREE_CHAIN (tail), i++)
1872: {
1873: register tree decl = build_decl (VAR_DECL, DECL_NAME (tail),
1874: TREE_TYPE (tail));
1875: rtx new_decl_rtl
1876: = copy_rtx_and_substitute (RTVEC_ELT (arg_vector, i), map);
1877:
1878: DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (tail);
1879: /* We really should be setting DECL_INCOMING_RTL to something reasonable
1880: here, but that's going to require some more work. */
1881: /* DECL_INCOMING_RTL (decl) = ?; */
1882: /* These args would always appear unused, if not for this. */
1883: TREE_USED (decl) = 1;
1884: /* Prevent warning for shadowing with these. */
1885: DECL_ABSTRACT_ORIGIN (decl) = tail;
1886: pushdecl (decl);
1887: /* Fully instantiate the address with the equivalent form so that the
1888: debugging information contains the actual register, instead of the
1889: virtual register. Do this by not passing an insn to
1890: subst_constants. */
1891: subst_constants (&new_decl_rtl, NULL_RTX, map);
1892: apply_change_group ();
1893: DECL_RTL (decl) = new_decl_rtl;
1894: }
1895: }
1896:
1897: /* Given a BLOCK node LET, push decls and levels so as to construct in the
1898: current function a tree of contexts isomorphic to the one that is given.
1899:
1900: LEVEL indicates how far down into the BLOCK tree is the node we are
1901: currently traversing. It is always zero except for recursive calls.
1902:
1903: MAP, if nonzero, is a pointer to an inline_remap map which indicates how
1904: registers used in the DECL_RTL field should be remapped. If it is zero,
1905: no mapping is necessary. */
1906:
1907: static void
1908: integrate_decl_tree (let, level, map)
1909: tree let;
1910: int level;
1911: struct inline_remap *map;
1912: {
1913: tree t, node;
1914:
1915: if (level > 0)
1916: pushlevel (0);
1917:
1918: for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
1919: {
1920: tree d = build_decl (TREE_CODE (t), DECL_NAME (t), TREE_TYPE (t));
1921: DECL_SOURCE_LINE (d) = DECL_SOURCE_LINE (t);
1922: DECL_SOURCE_FILE (d) = DECL_SOURCE_FILE (t);
1923: if (DECL_RTL (t) != 0)
1924: {
1925: DECL_RTL (d) = copy_rtx_and_substitute (DECL_RTL (t), map);
1926: /* Fully instantiate the address with the equivalent form so that the
1927: debugging information contains the actual register, instead of the
1928: virtual register. Do this by not passing an insn to
1929: subst_constants. */
1930: subst_constants (&DECL_RTL (d), NULL_RTX, map);
1931: apply_change_group ();
1932: }
1933: else if (DECL_RTL (t))
1934: DECL_RTL (d) = copy_rtx (DECL_RTL (t));
1935: DECL_EXTERNAL (d) = DECL_EXTERNAL (t);
1936: TREE_STATIC (d) = TREE_STATIC (t);
1937: TREE_PUBLIC (d) = TREE_PUBLIC (t);
1938: TREE_CONSTANT (d) = TREE_CONSTANT (t);
1939: TREE_ADDRESSABLE (d) = TREE_ADDRESSABLE (t);
1940: TREE_READONLY (d) = TREE_READONLY (t);
1941: TREE_SIDE_EFFECTS (d) = TREE_SIDE_EFFECTS (t);
1942: /* These args would always appear unused, if not for this. */
1943: TREE_USED (d) = 1;
1944: /* Prevent warning for shadowing with these. */
1945: DECL_ABSTRACT_ORIGIN (d) = t;
1946: pushdecl (d);
1947: }
1948:
1949: for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
1950: integrate_decl_tree (t, level + 1, map);
1951:
1952: if (level > 0)
1953: {
1954: node = poplevel (1, 0, 0);
1955: if (node)
1956: {
1957: TREE_USED (node) = TREE_USED (let);
1958: BLOCK_ABSTRACT_ORIGIN (node) = let;
1959: }
1960: }
1961: }
1962:
1963: /* Create a new copy of an rtx.
1964: Recursively copies the operands of the rtx,
1965: except for those few rtx codes that are sharable.
1966:
1967: We always return an rtx that is similar to that incoming rtx, with the
1968: exception of possibly changing a REG to a SUBREG or vice versa. No
1969: rtl is ever emitted.
1970:
1971: Handle constants that need to be placed in the constant pool by
1972: calling `force_const_mem'. */
1973:
1974: rtx
1975: copy_rtx_and_substitute (orig, map)
1976: register rtx orig;
1977: struct inline_remap *map;
1978: {
1979: register rtx copy, temp;
1980: register int i, j;
1981: register RTX_CODE code;
1982: register enum machine_mode mode;
1983: register char *format_ptr;
1984: int regno;
1985:
1986: if (orig == 0)
1987: return 0;
1988:
1989: code = GET_CODE (orig);
1990: mode = GET_MODE (orig);
1991:
1992: switch (code)
1993: {
1994: case REG:
1995: /* If the stack pointer register shows up, it must be part of
1996: stack-adjustments (*not* because we eliminated the frame pointer!).
1997: Small hard registers are returned as-is. Pseudo-registers
1998: go through their `reg_map'. */
1999: regno = REGNO (orig);
2000: if (regno <= LAST_VIRTUAL_REGISTER)
2001: {
2002: /* Some hard registers are also mapped,
2003: but others are not translated. */
2004: if (map->reg_map[regno] != 0)
2005: return map->reg_map[regno];
2006:
2007: /* If this is the virtual frame pointer, make space in current
2008: function's stack frame for the stack frame of the inline function.
2009:
2010: Copy the address of this area into a pseudo. Map
2011: virtual_stack_vars_rtx to this pseudo and set up a constant
2012: equivalence for it to be the address. This will substitute the
2013: address into insns where it can be substituted and use the new
2014: pseudo where it can't. */
2015: if (regno == VIRTUAL_STACK_VARS_REGNUM)
2016: {
2017: rtx loc, seq;
2018: int size = DECL_FRAME_SIZE (map->fndecl);
2019: int rounded;
2020:
2021: start_sequence ();
2022: loc = assign_stack_temp (BLKmode, size, 1);
2023: loc = XEXP (loc, 0);
2024: #ifdef FRAME_GROWS_DOWNWARD
2025: /* In this case, virtual_stack_vars_rtx points to one byte
2026: higher than the top of the frame area. So compute the offset
2027: to one byte higher than our substitute frame.
2028: Keep the fake frame pointer aligned like a real one. */
2029: rounded = CEIL_ROUND (size, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
2030: loc = plus_constant (loc, rounded);
2031: #endif
2032: map->reg_map[regno] = temp
2033: = force_reg (Pmode, force_operand (loc, NULL_RTX));
2034:
2035: if (REGNO (temp) < map->const_equiv_map_size)
2036: {
2037: map->const_equiv_map[REGNO (temp)] = loc;
2038: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
2039: }
2040:
2041: seq = gen_sequence ();
2042: end_sequence ();
2043: emit_insn_after (seq, map->insns_at_start);
2044: return temp;
2045: }
2046: else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
2047: {
2048: /* Do the same for a block to contain any arguments referenced
2049: in memory. */
2050: rtx loc, seq;
2051: int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
2052:
2053: start_sequence ();
2054: loc = assign_stack_temp (BLKmode, size, 1);
2055: loc = XEXP (loc, 0);
2056: /* When arguments grow downward, the virtual incoming
2057: args pointer points to the top of the argument block,
2058: so the remapped location better do the same. */
2059: #ifdef ARGS_GROW_DOWNWARD
2060: loc = plus_constant (loc, size);
2061: #endif
2062: map->reg_map[regno] = temp
2063: = force_reg (Pmode, force_operand (loc, NULL_RTX));
2064:
2065: if (REGNO (temp) < map->const_equiv_map_size)
2066: {
2067: map->const_equiv_map[REGNO (temp)] = loc;
2068: map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
2069: }
2070:
2071: seq = gen_sequence ();
2072: end_sequence ();
2073: emit_insn_after (seq, map->insns_at_start);
2074: return temp;
2075: }
2076: else if (REG_FUNCTION_VALUE_P (orig))
2077: {
2078: /* This is a reference to the function return value. If
2079: the function doesn't have a return value, error. If the
2080: mode doesn't agree, make a SUBREG. */
2081: if (map->inline_target == 0)
2082: /* Must be unrolling loops or replicating code if we
2083: reach here, so return the register unchanged. */
2084: return orig;
2085: else if (mode != GET_MODE (map->inline_target))
2086: return gen_lowpart (mode, map->inline_target);
2087: else
2088: return map->inline_target;
2089: }
2090: return orig;
2091: }
2092: if (map->reg_map[regno] == NULL)
2093: {
2094: map->reg_map[regno] = gen_reg_rtx (mode);
2095: REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (orig);
2096: REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (orig);
2097: RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (orig);
2098: /* A reg with REG_FUNCTION_VALUE_P true will never reach here. */
2099: }
2100: return map->reg_map[regno];
2101:
2102: case SUBREG:
2103: copy = copy_rtx_and_substitute (SUBREG_REG (orig), map);
2104: /* SUBREG is ordinary, but don't make nested SUBREGs. */
2105: if (GET_CODE (copy) == SUBREG)
2106: return gen_rtx (SUBREG, GET_MODE (orig), SUBREG_REG (copy),
2107: SUBREG_WORD (orig) + SUBREG_WORD (copy));
2108: else if (GET_CODE (copy) == CONCAT)
2109: return (subreg_lowpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1));
2110: else
2111: return gen_rtx (SUBREG, GET_MODE (orig), copy,
2112: SUBREG_WORD (orig));
2113:
2114: case USE:
2115: case CLOBBER:
2116: /* USE and CLOBBER are ordinary, but we convert (use (subreg foo))
2117: to (use foo) if the original insn didn't have a subreg.
2118: Removing the subreg distorts the VAX movstrhi pattern
2119: by changing the mode of an operand. */
2120: copy = copy_rtx_and_substitute (XEXP (orig, 0), map);
2121: if (GET_CODE (copy) == SUBREG && GET_CODE (XEXP (orig, 0)) != SUBREG)
2122: copy = SUBREG_REG (copy);
2123: return gen_rtx (code, VOIDmode, copy);
2124:
2125: case CODE_LABEL:
2126: LABEL_PRESERVE_P (map->label_map[CODE_LABEL_NUMBER (orig)])
2127: = LABEL_PRESERVE_P (orig);
2128: return map->label_map[CODE_LABEL_NUMBER (orig)];
2129:
2130: case LABEL_REF:
2131: copy = gen_rtx (LABEL_REF, mode,
2132: LABEL_REF_NONLOCAL_P (orig) ? XEXP (orig, 0)
2133: : map->label_map[CODE_LABEL_NUMBER (XEXP (orig, 0))]);
2134: LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
2135:
2136: /* The fact that this label was previously nonlocal does not mean
2137: it still is, so we must check if it is within the range of
2138: this function's labels. */
2139: LABEL_REF_NONLOCAL_P (copy)
2140: = (LABEL_REF_NONLOCAL_P (orig)
2141: && ! (CODE_LABEL_NUMBER (XEXP (copy, 0)) >= get_first_label_num ()
2142: && CODE_LABEL_NUMBER (XEXP (copy, 0)) < max_label_num ()));
2143:
2144: /* If we have made a nonlocal label local, it means that this
2145: inlined call will be refering to our nonlocal goto handler.
2146: So make sure we create one for this block; we normally would
2147: not since this is not otherwise considered a "call". */
2148: if (LABEL_REF_NONLOCAL_P (orig) && ! LABEL_REF_NONLOCAL_P (copy))
2149: function_call_count++;
2150:
2151: return copy;
2152:
2153: case PC:
2154: case CC0:
2155: case CONST_INT:
2156: return orig;
2157:
2158: case SYMBOL_REF:
2159: /* Symbols which represent the address of a label stored in the constant
2160: pool must be modified to point to a constant pool entry for the
2161: remapped label. Otherwise, symbols are returned unchanged. */
2162: if (CONSTANT_POOL_ADDRESS_P (orig))
2163: {
2164: rtx constant = get_pool_constant (orig);
2165: if (GET_CODE (constant) == LABEL_REF)
2166: return XEXP (force_const_mem (Pmode,
2167: copy_rtx_and_substitute (constant,
2168: map)),
2169: 0);
2170: }
2171:
2172: return orig;
2173:
2174: case CONST_DOUBLE:
2175: /* We have to make a new copy of this CONST_DOUBLE because don't want
2176: to use the old value of CONST_DOUBLE_MEM. Also, this may be a
2177: duplicate of a CONST_DOUBLE we have already seen. */
2178: if (GET_MODE_CLASS (GET_MODE (orig)) == MODE_FLOAT)
2179: {
2180: REAL_VALUE_TYPE d;
2181:
2182: REAL_VALUE_FROM_CONST_DOUBLE (d, orig);
2183: return immed_real_const_1 (d, GET_MODE (orig));
2184: }
2185: else
2186: return immed_double_const (CONST_DOUBLE_LOW (orig),
2187: CONST_DOUBLE_HIGH (orig), VOIDmode);
2188:
2189: case CONST:
2190: /* Make new constant pool entry for a constant
2191: that was in the pool of the inline function. */
2192: if (RTX_INTEGRATED_P (orig))
2193: {
2194: /* If this was an address of a constant pool entry that itself
2195: had to be placed in the constant pool, it might not be a
2196: valid address. So the recursive call below might turn it
2197: into a register. In that case, it isn't a constant any
2198: more, so return it. This has the potential of changing a
2199: MEM into a REG, but we'll assume that it safe. */
2200: temp = copy_rtx_and_substitute (XEXP (orig, 0), map);
2201: if (! CONSTANT_P (temp))
2202: return temp;
2203: return validize_mem (force_const_mem (GET_MODE (orig), temp));
2204: }
2205: break;
2206:
2207: case ADDRESS:
2208: /* If from constant pool address, make new constant pool entry and
2209: return its address. */
2210: if (! RTX_INTEGRATED_P (orig))
2211: abort ();
2212:
2213: temp = force_const_mem (GET_MODE (orig),
2214: copy_rtx_and_substitute (XEXP (orig, 0), map));
2215:
2216: #if 0
2217: /* Legitimizing the address here is incorrect.
2218:
2219: The only ADDRESS rtx's that can reach here are ones created by
2220: save_constants. Hence the operand of the ADDRESS is always legal
2221: in this position of the instruction, since the original rtx without
2222: the ADDRESS was legal.
2223:
2224: The reason we don't legitimize the address here is that on the
2225: Sparc, the caller may have a (high ...) surrounding this ADDRESS.
2226: This code forces the operand of the address to a register, which
2227: fails because we can not take the HIGH part of a register.
2228:
2229: Also, change_address may create new registers. These registers
2230: will not have valid reg_map entries. This can cause try_constants()
2231: to fail because assumes that all registers in the rtx have valid
2232: reg_map entries, and it may end up replacing one of these new
2233: registers with junk. */
2234:
2235: if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
2236: temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
2237: #endif
2238:
2239: return XEXP (temp, 0);
2240:
2241: case ASM_OPERANDS:
2242: /* If a single asm insn contains multiple output operands
2243: then it contains multiple ASM_OPERANDS rtx's that share operand 3.
2244: We must make sure that the copied insn continues to share it. */
2245: if (map->orig_asm_operands_vector == XVEC (orig, 3))
2246: {
2247: copy = rtx_alloc (ASM_OPERANDS);
2248: copy->volatil = orig->volatil;
2249: XSTR (copy, 0) = XSTR (orig, 0);
2250: XSTR (copy, 1) = XSTR (orig, 1);
2251: XINT (copy, 2) = XINT (orig, 2);
2252: XVEC (copy, 3) = map->copy_asm_operands_vector;
2253: XVEC (copy, 4) = map->copy_asm_constraints_vector;
2254: XSTR (copy, 5) = XSTR (orig, 5);
2255: XINT (copy, 6) = XINT (orig, 6);
2256: return copy;
2257: }
2258: break;
2259:
2260: case CALL:
2261: /* This is given special treatment because the first
2262: operand of a CALL is a (MEM ...) which may get
2263: forced into a register for cse. This is undesirable
2264: if function-address cse isn't wanted or if we won't do cse. */
2265: #ifndef NO_FUNCTION_CSE
2266: if (! (optimize && ! flag_no_function_cse))
2267: #endif
2268: return gen_rtx (CALL, GET_MODE (orig),
2269: gen_rtx (MEM, GET_MODE (XEXP (orig, 0)),
2270: copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0), map)),
2271: copy_rtx_and_substitute (XEXP (orig, 1), map));
2272: break;
2273:
2274: #if 0
2275: /* Must be ifdefed out for loop unrolling to work. */
2276: case RETURN:
2277: abort ();
2278: #endif
2279:
2280: case SET:
2281: /* If this is setting fp or ap, it means that we have a nonlocal goto.
2282: Don't alter that.
2283: If the nonlocal goto is into the current function,
2284: this will result in unnecessarily bad code, but should work. */
2285: if (SET_DEST (orig) == virtual_stack_vars_rtx
2286: || SET_DEST (orig) == virtual_incoming_args_rtx)
2287: return gen_rtx (SET, VOIDmode, SET_DEST (orig),
2288: copy_rtx_and_substitute (SET_SRC (orig), map));
2289: break;
2290:
2291: case MEM:
2292: copy = rtx_alloc (MEM);
2293: PUT_MODE (copy, mode);
2294: XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map);
2295: MEM_IN_STRUCT_P (copy) = MEM_IN_STRUCT_P (orig);
2296: MEM_VOLATILE_P (copy) = MEM_VOLATILE_P (orig);
2297:
2298: /* If doing function inlining, this MEM might not be const in the
2299: function that it is being inlined into, and thus may not be
2300: unchanging after function inlining. Constant pool references are
2301: handled elsewhere, so this doesn't lose RTX_UNCHANGING_P bits
2302: for them. */
2303: if (! map->integrating)
2304: RTX_UNCHANGING_P (copy) = RTX_UNCHANGING_P (orig);
2305:
2306: return copy;
2307: }
2308:
2309: copy = rtx_alloc (code);
2310: PUT_MODE (copy, mode);
2311: copy->in_struct = orig->in_struct;
2312: copy->volatil = orig->volatil;
2313: copy->unchanging = orig->unchanging;
2314:
2315: format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
2316:
2317: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
2318: {
2319: switch (*format_ptr++)
2320: {
2321: case '0':
2322: break;
2323:
2324: case 'e':
2325: XEXP (copy, i) = copy_rtx_and_substitute (XEXP (orig, i), map);
2326: break;
2327:
2328: case 'u':
2329: /* Change any references to old-insns to point to the
2330: corresponding copied insns. */
2331: XEXP (copy, i) = map->insn_map[INSN_UID (XEXP (orig, i))];
2332: break;
2333:
2334: case 'E':
2335: XVEC (copy, i) = XVEC (orig, i);
2336: if (XVEC (orig, i) != NULL && XVECLEN (orig, i) != 0)
2337: {
2338: XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
2339: for (j = 0; j < XVECLEN (copy, i); j++)
2340: XVECEXP (copy, i, j)
2341: = copy_rtx_and_substitute (XVECEXP (orig, i, j), map);
2342: }
2343: break;
2344:
2345: case 'w':
2346: XWINT (copy, i) = XWINT (orig, i);
2347: break;
2348:
2349: case 'i':
2350: XINT (copy, i) = XINT (orig, i);
2351: break;
2352:
2353: case 's':
2354: XSTR (copy, i) = XSTR (orig, i);
2355: break;
2356:
2357: default:
2358: abort ();
2359: }
2360: }
2361:
2362: if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
2363: {
2364: map->orig_asm_operands_vector = XVEC (orig, 3);
2365: map->copy_asm_operands_vector = XVEC (copy, 3);
2366: map->copy_asm_constraints_vector = XVEC (copy, 4);
2367: }
2368:
2369: return copy;
2370: }
2371:
2372: /* Substitute known constant values into INSN, if that is valid. */
2373:
2374: void
2375: try_constants (insn, map)
2376: rtx insn;
2377: struct inline_remap *map;
2378: {
2379: int i;
2380:
2381: map->num_sets = 0;
2382: subst_constants (&PATTERN (insn), insn, map);
2383:
2384: /* Apply the changes if they are valid; otherwise discard them. */
2385: apply_change_group ();
2386:
2387: /* Show we don't know the value of anything stored or clobbered. */
2388: note_stores (PATTERN (insn), mark_stores);
2389: map->last_pc_value = 0;
2390: #ifdef HAVE_cc0
2391: map->last_cc0_value = 0;
2392: #endif
2393:
2394: /* Set up any constant equivalences made in this insn. */
2395: for (i = 0; i < map->num_sets; i++)
2396: {
2397: if (GET_CODE (map->equiv_sets[i].dest) == REG)
2398: {
2399: int regno = REGNO (map->equiv_sets[i].dest);
2400:
2401: if (regno < map->const_equiv_map_size
2402: && (map->const_equiv_map[regno] == 0
2403: /* Following clause is a hack to make case work where GNU C++
2404: reassigns a variable to make cse work right. */
2405: || ! rtx_equal_p (map->const_equiv_map[regno],
2406: map->equiv_sets[i].equiv)))
2407: {
2408: map->const_equiv_map[regno] = map->equiv_sets[i].equiv;
2409: map->const_age_map[regno] = map->const_age;
2410: }
2411: }
2412: else if (map->equiv_sets[i].dest == pc_rtx)
2413: map->last_pc_value = map->equiv_sets[i].equiv;
2414: #ifdef HAVE_cc0
2415: else if (map->equiv_sets[i].dest == cc0_rtx)
2416: map->last_cc0_value = map->equiv_sets[i].equiv;
2417: #endif
2418: }
2419: }
2420:
2421: /* Substitute known constants for pseudo regs in the contents of LOC,
2422: which are part of INSN.
2423: If INSN is zero, the substitution should always be done (this is used to
2424: update DECL_RTL).
2425: These changes are taken out by try_constants if the result is not valid.
2426:
2427: Note that we are more concerned with determining when the result of a SET
2428: is a constant, for further propagation, than actually inserting constants
2429: into insns; cse will do the latter task better.
2430:
2431: This function is also used to adjust address of items previously addressed
2432: via the virtual stack variable or virtual incoming arguments registers. */
2433:
2434: static void
2435: subst_constants (loc, insn, map)
2436: rtx *loc;
2437: rtx insn;
2438: struct inline_remap *map;
2439: {
2440: rtx x = *loc;
2441: register int i;
2442: register enum rtx_code code;
2443: register char *format_ptr;
2444: int num_changes = num_validated_changes ();
2445: rtx new = 0;
2446: enum machine_mode op0_mode;
2447:
2448: code = GET_CODE (x);
2449:
2450: switch (code)
2451: {
2452: case PC:
2453: case CONST_INT:
2454: case CONST_DOUBLE:
2455: case SYMBOL_REF:
2456: case CONST:
2457: case LABEL_REF:
2458: case ADDRESS:
2459: return;
2460:
2461: #ifdef HAVE_cc0
2462: case CC0:
2463: validate_change (insn, loc, map->last_cc0_value, 1);
2464: return;
2465: #endif
2466:
2467: case USE:
2468: case CLOBBER:
2469: /* The only thing we can do with a USE or CLOBBER is possibly do
2470: some substitutions in a MEM within it. */
2471: if (GET_CODE (XEXP (x, 0)) == MEM)
2472: subst_constants (&XEXP (XEXP (x, 0), 0), insn, map);
2473: return;
2474:
2475: case REG:
2476: /* Substitute for parms and known constants. Don't replace
2477: hard regs used as user variables with constants. */
2478: {
2479: int regno = REGNO (x);
2480:
2481: if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
2482: && regno < map->const_equiv_map_size
2483: && map->const_equiv_map[regno] != 0
2484: && map->const_age_map[regno] >= map->const_age)
2485: validate_change (insn, loc, map->const_equiv_map[regno], 1);
2486: return;
2487: }
2488:
2489: case SUBREG:
2490: /* SUBREG applied to something other than a reg
2491: should be treated as ordinary, since that must
2492: be a special hack and we don't know how to treat it specially.
2493: Consider for example mulsidi3 in m68k.md.
2494: Ordinary SUBREG of a REG needs this special treatment. */
2495: if (GET_CODE (SUBREG_REG (x)) == REG)
2496: {
2497: rtx inner = SUBREG_REG (x);
2498: rtx new = 0;
2499:
2500: /* We can't call subst_constants on &SUBREG_REG (x) because any
2501: constant or SUBREG wouldn't be valid inside our SUBEG. Instead,
2502: see what is inside, try to form the new SUBREG and see if that is
2503: valid. We handle two cases: extracting a full word in an
2504: integral mode and extracting the low part. */
2505: subst_constants (&inner, NULL_RTX, map);
2506:
2507: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
2508: && GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD
2509: && GET_MODE (SUBREG_REG (x)) != VOIDmode)
2510: new = operand_subword (inner, SUBREG_WORD (x), 0,
2511: GET_MODE (SUBREG_REG (x)));
2512:
2513: if (new == 0 && subreg_lowpart_p (x))
2514: new = gen_lowpart_common (GET_MODE (x), inner);
2515:
2516: if (new)
2517: validate_change (insn, loc, new, 1);
2518:
2519: return;
2520: }
2521: break;
2522:
2523: case MEM:
2524: subst_constants (&XEXP (x, 0), insn, map);
2525:
2526: /* If a memory address got spoiled, change it back. */
2527: if (insn != 0 && num_validated_changes () != num_changes
2528: && !memory_address_p (GET_MODE (x), XEXP (x, 0)))
2529: cancel_changes (num_changes);
2530: return;
2531:
2532: case SET:
2533: {
2534: /* Substitute constants in our source, and in any arguments to a
2535: complex (e..g, ZERO_EXTRACT) destination, but not in the destination
2536: itself. */
2537: rtx *dest_loc = &SET_DEST (x);
2538: rtx dest = *dest_loc;
2539: rtx src, tem;
2540:
2541: subst_constants (&SET_SRC (x), insn, map);
2542: src = SET_SRC (x);
2543:
2544: while (GET_CODE (*dest_loc) == ZERO_EXTRACT
2545: /* By convention, we always use ZERO_EXTRACT in the dest. */
2546: /* || GET_CODE (*dest_loc) == SIGN_EXTRACT */
2547: || GET_CODE (*dest_loc) == SUBREG
2548: || GET_CODE (*dest_loc) == STRICT_LOW_PART)
2549: {
2550: if (GET_CODE (*dest_loc) == ZERO_EXTRACT)
2551: {
2552: subst_constants (&XEXP (*dest_loc, 1), insn, map);
2553: subst_constants (&XEXP (*dest_loc, 2), insn, map);
2554: }
2555: dest_loc = &XEXP (*dest_loc, 0);
2556: }
2557:
2558: /* Do substitute in the address of a destination in memory. */
2559: if (GET_CODE (*dest_loc) == MEM)
2560: subst_constants (&XEXP (*dest_loc, 0), insn, map);
2561:
2562: /* Check for the case of DEST a SUBREG, both it and the underlying
2563: register are less than one word, and the SUBREG has the wider mode.
2564: In the case, we are really setting the underlying register to the
2565: source converted to the mode of DEST. So indicate that. */
2566: if (GET_CODE (dest) == SUBREG
2567: && GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD
2568: && GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) <= UNITS_PER_WORD
2569: && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
2570: <= GET_MODE_SIZE (GET_MODE (dest)))
2571: && (tem = gen_lowpart_if_possible (GET_MODE (SUBREG_REG (dest)),
2572: src)))
2573: src = tem, dest = SUBREG_REG (dest);
2574:
2575: /* If storing a recognizable value save it for later recording. */
2576: if ((map->num_sets < MAX_RECOG_OPERANDS)
2577: && (CONSTANT_P (src)
2578: || (GET_CODE (src) == PLUS
2579: && GET_CODE (XEXP (src, 0)) == REG
2580: && REGNO (XEXP (src, 0)) >= FIRST_VIRTUAL_REGISTER
2581: && REGNO (XEXP (src, 0)) <= LAST_VIRTUAL_REGISTER
2582: && CONSTANT_P (XEXP (src, 1)))
2583: || GET_CODE (src) == COMPARE
2584: #ifdef HAVE_cc0
2585: || dest == cc0_rtx
2586: #endif
2587: || (dest == pc_rtx
2588: && (src == pc_rtx || GET_CODE (src) == RETURN
2589: || GET_CODE (src) == LABEL_REF))))
2590: {
2591: /* Normally, this copy won't do anything. But, if SRC is a COMPARE
2592: it will cause us to save the COMPARE with any constants
2593: substituted, which is what we want for later. */
2594: map->equiv_sets[map->num_sets].equiv = copy_rtx (src);
2595: map->equiv_sets[map->num_sets++].dest = dest;
2596: }
2597:
2598: return;
2599: }
2600: }
2601:
2602: format_ptr = GET_RTX_FORMAT (code);
2603:
2604: /* If the first operand is an expression, save its mode for later. */
2605: if (*format_ptr == 'e')
2606: op0_mode = GET_MODE (XEXP (x, 0));
2607:
2608: for (i = 0; i < GET_RTX_LENGTH (code); i++)
2609: {
2610: switch (*format_ptr++)
2611: {
2612: case '0':
2613: break;
2614:
2615: case 'e':
2616: if (XEXP (x, i))
2617: subst_constants (&XEXP (x, i), insn, map);
2618: break;
2619:
2620: case 'u':
2621: case 'i':
2622: case 's':
2623: case 'w':
2624: break;
2625:
2626: case 'E':
2627: if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
2628: {
2629: int j;
2630: for (j = 0; j < XVECLEN (x, i); j++)
2631: subst_constants (&XVECEXP (x, i, j), insn, map);
2632: }
2633: break;
2634:
2635: default:
2636: abort ();
2637: }
2638: }
2639:
2640: /* If this is a commutative operation, move a constant to the second
2641: operand unless the second operand is already a CONST_INT. */
2642: if ((GET_RTX_CLASS (code) == 'c' || code == NE || code == EQ)
2643: && CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
2644: {
2645: rtx tem = XEXP (x, 0);
2646: validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
2647: validate_change (insn, &XEXP (x, 1), tem, 1);
2648: }
2649:
2650: /* Simplify the expression in case we put in some constants. */
2651: switch (GET_RTX_CLASS (code))
2652: {
2653: case '1':
2654: new = simplify_unary_operation (code, GET_MODE (x),
2655: XEXP (x, 0), op0_mode);
2656: break;
2657:
2658: case '<':
2659: {
2660: enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
2661: if (op_mode == VOIDmode)
2662: op_mode = GET_MODE (XEXP (x, 1));
2663: new = simplify_relational_operation (code, op_mode,
2664: XEXP (x, 0), XEXP (x, 1));
2665: #ifdef FLOAT_STORE_FLAG_VALUE
2666: if (new != 0 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
2667: new = ((new == const0_rtx) ? CONST0_RTX (GET_MODE (x))
2668: : immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, GET_MODE (x)));
2669: #endif
2670: break;
2671: }
2672:
2673: case '2':
2674: case 'c':
2675: new = simplify_binary_operation (code, GET_MODE (x),
2676: XEXP (x, 0), XEXP (x, 1));
2677: break;
2678:
2679: case 'b':
2680: case '3':
2681: new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
2682: XEXP (x, 0), XEXP (x, 1), XEXP (x, 2));
2683: break;
2684: }
2685:
2686: if (new)
2687: validate_change (insn, loc, new, 1);
2688: }
2689:
2690: /* Show that register modified no longer contain known constants. We are
2691: called from note_stores with parts of the new insn. */
2692:
2693: void
2694: mark_stores (dest, x)
2695: rtx dest;
2696: rtx x;
2697: {
2698: int regno = -1;
2699: enum machine_mode mode;
2700:
2701: /* DEST is always the innermost thing set, except in the case of
2702: SUBREGs of hard registers. */
2703:
2704: if (GET_CODE (dest) == REG)
2705: regno = REGNO (dest), mode = GET_MODE (dest);
2706: else if (GET_CODE (dest) == SUBREG && GET_CODE (SUBREG_REG (dest)) == REG)
2707: {
2708: regno = REGNO (SUBREG_REG (dest)) + SUBREG_WORD (dest);
2709: mode = GET_MODE (SUBREG_REG (dest));
2710: }
2711:
2712: if (regno >= 0)
2713: {
2714: int last_reg = (regno >= FIRST_PSEUDO_REGISTER ? regno
2715: : regno + HARD_REGNO_NREGS (regno, mode) - 1);
2716: int i;
2717:
2718: for (i = regno; i <= last_reg; i++)
2719: if (i < global_const_equiv_map_size)
2720: global_const_equiv_map[i] = 0;
2721: }
2722: }
2723:
2724: /* If any CONST expressions with RTX_INTEGRATED_P are present in the rtx
2725: pointed to by PX, they represent constants in the constant pool.
2726: Replace these with a new memory reference obtained from force_const_mem.
2727: Similarly, ADDRESS expressions with RTX_INTEGRATED_P represent the
2728: address of a constant pool entry. Replace them with the address of
2729: a new constant pool entry obtained from force_const_mem. */
2730:
2731: static void
2732: restore_constants (px)
2733: rtx *px;
2734: {
2735: rtx x = *px;
2736: int i, j;
2737: char *fmt;
2738:
2739: if (x == 0)
2740: return;
2741:
2742: if (GET_CODE (x) == CONST_DOUBLE)
2743: {
2744: /* We have to make a new CONST_DOUBLE to ensure that we account for
2745: it correctly. Using the old CONST_DOUBLE_MEM data is wrong. */
2746: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
2747: {
2748: REAL_VALUE_TYPE d;
2749:
2750: REAL_VALUE_FROM_CONST_DOUBLE (d, x);
2751: *px = immed_real_const_1 (d, GET_MODE (x));
2752: }
2753: else
2754: *px = immed_double_const (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
2755: VOIDmode);
2756: }
2757:
2758: else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == CONST)
2759: {
2760: restore_constants (&XEXP (x, 0));
2761: *px = validize_mem (force_const_mem (GET_MODE (x), XEXP (x, 0)));
2762: }
2763: else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == SUBREG)
2764: {
2765: /* This must be (subreg/i:M1 (const/i:M2 ...) 0). */
2766: rtx new = XEXP (SUBREG_REG (x), 0);
2767:
2768: restore_constants (&new);
2769: new = force_const_mem (GET_MODE (SUBREG_REG (x)), new);
2770: PUT_MODE (new, GET_MODE (x));
2771: *px = validize_mem (new);
2772: }
2773: else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == ADDRESS)
2774: {
2775: restore_constants (&XEXP (x, 0));
2776: *px = XEXP (force_const_mem (GET_MODE (x), XEXP (x, 0)), 0);
2777: }
2778: else
2779: {
2780: fmt = GET_RTX_FORMAT (GET_CODE (x));
2781: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
2782: {
2783: switch (*fmt++)
2784: {
2785: case 'E':
2786: for (j = 0; j < XVECLEN (x, i); j++)
2787: restore_constants (&XVECEXP (x, i, j));
2788: break;
2789:
2790: case 'e':
2791: restore_constants (&XEXP (x, i));
2792: break;
2793: }
2794: }
2795: }
2796: }
2797:
2798: /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
2799: given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
2800: that it points to the node itself, thus indicating that the node is its
2801: own (abstract) origin. Additionally, if the BLOCK_ABSTRACT_ORIGIN for
2802: the given node is NULL, recursively descend the decl/block tree which
2803: it is the root of, and for each other ..._DECL or BLOCK node contained
2804: therein whose DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also
2805: still NULL, set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN
2806: values to point to themselves. */
2807:
2808: static void set_decl_origin_self ();
2809:
2810: static void
2811: set_block_origin_self (stmt)
2812: register tree stmt;
2813: {
2814: if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
2815: {
2816: BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;
2817:
2818: {
2819: register tree local_decl;
2820:
2821: for (local_decl = BLOCK_VARS (stmt);
2822: local_decl != NULL_TREE;
2823: local_decl = TREE_CHAIN (local_decl))
2824: set_decl_origin_self (local_decl); /* Potential recursion. */
2825: }
2826:
2827: {
2828: register tree subblock;
2829:
2830: for (subblock = BLOCK_SUBBLOCKS (stmt);
2831: subblock != NULL_TREE;
2832: subblock = BLOCK_CHAIN (subblock))
2833: set_block_origin_self (subblock); /* Recurse. */
2834: }
2835: }
2836: }
2837:
2838: /* Given a pointer to some ..._DECL node, if the DECL_ABSTRACT_ORIGIN for
2839: the given ..._DECL node is NULL, set the DECL_ABSTRACT_ORIGIN for the
2840: node to so that it points to the node itself, thus indicating that the
2841: node represents its own (abstract) origin. Additionally, if the
2842: DECL_ABSTRACT_ORIGIN for the given node is NULL, recursively descend
2843: the decl/block tree of which the given node is the root of, and for
2844: each other ..._DECL or BLOCK node contained therein whose
2845: DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also still NULL,
2846: set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to
2847: point to themselves. */
2848:
2849: static void
2850: set_decl_origin_self (decl)
2851: register tree decl;
2852: {
2853: if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE)
2854: {
2855: DECL_ABSTRACT_ORIGIN (decl) = decl;
2856: if (TREE_CODE (decl) == FUNCTION_DECL)
2857: {
2858: register tree arg;
2859:
2860: for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
2861: DECL_ABSTRACT_ORIGIN (arg) = arg;
2862: if (DECL_INITIAL (decl) != NULL_TREE)
2863: set_block_origin_self (DECL_INITIAL (decl));
2864: }
2865: }
2866: }
2867:
2868: /* Given a pointer to some BLOCK node, and a boolean value to set the
2869: "abstract" flags to, set that value into the BLOCK_ABSTRACT flag for
2870: the given block, and for all local decls and all local sub-blocks
2871: (recursively) which are contained therein. */
2872:
2873: void set_decl_abstract_flags ();
2874:
2875: static void
2876: set_block_abstract_flags (stmt, setting)
2877: register tree stmt;
2878: register int setting;
2879: {
2880: BLOCK_ABSTRACT (stmt) = setting;
2881:
2882: {
2883: register tree local_decl;
2884:
2885: for (local_decl = BLOCK_VARS (stmt);
2886: local_decl != NULL_TREE;
2887: local_decl = TREE_CHAIN (local_decl))
2888: set_decl_abstract_flags (local_decl, setting);
2889: }
2890:
2891: {
2892: register tree subblock;
2893:
2894: for (subblock = BLOCK_SUBBLOCKS (stmt);
2895: subblock != NULL_TREE;
2896: subblock = BLOCK_CHAIN (subblock))
2897: set_block_abstract_flags (subblock, setting);
2898: }
2899: }
2900:
2901: /* Given a pointer to some ..._DECL node, and a boolean value to set the
2902: "abstract" flags to, set that value into the DECL_ABSTRACT flag for the
2903: given decl, and (in the case where the decl is a FUNCTION_DECL) also
2904: set the abstract flags for all of the parameters, local vars, local
2905: blocks and sub-blocks (recursively) to the same setting. */
2906:
2907: void
2908: set_decl_abstract_flags (decl, setting)
2909: register tree decl;
2910: register int setting;
2911: {
2912: DECL_ABSTRACT (decl) = setting;
2913: if (TREE_CODE (decl) == FUNCTION_DECL)
2914: {
2915: register tree arg;
2916:
2917: for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
2918: DECL_ABSTRACT (arg) = setting;
2919: if (DECL_INITIAL (decl) != NULL_TREE)
2920: set_block_abstract_flags (DECL_INITIAL (decl), setting);
2921: }
2922: }
2923:
2924: /* Output the assembly language code for the function FNDECL
2925: from its DECL_SAVED_INSNS. Used for inline functions that are output
2926: at end of compilation instead of where they came in the source. */
2927:
2928: void
2929: output_inline_function (fndecl)
2930: tree fndecl;
2931: {
2932: rtx head;
2933: rtx last;
2934:
2935: if (output_bytecode)
2936: {
2937: warning ("`inline' ignored for bytecode output");
2938: return;
2939: }
2940:
2941: head = DECL_SAVED_INSNS (fndecl);
2942: current_function_decl = fndecl;
2943:
2944: /* This call is only used to initialize global variables. */
2945: init_function_start (fndecl, "lossage", 1);
2946:
2947: /* Redo parameter determinations in case the FUNCTION_...
2948: macros took machine-specific actions that need to be redone. */
2949: assign_parms (fndecl, 1);
2950:
2951: /* Set stack frame size. */
2952: assign_stack_local (BLKmode, DECL_FRAME_SIZE (fndecl), 0);
2953:
2954: restore_reg_data (FIRST_PARM_INSN (head));
2955:
2956: stack_slot_list = STACK_SLOT_LIST (head);
2957:
2958: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_ALLOCA)
2959: current_function_calls_alloca = 1;
2960:
2961: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_SETJMP)
2962: current_function_calls_setjmp = 1;
2963:
2964: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_LONGJMP)
2965: current_function_calls_longjmp = 1;
2966:
2967: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_STRUCT)
2968: current_function_returns_struct = 1;
2969:
2970: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_PCC_STRUCT)
2971: current_function_returns_pcc_struct = 1;
2972:
2973: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_NEEDS_CONTEXT)
2974: current_function_needs_context = 1;
2975:
2976: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_HAS_NONLOCAL_LABEL)
2977: current_function_has_nonlocal_label = 1;
2978:
2979: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_POINTER)
2980: current_function_returns_pointer = 1;
2981:
2982: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_CONST_POOL)
2983: current_function_uses_const_pool = 1;
2984:
2985: if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
2986: current_function_uses_pic_offset_table = 1;
2987:
2988: current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (head);
2989: current_function_pops_args = POPS_ARGS (head);
2990:
2991: /* There is no need to output a return label again. */
2992: return_label = 0;
2993:
2994: expand_function_end (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_LINE (fndecl), 0);
2995:
2996: /* Find last insn and rebuild the constant pool. */
2997: for (last = FIRST_PARM_INSN (head);
2998: NEXT_INSN (last); last = NEXT_INSN (last))
2999: {
3000: if (GET_RTX_CLASS (GET_CODE (last)) == 'i')
3001: {
3002: restore_constants (&PATTERN (last));
3003: restore_constants (®_NOTES (last));
3004: }
3005: }
3006:
3007: set_new_first_and_last_insn (FIRST_PARM_INSN (head), last);
3008: set_new_first_and_last_label_num (FIRST_LABELNO (head), LAST_LABELNO (head));
3009:
3010: /* We must have already output DWARF debugging information for the
3011: original (abstract) inline function declaration/definition, so
3012: we want to make sure that the debugging information we generate
3013: for this special instance of the inline function refers back to
3014: the information we already generated. To make sure that happens,
3015: we simply have to set the DECL_ABSTRACT_ORIGIN for the function
3016: node (and for all of the local ..._DECL nodes which are its children)
3017: so that they all point to themselves. */
3018:
3019: set_decl_origin_self (fndecl);
3020:
3021: /* Compile this function all the way down to assembly code. */
3022: rest_of_compilation (fndecl);
3023:
3024: current_function_decl = 0;
3025: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.