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