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