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