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