1132732Skan/* Expands front end tree to back end RTL for GCC. 272564Sobrien Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3169702Skan 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 4169702Skan Free Software Foundation, Inc. 518334Speter 690091SobrienThis file is part of GCC. 718334Speter 890091SobrienGCC is free software; you can redistribute it and/or modify it under 990091Sobrienthe terms of the GNU General Public License as published by the Free 1090091SobrienSoftware Foundation; either version 2, or (at your option) any later 1190091Sobrienversion. 1218334Speter 1390091SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1490091SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1590091SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1690091Sobrienfor more details. 1718334Speter 1818334SpeterYou should have received a copy of the GNU General Public License 1990091Sobrienalong with GCC; see the file COPYING. If not, write to the Free 20169702SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 21169702Skan02110-1301, USA. */ 2218334Speter 23124160Skan/* $FreeBSD$ */ 24124160Skan 2518334Speter/* This file handles the generation of rtl code from tree structure 2618334Speter at the level of the function as a whole. 2718334Speter It creates the rtl expressions for parameters and auto variables 2818334Speter and has full responsibility for allocating stack slots. 2918334Speter 3018334Speter `expand_function_start' is called at the beginning of a function, 3118334Speter before the function body is parsed, and `expand_function_end' is 3218334Speter called after parsing the body. 3318334Speter 3418334Speter Call `assign_stack_local' to allocate a stack slot for a local variable. 3518334Speter This is usually done during the RTL generation for the function body, 3618334Speter but it can also be done in the reload pass when a pseudo-register does 37169702Skan not get a hard register. */ 3818334Speter 3918334Speter#include "config.h" 4052268Sobrien#include "system.h" 41132732Skan#include "coretypes.h" 42132732Skan#include "tm.h" 4318334Speter#include "rtl.h" 4418334Speter#include "tree.h" 4518334Speter#include "flags.h" 4652268Sobrien#include "except.h" 4718334Speter#include "function.h" 4818334Speter#include "expr.h" 49132732Skan#include "optabs.h" 5090091Sobrien#include "libfuncs.h" 5118334Speter#include "regs.h" 5218334Speter#include "hard-reg-set.h" 5318334Speter#include "insn-config.h" 5418334Speter#include "recog.h" 5518334Speter#include "output.h" 5618334Speter#include "basic-block.h" 5752268Sobrien#include "toplev.h" 58117404Skan#include "hashtab.h" 5990091Sobrien#include "ggc.h" 6090091Sobrien#include "tm_p.h" 6190091Sobrien#include "integrate.h" 62107605Sobrien#include "langhooks.h" 63132732Skan#include "target.h" 64169702Skan#include "cfglayout.h" 65169702Skan#include "tree-gimple.h" 66169702Skan#include "tree-pass.h" 67169702Skan#include "predict.h" 68169702Skan#include "vecprim.h" 6918334Speter 7052518Sobrien#ifndef LOCAL_ALIGNMENT 7152518Sobrien#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT 7252518Sobrien#endif 7352518Sobrien 74132732Skan#ifndef STACK_ALIGNMENT_NEEDED 75132732Skan#define STACK_ALIGNMENT_NEEDED 1 76132732Skan#endif 77132732Skan 78132732Skan#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT) 79132732Skan 8018334Speter/* Some systems use __main in a way incompatible with its use in gcc, in these 8118334Speter cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to 8218334Speter give the same symbol without quotes for an alternative entry point. You 8352268Sobrien must define both, or neither. */ 8418334Speter#ifndef NAME__MAIN 8518334Speter#define NAME__MAIN "__main" 8618334Speter#endif 8718334Speter 8818334Speter/* Round a value to the lowest integer less than it that is a multiple of 8918334Speter the required alignment. Avoid using division in case the value is 9018334Speter negative. Assume the alignment is a power of two. */ 9118334Speter#define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1)) 9218334Speter 9318334Speter/* Similar, but round to the next highest integer that meets the 9418334Speter alignment. */ 9518334Speter#define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1)) 9618334Speter 9752518Sobrien/* Nonzero if function being compiled doesn't contain any calls 9852518Sobrien (ignoring the prologue and epilogue). This is set prior to 9952518Sobrien local register allocation and is valid for the remaining 10090091Sobrien compiler passes. */ 10152518Sobrienint current_function_is_leaf; 10218334Speter 10352518Sobrien/* Nonzero if function being compiled doesn't modify the stack pointer 10452518Sobrien (ignoring the prologue and epilogue). This is only valid after 10590091Sobrien life_analysis has run. */ 10652518Sobrienint current_function_sp_is_unchanging; 10752518Sobrien 10852518Sobrien/* Nonzero if the function being compiled is a leaf function which only 10952518Sobrien uses leaf registers. This is valid after reload (specifically after 11052518Sobrien sched2) and is useful only if the port defines LEAF_REGISTERS. */ 11152518Sobrienint current_function_uses_only_leaf_regs; 11252518Sobrien 11390091Sobrien/* Nonzero once virtual register instantiation has been done. 11490091Sobrien assign_stack_local uses frame_pointer_rtx when this is nonzero. 11590091Sobrien calls.c:emit_library_call_value_1 uses it to set up 11690091Sobrien post-instantiation libcalls. */ 11790091Sobrienint virtuals_instantiated; 11852518Sobrien 119117404Skan/* Assign unique numbers to labels generated for profiling, debugging, etc. */ 120132732Skanstatic GTY(()) int funcdef_no; 12196283Sobrien 12290091Sobrien/* These variables hold pointers to functions to create and destroy 12390091Sobrien target specific, per-function data structures. */ 124132732Skanstruct machine_function * (*init_machine_status) (void); 12552518Sobrien 12690091Sobrien/* The currently compiled function. */ 12790091Sobrienstruct function *cfun = 0; 12818334Speter 12990091Sobrien/* These arrays record the INSN_UIDs of the prologue and epilogue insns. */ 130169702Skanstatic VEC(int,heap) *prologue; 131169702Skanstatic VEC(int,heap) *epilogue; 13218334Speter 13390091Sobrien/* Array of INSN_UIDs to hold the INSN_UIDs for each sibcall epilogue 13418334Speter in this function. */ 135169702Skanstatic VEC(int,heap) *sibcall_epilogue; 13618334Speter 13718334Speter/* In order to evaluate some expressions, such as function calls returning 13818334Speter structures in memory, we need to temporarily allocate stack locations. 13918334Speter We record each allocated temporary in the following structure. 14018334Speter 14118334Speter Associated with each temporary slot is a nesting level. When we pop up 14218334Speter one level, all temporaries associated with the previous level are freed. 14318334Speter Normally, all temporaries are freed after the execution of the statement 14418334Speter in which they were created. However, if we are inside a ({...}) grouping, 14518334Speter the result may be in a temporary and hence must be preserved. If the 14618334Speter result could be in a temporary, we preserve it if we can determine which 14718334Speter one it is in. If we cannot determine which temporary may contain the 14818334Speter result, all temporaries are preserved. A temporary is preserved by 14918334Speter pretending it was allocated at the previous nesting level. 15018334Speter 15118334Speter Automatic variables are also assigned temporary slots, at the nesting 15218334Speter level where they are defined. They are marked a "kept" so that 15318334Speter free_temp_slots will not free them. */ 15418334Speter 155117404Skanstruct temp_slot GTY(()) 15618334Speter{ 15718334Speter /* Points to next temporary slot. */ 15818334Speter struct temp_slot *next; 159169702Skan /* Points to previous temporary slot. */ 160169702Skan struct temp_slot *prev; 161169702Skan 16252268Sobrien /* The rtx to used to reference the slot. */ 16318334Speter rtx slot; 16418334Speter /* The rtx used to represent the address if not the address of the 16518334Speter slot above. May be an EXPR_LIST if multiple addresses exist. */ 16618334Speter rtx address; 16790091Sobrien /* The alignment (in bits) of the slot. */ 16890091Sobrien unsigned int align; 16918334Speter /* The size, in units, of the slot. */ 17052268Sobrien HOST_WIDE_INT size; 17190091Sobrien /* The type of the object in the slot, or zero if it doesn't correspond 17290091Sobrien to a type. We use this to determine whether a slot can be reused. 17390091Sobrien It can be reused if objects of the type of the new slot will always 17490091Sobrien conflict with objects of the type of the old slot. */ 17590091Sobrien tree type; 176117404Skan /* Nonzero if this temporary is currently in use. */ 17718334Speter char in_use; 178117404Skan /* Nonzero if this temporary has its address taken. */ 17918334Speter char addr_taken; 18018334Speter /* Nesting level at which this slot is being used. */ 18118334Speter int level; 182117404Skan /* Nonzero if this should survive a call to free_temp_slots. */ 18318334Speter int keep; 18418334Speter /* The offset of the slot from the frame_pointer, including extra space 18518334Speter for alignment. This info is for combine_temp_slots. */ 18652268Sobrien HOST_WIDE_INT base_offset; 18718334Speter /* The size of the slot, including extra space for alignment. This 18818334Speter info is for combine_temp_slots. */ 18952268Sobrien HOST_WIDE_INT full_size; 19018334Speter}; 19152268Sobrien 19218334Speter/* Forward declarations. */ 19318334Speter 194132732Skanstatic rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int, 195132732Skan struct function *); 196132732Skanstatic struct temp_slot *find_temp_slot_from_address (rtx); 197132732Skanstatic void pad_to_arg_alignment (struct args_size *, int, struct args_size *); 198132732Skanstatic void pad_below (struct args_size *, enum machine_mode, tree); 199169702Skanstatic void reorder_blocks_1 (rtx, tree, VEC(tree,heap) **); 200132732Skanstatic int all_blocks (tree, tree *); 201132732Skanstatic tree *get_block_vector (tree, int *); 202132732Skanextern tree debug_find_var_in_block_tree (tree, tree); 203169702Skan/* We always define `record_insns' even if it's not used so that we 20490091Sobrien can always export `prologue_epilogue_contains'. */ 205169702Skanstatic void record_insns (rtx, VEC(int,heap) **) ATTRIBUTE_UNUSED; 206169702Skanstatic int contains (rtx, VEC(int,heap) **); 20790091Sobrien#ifdef HAVE_return 208132732Skanstatic void emit_return_into_block (basic_block, rtx); 20952268Sobrien#endif 21090091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX) 211132732Skanstatic rtx keep_stack_depressed (rtx); 21290091Sobrien#endif 213132732Skanstatic void prepare_function_start (tree); 214132732Skanstatic void do_clobber_return_reg (rtx, void *); 215132732Skanstatic void do_use_return_reg (rtx, void *); 216132732Skanstatic void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED; 21718334Speter 21818334Speter/* Pointer to chain of `struct function' for containing functions. */ 219132732Skanstruct function *outer_function_chain; 22018334Speter 22118334Speter/* Given a function decl for a containing function, 22218334Speter return the `struct function' for it. */ 22318334Speter 22418334Speterstruct function * 225132732Skanfind_function_data (tree decl) 22618334Speter{ 22718334Speter struct function *p; 22852268Sobrien 22990091Sobrien for (p = outer_function_chain; p; p = p->outer) 23018334Speter if (p->decl == decl) 23118334Speter return p; 23252268Sobrien 233169702Skan gcc_unreachable (); 23418334Speter} 23518334Speter 23618334Speter/* Save the current context for compilation of a nested function. 23790091Sobrien This is called from language-specific code. The caller should use 238117404Skan the enter_nested langhook to save any language-specific state, 23990091Sobrien since this function knows only about language-independent 24090091Sobrien variables. */ 24118334Speter 24218334Spetervoid 243169702Skanpush_function_context_to (tree context ATTRIBUTE_UNUSED) 24418334Speter{ 24590091Sobrien struct function *p; 24618334Speter 24790091Sobrien if (cfun == 0) 24890091Sobrien init_dummy_function_start (); 24990091Sobrien p = cfun; 25090091Sobrien 25190091Sobrien p->outer = outer_function_chain; 25218334Speter outer_function_chain = p; 25318334Speter 254169702Skan lang_hooks.function.enter_nested (p); 25590091Sobrien 25690091Sobrien cfun = 0; 25718334Speter} 25818334Speter 25918334Spetervoid 260132732Skanpush_function_context (void) 26118334Speter{ 26218334Speter push_function_context_to (current_function_decl); 26318334Speter} 26418334Speter 26518334Speter/* Restore the last saved context, at the end of a nested function. 26618334Speter This function is called from language-specific code. */ 26718334Speter 26818334Spetervoid 269132732Skanpop_function_context_from (tree context ATTRIBUTE_UNUSED) 27018334Speter{ 27118334Speter struct function *p = outer_function_chain; 27218334Speter 27390091Sobrien cfun = p; 27490091Sobrien outer_function_chain = p->outer; 27518334Speter 27618334Speter current_function_decl = p->decl; 27718334Speter 278169702Skan lang_hooks.function.leave_nested (p); 27918334Speter 28018334Speter /* Reset variables that have known state during rtx generation. */ 28118334Speter virtuals_instantiated = 0; 28290091Sobrien generating_concat_p = 1; 28318334Speter} 28418334Speter 28590091Sobrienvoid 286132732Skanpop_function_context (void) 28718334Speter{ 28818334Speter pop_function_context_from (current_function_decl); 28918334Speter} 29090091Sobrien 29190091Sobrien/* Clear out all parts of the state in F that can safely be discarded 29290091Sobrien after the function has been parsed, but not compiled, to let 29390091Sobrien garbage collection reclaim the memory. */ 29490091Sobrien 29590091Sobrienvoid 296132732Skanfree_after_parsing (struct function *f) 29790091Sobrien{ 29890091Sobrien /* f->expr->forced_labels is used by code generation. */ 29990091Sobrien /* f->emit->regno_reg_rtx is used by code generation. */ 30090091Sobrien /* f->varasm is used by code generation. */ 30190091Sobrien /* f->eh->eh_return_stub_label is used by code generation. */ 30290091Sobrien 303169702Skan lang_hooks.function.final (f); 30490091Sobrien} 30590091Sobrien 30690091Sobrien/* Clear out all parts of the state in F that can safely be discarded 30790091Sobrien after the function has been compiled, to let garbage collection 30890091Sobrien reclaim the memory. */ 30990091Sobrien 31090091Sobrienvoid 311132732Skanfree_after_compilation (struct function *f) 31290091Sobrien{ 313169702Skan VEC_free (int, heap, prologue); 314169702Skan VEC_free (int, heap, epilogue); 315169702Skan VEC_free (int, heap, sibcall_epilogue); 316169702Skan 317117404Skan f->eh = NULL; 318117404Skan f->expr = NULL; 319117404Skan f->emit = NULL; 320117404Skan f->varasm = NULL; 321117404Skan f->machine = NULL; 322169702Skan f->cfg = NULL; 32390091Sobrien 324169702Skan f->x_avail_temp_slots = NULL; 325169702Skan f->x_used_temp_slots = NULL; 32690091Sobrien f->arg_offset_rtx = NULL; 32790091Sobrien f->return_rtx = NULL; 32890091Sobrien f->internal_arg_pointer = NULL; 32990091Sobrien f->x_nonlocal_goto_handler_labels = NULL; 33090091Sobrien f->x_return_label = NULL; 331132732Skan f->x_naked_return_label = NULL; 33290091Sobrien f->x_stack_slot_list = NULL; 333169702Skan f->x_stack_check_probe_note = NULL; 33490091Sobrien f->x_arg_pointer_save_area = NULL; 33590091Sobrien f->x_parm_birth_insn = NULL; 33690091Sobrien f->epilogue_delay_list = NULL; 33790091Sobrien} 33818334Speter 33918334Speter/* Allocate fixed slots in the stack frame of the current function. */ 34018334Speter 34190091Sobrien/* Return size needed for stack frame based on slots so far allocated in 34290091Sobrien function F. 34352518Sobrien This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY; 34418334Speter the caller may have to do that. */ 34518334Speter 346169702Skanstatic HOST_WIDE_INT 347132732Skanget_func_frame_size (struct function *f) 34818334Speter{ 349169702Skan if (FRAME_GROWS_DOWNWARD) 350169702Skan return -f->x_frame_offset; 351169702Skan else 352169702Skan return f->x_frame_offset; 35318334Speter} 35418334Speter 35590091Sobrien/* Return size needed for stack frame based on slots so far allocated. 35690091Sobrien This size counts from zero. It is not rounded to PREFERRED_STACK_BOUNDARY; 35790091Sobrien the caller may have to do that. */ 358169702Skan 35990091SobrienHOST_WIDE_INT 360132732Skanget_frame_size (void) 36190091Sobrien{ 36290091Sobrien return get_func_frame_size (cfun); 36390091Sobrien} 36490091Sobrien 365169702Skan/* Issue an error message and return TRUE if frame OFFSET overflows in 366169702Skan the signed target pointer arithmetics for function FUNC. Otherwise 367169702Skan return FALSE. */ 368169702Skan 369169702Skanbool 370169702Skanframe_offset_overflow (HOST_WIDE_INT offset, tree func) 371169702Skan{ 372169702Skan unsigned HOST_WIDE_INT size = FRAME_GROWS_DOWNWARD ? -offset : offset; 373169702Skan 374169702Skan if (size > ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (Pmode) - 1)) 375169702Skan /* Leave room for the fixed part of the frame. */ 376169702Skan - 64 * UNITS_PER_WORD) 377169702Skan { 378169702Skan error ("%Jtotal size of local objects too large", func); 379169702Skan return TRUE; 380169702Skan } 381169702Skan 382169702Skan return FALSE; 383169702Skan} 384169702Skan 38518334Speter/* Allocate a stack slot of SIZE bytes and return a MEM rtx for it 38618334Speter with machine mode MODE. 38790091Sobrien 38818334Speter ALIGN controls the amount of alignment for the address of the slot: 38918334Speter 0 means according to MODE, 39018334Speter -1 means use BIGGEST_ALIGNMENT and round size to multiple of that, 391146908Skan -2 means use BITS_PER_UNIT, 39218334Speter positive specifies alignment boundary in bits. 39318334Speter 39490091Sobrien We do not round to stack_boundary here. 39518334Speter 39690091Sobrien FUNCTION specifies the function to allocate in. */ 39790091Sobrien 39890091Sobrienstatic rtx 399132732Skanassign_stack_local_1 (enum machine_mode mode, HOST_WIDE_INT size, int align, 400132732Skan struct function *function) 40118334Speter{ 40290091Sobrien rtx x, addr; 40318334Speter int bigend_correction = 0; 404169702Skan unsigned int alignment; 40590091Sobrien int frame_off, frame_alignment, frame_phase; 40618334Speter 40718334Speter if (align == 0) 40818334Speter { 40952518Sobrien tree type; 41052518Sobrien 41118334Speter if (mode == BLKmode) 41252518Sobrien alignment = BIGGEST_ALIGNMENT; 41390091Sobrien else 41490091Sobrien alignment = GET_MODE_ALIGNMENT (mode); 41552518Sobrien 41652518Sobrien /* Allow the target to (possibly) increase the alignment of this 41752518Sobrien stack slot. */ 418169702Skan type = lang_hooks.types.type_for_mode (mode, 0); 41952518Sobrien if (type) 42052518Sobrien alignment = LOCAL_ALIGNMENT (type, alignment); 42152518Sobrien 42252518Sobrien alignment /= BITS_PER_UNIT; 42318334Speter } 42418334Speter else if (align == -1) 42518334Speter { 42618334Speter alignment = BIGGEST_ALIGNMENT / BITS_PER_UNIT; 42718334Speter size = CEIL_ROUND (size, alignment); 42818334Speter } 429146908Skan else if (align == -2) 430146908Skan alignment = 1; /* BITS_PER_UNIT / BITS_PER_UNIT */ 43118334Speter else 43218334Speter alignment = align / BITS_PER_UNIT; 43318334Speter 434169702Skan if (FRAME_GROWS_DOWNWARD) 435169702Skan function->x_frame_offset -= size; 43652518Sobrien 43790091Sobrien /* Ignore alignment we can't do with expected alignment of the boundary. */ 43890091Sobrien if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY) 43990091Sobrien alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; 44090091Sobrien 44190091Sobrien if (function->stack_alignment_needed < alignment * BITS_PER_UNIT) 44290091Sobrien function->stack_alignment_needed = alignment * BITS_PER_UNIT; 44390091Sobrien 44490091Sobrien /* Calculate how many bytes the start of local variables is off from 44590091Sobrien stack alignment. */ 44690091Sobrien frame_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; 44790091Sobrien frame_off = STARTING_FRAME_OFFSET % frame_alignment; 44890091Sobrien frame_phase = frame_off ? frame_alignment - frame_off : 0; 44990091Sobrien 450132732Skan /* Round the frame offset to the specified alignment. The default is 451132732Skan to always honor requests to align the stack but a port may choose to 452132732Skan do its own stack alignment by defining STACK_ALIGNMENT_NEEDED. */ 453132732Skan if (STACK_ALIGNMENT_NEEDED 454132732Skan || mode != BLKmode 455132732Skan || size != 0) 456132732Skan { 457132732Skan /* We must be careful here, since FRAME_OFFSET might be negative and 458132732Skan division with a negative dividend isn't as well defined as we might 459132732Skan like. So we instead assume that ALIGNMENT is a power of two and 460132732Skan use logical operations which are unambiguous. */ 461169702Skan if (FRAME_GROWS_DOWNWARD) 462169702Skan function->x_frame_offset 463169702Skan = (FLOOR_ROUND (function->x_frame_offset - frame_phase, 464169702Skan (unsigned HOST_WIDE_INT) alignment) 465169702Skan + frame_phase); 466169702Skan else 467169702Skan function->x_frame_offset 468169702Skan = (CEIL_ROUND (function->x_frame_offset - frame_phase, 469169702Skan (unsigned HOST_WIDE_INT) alignment) 470169702Skan + frame_phase); 471132732Skan } 47218334Speter 47318334Speter /* On a big-endian machine, if we are allocating more space than we will use, 47418334Speter use the least significant bytes of those that are allocated. */ 475169702Skan if (BYTES_BIG_ENDIAN && mode != BLKmode && GET_MODE_SIZE (mode) < size) 47618334Speter bigend_correction = size - GET_MODE_SIZE (mode); 47718334Speter 47818334Speter /* If we have already instantiated virtual registers, return the actual 47918334Speter address relative to the frame pointer. */ 48090091Sobrien if (function == cfun && virtuals_instantiated) 48118334Speter addr = plus_constant (frame_pointer_rtx, 482132732Skan trunc_int_for_mode 48318334Speter (frame_offset + bigend_correction 484132732Skan + STARTING_FRAME_OFFSET, Pmode)); 48518334Speter else 48618334Speter addr = plus_constant (virtual_stack_vars_rtx, 487132732Skan trunc_int_for_mode 488132732Skan (function->x_frame_offset + bigend_correction, 489132732Skan Pmode)); 49018334Speter 491169702Skan if (!FRAME_GROWS_DOWNWARD) 492169702Skan function->x_frame_offset += size; 49318334Speter 49452268Sobrien x = gen_rtx_MEM (mode, addr); 495169702Skan MEM_NOTRAP_P (x) = 1; 49618334Speter 49790091Sobrien function->x_stack_slot_list 49890091Sobrien = gen_rtx_EXPR_LIST (VOIDmode, x, function->x_stack_slot_list); 49918334Speter 500169702Skan if (frame_offset_overflow (function->x_frame_offset, function->decl)) 501169702Skan function->x_frame_offset = 0; 502169702Skan 50318334Speter return x; 50418334Speter} 50518334Speter 50690091Sobrien/* Wrapper around assign_stack_local_1; assign a local stack slot for the 50790091Sobrien current function. */ 50818334Speter 50990091Sobrienrtx 510132732Skanassign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align) 51118334Speter{ 51290091Sobrien return assign_stack_local_1 (mode, size, align, cfun); 51318334Speter} 514169702Skan 51518334Speter 516169702Skan/* Removes temporary slot TEMP from LIST. */ 517169702Skan 518169702Skanstatic void 519169702Skancut_slot_from_list (struct temp_slot *temp, struct temp_slot **list) 520169702Skan{ 521169702Skan if (temp->next) 522169702Skan temp->next->prev = temp->prev; 523169702Skan if (temp->prev) 524169702Skan temp->prev->next = temp->next; 525169702Skan else 526169702Skan *list = temp->next; 527169702Skan 528169702Skan temp->prev = temp->next = NULL; 529169702Skan} 530169702Skan 531169702Skan/* Inserts temporary slot TEMP to LIST. */ 532169702Skan 533169702Skanstatic void 534169702Skaninsert_slot_to_list (struct temp_slot *temp, struct temp_slot **list) 535169702Skan{ 536169702Skan temp->next = *list; 537169702Skan if (*list) 538169702Skan (*list)->prev = temp; 539169702Skan temp->prev = NULL; 540169702Skan *list = temp; 541169702Skan} 542169702Skan 543169702Skan/* Returns the list of used temp slots at LEVEL. */ 544169702Skan 545169702Skanstatic struct temp_slot ** 546169702Skantemp_slots_at_level (int level) 547169702Skan{ 548169702Skan if (level >= (int) VEC_length (temp_slot_p, used_temp_slots)) 549169702Skan { 550169702Skan size_t old_length = VEC_length (temp_slot_p, used_temp_slots); 551169702Skan temp_slot_p *p; 552169702Skan 553169702Skan VEC_safe_grow (temp_slot_p, gc, used_temp_slots, level + 1); 554169702Skan p = VEC_address (temp_slot_p, used_temp_slots); 555169702Skan memset (&p[old_length], 0, 556169702Skan sizeof (temp_slot_p) * (level + 1 - old_length)); 557169702Skan } 558169702Skan 559169702Skan return &(VEC_address (temp_slot_p, used_temp_slots)[level]); 560169702Skan} 561169702Skan 562169702Skan/* Returns the maximal temporary slot level. */ 563169702Skan 564169702Skanstatic int 565169702Skanmax_slot_level (void) 566169702Skan{ 567169702Skan if (!used_temp_slots) 568169702Skan return -1; 569169702Skan 570169702Skan return VEC_length (temp_slot_p, used_temp_slots) - 1; 571169702Skan} 572169702Skan 573169702Skan/* Moves temporary slot TEMP to LEVEL. */ 574169702Skan 575169702Skanstatic void 576169702Skanmove_slot_to_level (struct temp_slot *temp, int level) 577169702Skan{ 578169702Skan cut_slot_from_list (temp, temp_slots_at_level (temp->level)); 579169702Skan insert_slot_to_list (temp, temp_slots_at_level (level)); 580169702Skan temp->level = level; 581169702Skan} 582169702Skan 583169702Skan/* Make temporary slot TEMP available. */ 584169702Skan 585169702Skanstatic void 586169702Skanmake_slot_available (struct temp_slot *temp) 587169702Skan{ 588169702Skan cut_slot_from_list (temp, temp_slots_at_level (temp->level)); 589169702Skan insert_slot_to_list (temp, &avail_temp_slots); 590169702Skan temp->in_use = 0; 591169702Skan temp->level = -1; 592169702Skan} 593169702Skan 59418334Speter/* Allocate a temporary stack slot and record it for possible later 59518334Speter reuse. 59618334Speter 59718334Speter MODE is the machine mode to be given to the returned rtx. 59818334Speter 59918334Speter SIZE is the size in units of the space required. We do no rounding here 60018334Speter since assign_stack_local will do any required rounding. 60118334Speter 60218334Speter KEEP is 1 if this slot is to be retained after a call to 60318334Speter free_temp_slots. Automatic variables for a block are allocated 604169702Skan with this flag. KEEP values of 2 or 3 were needed respectively 605169702Skan for variables whose lifetime is controlled by CLEANUP_POINT_EXPRs 606169702Skan or for SAVE_EXPRs, but they are now unused. 60718334Speter 60852518Sobrien TYPE is the type that will be used for the stack slot. */ 60952518Sobrien 61090091Sobrienrtx 611169702Skanassign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size, 612169702Skan int keep, tree type) 61318334Speter{ 61490091Sobrien unsigned int align; 615169702Skan struct temp_slot *p, *best_p = 0, *selected = NULL, **pp; 616102794Skan rtx slot; 61718334Speter 61818334Speter /* If SIZE is -1 it means that somebody tried to allocate a temporary 61918334Speter of a variable size. */ 620169702Skan gcc_assert (size != -1); 62118334Speter 622169702Skan /* These are now unused. */ 623169702Skan gcc_assert (keep <= 1); 624169702Skan 62552518Sobrien if (mode == BLKmode) 62652518Sobrien align = BIGGEST_ALIGNMENT; 62790091Sobrien else 62890091Sobrien align = GET_MODE_ALIGNMENT (mode); 62952518Sobrien 63052518Sobrien if (! type) 631169702Skan type = lang_hooks.types.type_for_mode (mode, 0); 63290091Sobrien 63352518Sobrien if (type) 63452518Sobrien align = LOCAL_ALIGNMENT (type, align); 63552518Sobrien 63652518Sobrien /* Try to find an available, already-allocated temporary of the proper 63752518Sobrien mode which meets the size and alignment requirements. Choose the 638169702Skan smallest one with the closest alignment. 639169702Skan 640169702Skan If assign_stack_temp is called outside of the tree->rtl expansion, 641169702Skan we cannot reuse the stack slots (that may still refer to 642169702Skan VIRTUAL_STACK_VARS_REGNUM). */ 643169702Skan if (!virtuals_instantiated) 644169702Skan { 645169702Skan for (p = avail_temp_slots; p; p = p->next) 646169702Skan { 647169702Skan if (p->align >= align && p->size >= size 648169702Skan && GET_MODE (p->slot) == mode 649169702Skan && objects_must_conflict_p (p->type, type) 650169702Skan && (best_p == 0 || best_p->size > p->size 651169702Skan || (best_p->size == p->size && best_p->align > p->align))) 652169702Skan { 653169702Skan if (p->align == align && p->size == size) 654169702Skan { 655169702Skan selected = p; 656169702Skan cut_slot_from_list (selected, &avail_temp_slots); 657169702Skan best_p = 0; 658169702Skan break; 659169702Skan } 660169702Skan best_p = p; 661169702Skan } 662169702Skan } 663169702Skan } 66418334Speter 66518334Speter /* Make our best, if any, the one to use. */ 66618334Speter if (best_p) 66718334Speter { 668169702Skan selected = best_p; 669169702Skan cut_slot_from_list (selected, &avail_temp_slots); 670169702Skan 67118334Speter /* If there are enough aligned bytes left over, make them into a new 67218334Speter temp_slot so that the extra bytes don't get wasted. Do this only 67318334Speter for BLKmode slots, so that we can be sure of the alignment. */ 67490091Sobrien if (GET_MODE (best_p->slot) == BLKmode) 67518334Speter { 67652518Sobrien int alignment = best_p->align / BITS_PER_UNIT; 67752268Sobrien HOST_WIDE_INT rounded_size = CEIL_ROUND (size, alignment); 67818334Speter 67918334Speter if (best_p->size - rounded_size >= alignment) 68018334Speter { 681132732Skan p = ggc_alloc (sizeof (struct temp_slot)); 68218334Speter p->in_use = p->addr_taken = 0; 68318334Speter p->size = best_p->size - rounded_size; 68418334Speter p->base_offset = best_p->base_offset + rounded_size; 68518334Speter p->full_size = best_p->full_size - rounded_size; 686169702Skan p->slot = adjust_address_nv (best_p->slot, BLKmode, rounded_size); 68752518Sobrien p->align = best_p->align; 68818334Speter p->address = 0; 68990091Sobrien p->type = best_p->type; 690169702Skan insert_slot_to_list (p, &avail_temp_slots); 69118334Speter 69252268Sobrien stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, p->slot, 69352268Sobrien stack_slot_list); 69418334Speter 69518334Speter best_p->size = rounded_size; 69618334Speter best_p->full_size = rounded_size; 69718334Speter } 69818334Speter } 69918334Speter } 70090091Sobrien 70118334Speter /* If we still didn't find one, make a new temporary. */ 702169702Skan if (selected == 0) 70318334Speter { 70452268Sobrien HOST_WIDE_INT frame_offset_old = frame_offset; 70552268Sobrien 706132732Skan p = ggc_alloc (sizeof (struct temp_slot)); 70752268Sobrien 70852518Sobrien /* We are passing an explicit alignment request to assign_stack_local. 70952518Sobrien One side effect of that is assign_stack_local will not round SIZE 71052518Sobrien to ensure the frame offset remains suitably aligned. 71152268Sobrien 71252518Sobrien So for requests which depended on the rounding of SIZE, we go ahead 71352518Sobrien and round it now. We also make sure ALIGNMENT is at least 71452518Sobrien BIGGEST_ALIGNMENT. */ 715169702Skan gcc_assert (mode != BLKmode || align == BIGGEST_ALIGNMENT); 71652518Sobrien p->slot = assign_stack_local (mode, 71752763Sobrien (mode == BLKmode 718132732Skan ? CEIL_ROUND (size, (int) align / BITS_PER_UNIT) 71952763Sobrien : size), 72052518Sobrien align); 72152518Sobrien 72252518Sobrien p->align = align; 72352518Sobrien 72418334Speter /* The following slot size computation is necessary because we don't 72518334Speter know the actual size of the temporary slot until assign_stack_local 72618334Speter has performed all the frame alignment and size rounding for the 72718334Speter requested temporary. Note that extra space added for alignment 72818334Speter can be either above or below this stack slot depending on which 72918334Speter way the frame grows. We include the extra space if and only if it 73018334Speter is above this slot. */ 731169702Skan if (FRAME_GROWS_DOWNWARD) 732169702Skan p->size = frame_offset_old - frame_offset; 733169702Skan else 734169702Skan p->size = size; 73552268Sobrien 73618334Speter /* Now define the fields used by combine_temp_slots. */ 737169702Skan if (FRAME_GROWS_DOWNWARD) 738169702Skan { 739169702Skan p->base_offset = frame_offset; 740169702Skan p->full_size = frame_offset_old - frame_offset; 741169702Skan } 742169702Skan else 743169702Skan { 744169702Skan p->base_offset = frame_offset_old; 745169702Skan p->full_size = frame_offset - frame_offset_old; 746169702Skan } 74718334Speter p->address = 0; 748169702Skan 749169702Skan selected = p; 75018334Speter } 75118334Speter 752169702Skan p = selected; 75318334Speter p->in_use = 1; 75418334Speter p->addr_taken = 0; 75590091Sobrien p->type = type; 756169702Skan p->level = temp_slot_level; 757169702Skan p->keep = keep; 75818334Speter 759169702Skan pp = temp_slots_at_level (p->level); 760169702Skan insert_slot_to_list (p, pp); 76152268Sobrien 762102794Skan /* Create a new MEM rtx to avoid clobbering MEM flags of old slots. */ 763102794Skan slot = gen_rtx_MEM (mode, XEXP (p->slot, 0)); 764102794Skan stack_slot_list = gen_rtx_EXPR_LIST (VOIDmode, slot, stack_slot_list); 765102794Skan 76690091Sobrien /* If we know the alias set for the memory that will be used, use 76790091Sobrien it. If there's no TYPE, then we don't know anything about the 76890091Sobrien alias set for the memory. */ 769102794Skan set_mem_alias_set (slot, type ? get_alias_set (type) : 0); 770102794Skan set_mem_align (slot, align); 77190091Sobrien 77290091Sobrien /* If a type is specified, set the relevant flags. */ 77390091Sobrien if (type != 0) 77490091Sobrien { 775102794Skan MEM_VOLATILE_P (slot) = TYPE_VOLATILE (type); 776102794Skan MEM_SET_IN_STRUCT_P (slot, AGGREGATE_TYPE_P (type)); 77790091Sobrien } 778169702Skan MEM_NOTRAP_P (slot) = 1; 77990091Sobrien 780102794Skan return slot; 78118334Speter} 78252518Sobrien 78352518Sobrien/* Allocate a temporary stack slot and record it for possible later 78452518Sobrien reuse. First three arguments are same as in preceding function. */ 78552518Sobrien 78652518Sobrienrtx 787132732Skanassign_stack_temp (enum machine_mode mode, HOST_WIDE_INT size, int keep) 78852518Sobrien{ 78952518Sobrien return assign_stack_temp_for_type (mode, size, keep, NULL_TREE); 79052518Sobrien} 79152268Sobrien 79296283Sobrien/* Assign a temporary. 79396283Sobrien If TYPE_OR_DECL is a decl, then we are doing it on behalf of the decl 79496283Sobrien and so that should be used in error messages. In either case, we 79596283Sobrien allocate of the given type. 79652268Sobrien KEEP is as for assign_stack_temp. 79752268Sobrien MEMORY_REQUIRED is 1 if the result must be addressable stack memory; 79852268Sobrien it is 0 if a register is OK. 79952268Sobrien DONT_PROMOTE is 1 if we should not promote values in register 80052268Sobrien to wider modes. */ 80118334Speter 80252268Sobrienrtx 803132732Skanassign_temp (tree type_or_decl, int keep, int memory_required, 804132732Skan int dont_promote ATTRIBUTE_UNUSED) 80552268Sobrien{ 80696283Sobrien tree type, decl; 80796283Sobrien enum machine_mode mode; 808169702Skan#ifdef PROMOTE_MODE 80996283Sobrien int unsignedp; 81090091Sobrien#endif 81152268Sobrien 81296283Sobrien if (DECL_P (type_or_decl)) 81396283Sobrien decl = type_or_decl, type = TREE_TYPE (decl); 81496283Sobrien else 81596283Sobrien decl = NULL, type = type_or_decl; 81696283Sobrien 81796283Sobrien mode = TYPE_MODE (type); 818169702Skan#ifdef PROMOTE_MODE 819169702Skan unsignedp = TYPE_UNSIGNED (type); 82096283Sobrien#endif 82196283Sobrien 82252268Sobrien if (mode == BLKmode || memory_required) 82352268Sobrien { 82452268Sobrien HOST_WIDE_INT size = int_size_in_bytes (type); 82552268Sobrien rtx tmp; 82652268Sobrien 82790091Sobrien /* Zero sized arrays are GNU C extension. Set size to 1 to avoid 82890091Sobrien problems with allocating the stack space. */ 82990091Sobrien if (size == 0) 83090091Sobrien size = 1; 83190091Sobrien 83252268Sobrien /* Unfortunately, we don't yet know how to allocate variable-sized 833169702Skan temporaries. However, sometimes we can find a fixed upper limit on 834169702Skan the size, so try that instead. */ 835169702Skan else if (size == -1) 836169702Skan size = max_int_size_in_bytes (type); 83752268Sobrien 83896283Sobrien /* The size of the temporary may be too large to fit into an integer. */ 83996283Sobrien /* ??? Not sure this should happen except for user silliness, so limit 840117404Skan this to things that aren't compiler-generated temporaries. The 841169702Skan rest of the time we'll die in assign_stack_temp_for_type. */ 84296283Sobrien if (decl && size == -1 84396283Sobrien && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST) 84496283Sobrien { 845169702Skan error ("size of variable %q+D is too large", decl); 84696283Sobrien size = 1; 84796283Sobrien } 84896283Sobrien 84952518Sobrien tmp = assign_stack_temp_for_type (mode, size, keep, type); 85052268Sobrien return tmp; 85152268Sobrien } 85252268Sobrien 853169702Skan#ifdef PROMOTE_MODE 85452268Sobrien if (! dont_promote) 85552268Sobrien mode = promote_mode (type, mode, &unsignedp, 0); 85652268Sobrien#endif 85752268Sobrien 85852268Sobrien return gen_reg_rtx (mode); 85952268Sobrien} 86052268Sobrien 86118334Speter/* Combine temporary stack slots which are adjacent on the stack. 86218334Speter 86318334Speter This allows for better use of already allocated stack space. This is only 86418334Speter done for BLKmode slots because we can be sure that we won't have alignment 86518334Speter problems in this case. */ 86618334Speter 867169702Skanstatic void 868132732Skancombine_temp_slots (void) 86918334Speter{ 870169702Skan struct temp_slot *p, *q, *next, *next_q; 87152268Sobrien int num_slots; 87218334Speter 87352518Sobrien /* We can't combine slots, because the information about which slot 87452518Sobrien is in which alias set will be lost. */ 87552518Sobrien if (flag_strict_aliasing) 87652518Sobrien return; 87752518Sobrien 87890091Sobrien /* If there are a lot of temp slots, don't do anything unless 87990091Sobrien high levels of optimization. */ 88052268Sobrien if (! flag_expensive_optimizations) 881169702Skan for (p = avail_temp_slots, num_slots = 0; p; p = p->next, num_slots++) 88252268Sobrien if (num_slots > 100 || (num_slots > 10 && optimize == 0)) 88352268Sobrien return; 88452268Sobrien 885169702Skan for (p = avail_temp_slots; p; p = next) 88618334Speter { 88718334Speter int delete_p = 0; 88852268Sobrien 889169702Skan next = p->next; 890169702Skan 891169702Skan if (GET_MODE (p->slot) != BLKmode) 892169702Skan continue; 893169702Skan 894169702Skan for (q = p->next; q; q = next_q) 895169702Skan { 896169702Skan int delete_q = 0; 897169702Skan 898169702Skan next_q = q->next; 899169702Skan 900169702Skan if (GET_MODE (q->slot) != BLKmode) 901169702Skan continue; 902169702Skan 903169702Skan if (p->base_offset + p->full_size == q->base_offset) 904169702Skan { 905169702Skan /* Q comes after P; combine Q into P. */ 906169702Skan p->size += q->size; 907169702Skan p->full_size += q->full_size; 908169702Skan delete_q = 1; 909169702Skan } 910169702Skan else if (q->base_offset + q->full_size == p->base_offset) 911169702Skan { 912169702Skan /* P comes after Q; combine P into Q. */ 913169702Skan q->size += p->size; 914169702Skan q->full_size += p->full_size; 915169702Skan delete_p = 1; 916169702Skan break; 917169702Skan } 918169702Skan if (delete_q) 919169702Skan cut_slot_from_list (q, &avail_temp_slots); 920169702Skan } 921169702Skan 92218334Speter /* Either delete P or advance past it. */ 92318334Speter if (delete_p) 924169702Skan cut_slot_from_list (p, &avail_temp_slots); 92518334Speter } 92618334Speter} 92718334Speter 92818334Speter/* Find the temp slot corresponding to the object at address X. */ 92918334Speter 93018334Speterstatic struct temp_slot * 931132732Skanfind_temp_slot_from_address (rtx x) 93218334Speter{ 93318334Speter struct temp_slot *p; 93418334Speter rtx next; 935169702Skan int i; 93618334Speter 937169702Skan for (i = max_slot_level (); i >= 0; i--) 938169702Skan for (p = *temp_slots_at_level (i); p; p = p->next) 939169702Skan { 940169702Skan if (XEXP (p->slot, 0) == x 941169702Skan || p->address == x 942169702Skan || (GET_CODE (x) == PLUS 943169702Skan && XEXP (x, 0) == virtual_stack_vars_rtx 944169702Skan && GET_CODE (XEXP (x, 1)) == CONST_INT 945169702Skan && INTVAL (XEXP (x, 1)) >= p->base_offset 946169702Skan && INTVAL (XEXP (x, 1)) < p->base_offset + p->full_size)) 947169702Skan return p; 94852268Sobrien 949169702Skan else if (p->address != 0 && GET_CODE (p->address) == EXPR_LIST) 950169702Skan for (next = p->address; next; next = XEXP (next, 1)) 951169702Skan if (XEXP (next, 0) == x) 952169702Skan return p; 953169702Skan } 95418334Speter 95590091Sobrien /* If we have a sum involving a register, see if it points to a temp 95690091Sobrien slot. */ 957169702Skan if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 0)) 95890091Sobrien && (p = find_temp_slot_from_address (XEXP (x, 0))) != 0) 95990091Sobrien return p; 960169702Skan else if (GET_CODE (x) == PLUS && REG_P (XEXP (x, 1)) 96190091Sobrien && (p = find_temp_slot_from_address (XEXP (x, 1))) != 0) 96290091Sobrien return p; 96390091Sobrien 96418334Speter return 0; 96518334Speter} 96690091Sobrien 96718334Speter/* Indicate that NEW is an alternate way of referring to the temp slot 96852268Sobrien that previously was known by OLD. */ 96918334Speter 97018334Spetervoid 971132732Skanupdate_temp_slot_address (rtx old, rtx new) 97218334Speter{ 97390091Sobrien struct temp_slot *p; 97418334Speter 97590091Sobrien if (rtx_equal_p (old, new)) 97690091Sobrien return; 97790091Sobrien 97890091Sobrien p = find_temp_slot_from_address (old); 97990091Sobrien 98090091Sobrien /* If we didn't find one, see if both OLD is a PLUS. If so, and NEW 98190091Sobrien is a register, see if one operand of the PLUS is a temporary 98290091Sobrien location. If so, NEW points into it. Otherwise, if both OLD and 98390091Sobrien NEW are a PLUS and if there is a register in common between them. 98490091Sobrien If so, try a recursive call on those values. */ 98518334Speter if (p == 0) 98690091Sobrien { 98790091Sobrien if (GET_CODE (old) != PLUS) 98890091Sobrien return; 98990091Sobrien 990169702Skan if (REG_P (new)) 99190091Sobrien { 99290091Sobrien update_temp_slot_address (XEXP (old, 0), new); 99390091Sobrien update_temp_slot_address (XEXP (old, 1), new); 99490091Sobrien return; 99590091Sobrien } 99690091Sobrien else if (GET_CODE (new) != PLUS) 99790091Sobrien return; 99890091Sobrien 99990091Sobrien if (rtx_equal_p (XEXP (old, 0), XEXP (new, 0))) 100090091Sobrien update_temp_slot_address (XEXP (old, 1), XEXP (new, 1)); 100190091Sobrien else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 0))) 100290091Sobrien update_temp_slot_address (XEXP (old, 0), XEXP (new, 1)); 100390091Sobrien else if (rtx_equal_p (XEXP (old, 0), XEXP (new, 1))) 100490091Sobrien update_temp_slot_address (XEXP (old, 1), XEXP (new, 0)); 100590091Sobrien else if (rtx_equal_p (XEXP (old, 1), XEXP (new, 1))) 100690091Sobrien update_temp_slot_address (XEXP (old, 0), XEXP (new, 0)); 100790091Sobrien 100890091Sobrien return; 100990091Sobrien } 101090091Sobrien 101190091Sobrien /* Otherwise add an alias for the temp's address. */ 101218334Speter else if (p->address == 0) 101318334Speter p->address = new; 101418334Speter else 101518334Speter { 101618334Speter if (GET_CODE (p->address) != EXPR_LIST) 101752268Sobrien p->address = gen_rtx_EXPR_LIST (VOIDmode, p->address, NULL_RTX); 101818334Speter 101952268Sobrien p->address = gen_rtx_EXPR_LIST (VOIDmode, new, p->address); 102018334Speter } 102118334Speter} 102218334Speter 102318334Speter/* If X could be a reference to a temporary slot, mark the fact that its 102418334Speter address was taken. */ 102518334Speter 102618334Spetervoid 1027132732Skanmark_temp_addr_taken (rtx x) 102818334Speter{ 102918334Speter struct temp_slot *p; 103018334Speter 103118334Speter if (x == 0) 103218334Speter return; 103318334Speter 103418334Speter /* If X is not in memory or is at a constant address, it cannot be in 103518334Speter a temporary slot. */ 1036169702Skan if (!MEM_P (x) || CONSTANT_P (XEXP (x, 0))) 103718334Speter return; 103818334Speter 103918334Speter p = find_temp_slot_from_address (XEXP (x, 0)); 104018334Speter if (p != 0) 104118334Speter p->addr_taken = 1; 104218334Speter} 104318334Speter 104452268Sobrien/* If X could be a reference to a temporary slot, mark that slot as 104552268Sobrien belonging to the to one level higher than the current level. If X 104652268Sobrien matched one of our slots, just mark that one. Otherwise, we can't 104752268Sobrien easily predict which it is, so upgrade all of them. Kept slots 104852268Sobrien need not be touched. 104918334Speter 105018334Speter This is called when an ({...}) construct occurs and a statement 105118334Speter returns a value in memory. */ 105218334Speter 105318334Spetervoid 1054132732Skanpreserve_temp_slots (rtx x) 105518334Speter{ 1056169702Skan struct temp_slot *p = 0, *next; 105718334Speter 105818334Speter /* If there is no result, we still might have some objects whose address 105918334Speter were taken, so we need to make sure they stay around. */ 106018334Speter if (x == 0) 106118334Speter { 1062169702Skan for (p = *temp_slots_at_level (temp_slot_level); p; p = next) 1063169702Skan { 1064169702Skan next = p->next; 106518334Speter 1066169702Skan if (p->addr_taken) 1067169702Skan move_slot_to_level (p, temp_slot_level - 1); 1068169702Skan } 1069169702Skan 107018334Speter return; 107118334Speter } 107218334Speter 107318334Speter /* If X is a register that is being used as a pointer, see if we have 107418334Speter a temporary slot we know it points to. To be consistent with 107518334Speter the code below, we really should preserve all non-kept slots 107618334Speter if we can't find a match, but that seems to be much too costly. */ 1077169702Skan if (REG_P (x) && REG_POINTER (x)) 107818334Speter p = find_temp_slot_from_address (x); 107918334Speter 108018334Speter /* If X is not in memory or is at a constant address, it cannot be in 108118334Speter a temporary slot, but it can contain something whose address was 108218334Speter taken. */ 1083169702Skan if (p == 0 && (!MEM_P (x) || CONSTANT_P (XEXP (x, 0)))) 108418334Speter { 1085169702Skan for (p = *temp_slots_at_level (temp_slot_level); p; p = next) 1086169702Skan { 1087169702Skan next = p->next; 108818334Speter 1089169702Skan if (p->addr_taken) 1090169702Skan move_slot_to_level (p, temp_slot_level - 1); 1091169702Skan } 1092169702Skan 109318334Speter return; 109418334Speter } 109518334Speter 109618334Speter /* First see if we can find a match. */ 109718334Speter if (p == 0) 109818334Speter p = find_temp_slot_from_address (XEXP (x, 0)); 109918334Speter 110018334Speter if (p != 0) 110118334Speter { 110218334Speter /* Move everything at our level whose address was taken to our new 110318334Speter level in case we used its address. */ 110418334Speter struct temp_slot *q; 110518334Speter 110652268Sobrien if (p->level == temp_slot_level) 110752268Sobrien { 1108169702Skan for (q = *temp_slots_at_level (temp_slot_level); q; q = next) 1109169702Skan { 1110169702Skan next = q->next; 111118334Speter 1112169702Skan if (p != q && q->addr_taken) 1113169702Skan move_slot_to_level (q, temp_slot_level - 1); 1114169702Skan } 1115169702Skan 1116169702Skan move_slot_to_level (p, temp_slot_level - 1); 111752268Sobrien p->addr_taken = 0; 111852268Sobrien } 111918334Speter return; 112018334Speter } 112118334Speter 112218334Speter /* Otherwise, preserve all non-kept slots at this level. */ 1123169702Skan for (p = *temp_slots_at_level (temp_slot_level); p; p = next) 1124169702Skan { 1125169702Skan next = p->next; 112618334Speter 1127169702Skan if (!p->keep) 1128169702Skan move_slot_to_level (p, temp_slot_level - 1); 112918334Speter } 113018334Speter} 113118334Speter 1132169702Skan/* Free all temporaries used so far. This is normally called at the 1133169702Skan end of generating code for a statement. */ 113418334Speter 113518334Spetervoid 1136132732Skanfree_temp_slots (void) 113718334Speter{ 1138169702Skan struct temp_slot *p, *next; 113918334Speter 1140169702Skan for (p = *temp_slots_at_level (temp_slot_level); p; p = next) 1141169702Skan { 1142169702Skan next = p->next; 114318334Speter 1144169702Skan if (!p->keep) 1145169702Skan make_slot_available (p); 1146169702Skan } 114718334Speter 114818334Speter combine_temp_slots (); 114918334Speter} 115018334Speter 115118334Speter/* Push deeper into the nesting level for stack temporaries. */ 115218334Speter 115318334Spetervoid 1154132732Skanpush_temp_slots (void) 115518334Speter{ 115618334Speter temp_slot_level++; 115718334Speter} 115818334Speter 115918334Speter/* Pop a temporary nesting level. All slots in use in the current level 116018334Speter are freed. */ 116118334Speter 116218334Spetervoid 1163132732Skanpop_temp_slots (void) 116418334Speter{ 1165169702Skan struct temp_slot *p, *next; 116618334Speter 1167169702Skan for (p = *temp_slots_at_level (temp_slot_level); p; p = next) 1168169702Skan { 1169169702Skan next = p->next; 1170169702Skan make_slot_available (p); 1171169702Skan } 117218334Speter 117318334Speter combine_temp_slots (); 117418334Speter 117518334Speter temp_slot_level--; 117618334Speter} 117752268Sobrien 117852268Sobrien/* Initialize temporary slots. */ 117952268Sobrien 118052268Sobrienvoid 1181132732Skaninit_temp_slots (void) 118252268Sobrien{ 118352268Sobrien /* We have not allocated any temporaries yet. */ 1184169702Skan avail_temp_slots = 0; 1185169702Skan used_temp_slots = 0; 118652268Sobrien temp_slot_level = 0; 118752268Sobrien} 118818334Speter 1189169702Skan/* These routines are responsible for converting virtual register references 1190169702Skan to the actual hard register references once RTL generation is complete. 119118334Speter 1192169702Skan The following four variables are used for communication between the 1193169702Skan routines. They contain the offsets of the virtual registers from their 1194169702Skan respective hard registers. */ 119518334Speter 1196169702Skanstatic int in_arg_offset; 1197169702Skanstatic int var_offset; 1198169702Skanstatic int dynamic_offset; 1199169702Skanstatic int out_arg_offset; 1200169702Skanstatic int cfa_offset; 120118334Speter 1202169702Skan/* In most machines, the stack pointer register is equivalent to the bottom 1203169702Skan of the stack. */ 120418334Speter 1205169702Skan#ifndef STACK_POINTER_OFFSET 1206169702Skan#define STACK_POINTER_OFFSET 0 1207169702Skan#endif 120818334Speter 1209169702Skan/* If not defined, pick an appropriate default for the offset of dynamically 1210169702Skan allocated memory depending on the value of ACCUMULATE_OUTGOING_ARGS, 1211169702Skan REG_PARM_STACK_SPACE, and OUTGOING_REG_PARM_STACK_SPACE. */ 121218334Speter 1213169702Skan#ifndef STACK_DYNAMIC_OFFSET 121418334Speter 1215169702Skan/* The bottom of the stack points to the actual arguments. If 1216169702Skan REG_PARM_STACK_SPACE is defined, this includes the space for the register 1217169702Skan parameters. However, if OUTGOING_REG_PARM_STACK space is not defined, 1218169702Skan stack space for register parameters is not pushed by the caller, but 1219169702Skan rather part of the fixed stack areas and hence not included in 1220169702Skan `current_function_outgoing_args_size'. Nevertheless, we must allow 1221169702Skan for it when allocating stack dynamic objects. */ 122218334Speter 1223169702Skan#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE) 1224169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL) \ 1225169702Skan((ACCUMULATE_OUTGOING_ARGS \ 1226169702Skan ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\ 1227169702Skan + (STACK_POINTER_OFFSET)) \ 1228169702Skan 1229169702Skan#else 1230169702Skan#define STACK_DYNAMIC_OFFSET(FNDECL) \ 1231169702Skan((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0) \ 1232169702Skan + (STACK_POINTER_OFFSET)) 123352268Sobrien#endif 1234169702Skan#endif 123552268Sobrien 1236169702Skan 1237169702Skan/* Given a piece of RTX and a pointer to a HOST_WIDE_INT, if the RTX 1238169702Skan is a virtual register, return the equivalent hard register and set the 1239169702Skan offset indirectly through the pointer. Otherwise, return 0. */ 124052268Sobrien 1241169702Skanstatic rtx 1242169702Skaninstantiate_new_reg (rtx x, HOST_WIDE_INT *poffset) 1243169702Skan{ 1244169702Skan rtx new; 1245169702Skan HOST_WIDE_INT offset; 124618334Speter 1247169702Skan if (x == virtual_incoming_args_rtx) 1248169702Skan new = arg_pointer_rtx, offset = in_arg_offset; 1249169702Skan else if (x == virtual_stack_vars_rtx) 1250169702Skan new = frame_pointer_rtx, offset = var_offset; 1251169702Skan else if (x == virtual_stack_dynamic_rtx) 1252169702Skan new = stack_pointer_rtx, offset = dynamic_offset; 1253169702Skan else if (x == virtual_outgoing_args_rtx) 1254169702Skan new = stack_pointer_rtx, offset = out_arg_offset; 1255169702Skan else if (x == virtual_cfa_rtx) 125652268Sobrien { 1257169702Skan#ifdef FRAME_POINTER_CFA_OFFSET 1258169702Skan new = frame_pointer_rtx; 125918334Speter#else 1260169702Skan new = arg_pointer_rtx; 126118334Speter#endif 1262169702Skan offset = cfa_offset; 126318334Speter } 126452268Sobrien else 1265169702Skan return NULL_RTX; 126618334Speter 1267169702Skan *poffset = offset; 1268169702Skan return new; 126990091Sobrien} 127052268Sobrien 1271169702Skan/* A subroutine of instantiate_virtual_regs, called via for_each_rtx. 1272169702Skan Instantiate any virtual registers present inside of *LOC. The expression 1273169702Skan is simplified, as much as possible, but is not to be considered "valid" 1274169702Skan in any sense implied by the target. If any change is made, set CHANGED 1275169702Skan to true. */ 127690091Sobrien 1277169702Skanstatic int 1278169702Skaninstantiate_virtual_regs_in_rtx (rtx *loc, void *data) 127990091Sobrien{ 1280169702Skan HOST_WIDE_INT offset; 1281169702Skan bool *changed = (bool *) data; 1282169702Skan rtx x, new; 128390091Sobrien 1284169702Skan x = *loc; 1285169702Skan if (x == 0) 1286169702Skan return 0; 128718334Speter 1288169702Skan switch (GET_CODE (x)) 128990091Sobrien { 1290169702Skan case REG: 1291169702Skan new = instantiate_new_reg (x, &offset); 1292169702Skan if (new) 1293169702Skan { 1294169702Skan *loc = plus_constant (new, offset); 1295169702Skan if (changed) 1296169702Skan *changed = true; 1297169702Skan } 1298169702Skan return -1; 129918334Speter 1300169702Skan case PLUS: 1301169702Skan new = instantiate_new_reg (XEXP (x, 0), &offset); 1302169702Skan if (new) 130318334Speter { 1304169702Skan new = plus_constant (new, offset); 1305169702Skan *loc = simplify_gen_binary (PLUS, GET_MODE (x), new, XEXP (x, 1)); 1306169702Skan if (changed) 1307169702Skan *changed = true; 1308169702Skan return -1; 130918334Speter } 131018334Speter 1311169702Skan /* FIXME -- from old code */ 1312169702Skan /* If we have (plus (subreg (virtual-reg)) (const_int)), we know 1313169702Skan we can commute the PLUS and SUBREG because pointers into the 1314169702Skan frame are well-behaved. */ 1315169702Skan break; 131618334Speter 1317169702Skan default: 1318169702Skan break; 131918334Speter } 132018334Speter 1321169702Skan return 0; 132218334Speter} 132318334Speter 1324169702Skan/* A subroutine of instantiate_virtual_regs_in_insn. Return true if X 1325169702Skan matches the predicate for insn CODE operand OPERAND. */ 132618334Speter 1327169702Skanstatic int 1328169702Skansafe_insn_predicate (int code, int operand, rtx x) 132918334Speter{ 1330169702Skan const struct insn_operand_data *op_data; 133152268Sobrien 1332169702Skan if (code < 0) 1333169702Skan return true; 133490091Sobrien 1335169702Skan op_data = &insn_data[code].operand[operand]; 1336169702Skan if (op_data->predicate == NULL) 1337169702Skan return true; 133818334Speter 1339169702Skan return op_data->predicate (x, op_data->mode); 134090091Sobrien} 134118334Speter 1342169702Skan/* A subroutine of instantiate_virtual_regs. Instantiate any virtual 1343169702Skan registers present inside of insn. The result will be a valid insn. */ 134418334Speter 134590091Sobrienstatic void 1346169702Skaninstantiate_virtual_regs_in_insn (rtx insn) 134790091Sobrien{ 1348169702Skan HOST_WIDE_INT offset; 1349169702Skan int insn_code, i; 1350169702Skan bool any_change = false; 1351169702Skan rtx set, new, x, seq; 135218334Speter 1353169702Skan /* There are some special cases to be handled first. */ 1354169702Skan set = single_set (insn); 1355169702Skan if (set) 135690091Sobrien { 1357169702Skan /* We're allowed to assign to a virtual register. This is interpreted 1358169702Skan to mean that the underlying register gets assigned the inverse 1359169702Skan transformation. This is used, for example, in the handling of 1360169702Skan non-local gotos. */ 1361169702Skan new = instantiate_new_reg (SET_DEST (set), &offset); 1362169702Skan if (new) 136390091Sobrien { 1364169702Skan start_sequence (); 136518334Speter 1366169702Skan for_each_rtx (&SET_SRC (set), instantiate_virtual_regs_in_rtx, NULL); 1367169702Skan x = simplify_gen_binary (PLUS, GET_MODE (new), SET_SRC (set), 1368169702Skan GEN_INT (-offset)); 1369169702Skan x = force_operand (x, new); 1370169702Skan if (x != new) 1371169702Skan emit_move_insn (new, x); 137290091Sobrien 1373169702Skan seq = get_insns (); 1374169702Skan end_sequence (); 137590091Sobrien 1376169702Skan emit_insn_before (seq, insn); 1377169702Skan delete_insn (insn); 1378169702Skan return; 137918334Speter } 138052518Sobrien 1381169702Skan /* Handle a straight copy from a virtual register by generating a 1382169702Skan new add insn. The difference between this and falling through 1383169702Skan to the generic case is avoiding a new pseudo and eliminating a 1384169702Skan move insn in the initial rtl stream. */ 1385169702Skan new = instantiate_new_reg (SET_SRC (set), &offset); 1386169702Skan if (new && offset != 0 1387169702Skan && REG_P (SET_DEST (set)) 1388169702Skan && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER) 138952518Sobrien { 1390169702Skan start_sequence (); 139190091Sobrien 1392169702Skan x = expand_simple_binop (GET_MODE (SET_DEST (set)), PLUS, 1393169702Skan new, GEN_INT (offset), SET_DEST (set), 1394169702Skan 1, OPTAB_LIB_WIDEN); 1395169702Skan if (x != SET_DEST (set)) 1396169702Skan emit_move_insn (SET_DEST (set), x); 139790091Sobrien 1398169702Skan seq = get_insns (); 1399169702Skan end_sequence (); 140090091Sobrien 1401169702Skan emit_insn_before (seq, insn); 1402169702Skan delete_insn (insn); 1403169702Skan return; 140452518Sobrien } 140590091Sobrien 1406169702Skan extract_insn (insn); 1407169702Skan insn_code = INSN_CODE (insn); 140818334Speter 1409169702Skan /* Handle a plus involving a virtual register by determining if the 1410169702Skan operands remain valid if they're modified in place. */ 1411169702Skan if (GET_CODE (SET_SRC (set)) == PLUS 1412169702Skan && recog_data.n_operands >= 3 1413169702Skan && recog_data.operand_loc[1] == &XEXP (SET_SRC (set), 0) 1414169702Skan && recog_data.operand_loc[2] == &XEXP (SET_SRC (set), 1) 1415169702Skan && GET_CODE (recog_data.operand[2]) == CONST_INT 1416169702Skan && (new = instantiate_new_reg (recog_data.operand[1], &offset))) 141752268Sobrien { 1418169702Skan offset += INTVAL (recog_data.operand[2]); 141952268Sobrien 1420169702Skan /* If the sum is zero, then replace with a plain move. */ 1421169702Skan if (offset == 0 1422169702Skan && REG_P (SET_DEST (set)) 1423169702Skan && REGNO (SET_DEST (set)) > LAST_VIRTUAL_REGISTER) 142452268Sobrien { 142552518Sobrien start_sequence (); 1426169702Skan emit_move_insn (SET_DEST (set), new); 1427117404Skan seq = get_insns (); 142852518Sobrien end_sequence (); 142952518Sobrien 143052518Sobrien emit_insn_before (seq, insn); 1431169702Skan delete_insn (insn); 1432169702Skan return; 143352268Sobrien } 143452268Sobrien 1435169702Skan x = gen_int_mode (offset, recog_data.operand_mode[2]); 143618334Speter 1437169702Skan /* Using validate_change and apply_change_group here leaves 1438169702Skan recog_data in an invalid state. Since we know exactly what 1439169702Skan we want to check, do those two by hand. */ 1440169702Skan if (safe_insn_predicate (insn_code, 1, new) 1441169702Skan && safe_insn_predicate (insn_code, 2, x)) 144218334Speter { 1443169702Skan *recog_data.operand_loc[1] = recog_data.operand[1] = new; 1444169702Skan *recog_data.operand_loc[2] = recog_data.operand[2] = x; 1445169702Skan any_change = true; 1446169702Skan 1447169702Skan /* Fall through into the regular operand fixup loop in 1448169702Skan order to take care of operands other than 1 and 2. */ 144918334Speter } 145018334Speter } 1451169702Skan } 1452169702Skan else 1453169702Skan { 1454169702Skan extract_insn (insn); 1455169702Skan insn_code = INSN_CODE (insn); 1456169702Skan } 145718334Speter 1458169702Skan /* In the general case, we expect virtual registers to appear only in 1459169702Skan operands, and then only as either bare registers or inside memories. */ 1460169702Skan for (i = 0; i < recog_data.n_operands; ++i) 1461169702Skan { 1462169702Skan x = recog_data.operand[i]; 1463169702Skan switch (GET_CODE (x)) 146418334Speter { 1465169702Skan case MEM: 1466169702Skan { 1467169702Skan rtx addr = XEXP (x, 0); 1468169702Skan bool changed = false; 146918334Speter 1470169702Skan for_each_rtx (&addr, instantiate_virtual_regs_in_rtx, &changed); 1471169702Skan if (!changed) 1472169702Skan continue; 147318334Speter 1474169702Skan start_sequence (); 1475169702Skan x = replace_equiv_address (x, addr); 1476169702Skan seq = get_insns (); 1477169702Skan end_sequence (); 1478169702Skan if (seq) 1479169702Skan emit_insn_before (seq, insn); 1480169702Skan } 1481169702Skan break; 148218334Speter 1483169702Skan case REG: 1484169702Skan new = instantiate_new_reg (x, &offset); 1485169702Skan if (new == NULL) 1486169702Skan continue; 1487169702Skan if (offset == 0) 1488169702Skan x = new; 148952268Sobrien else 149018334Speter { 1491169702Skan start_sequence (); 149218334Speter 1493169702Skan /* Careful, special mode predicates may have stuff in 1494169702Skan insn_data[insn_code].operand[i].mode that isn't useful 1495169702Skan to us for computing a new value. */ 1496169702Skan /* ??? Recognize address_operand and/or "p" constraints 1497169702Skan to see if (plus new offset) is a valid before we put 1498169702Skan this through expand_simple_binop. */ 1499169702Skan x = expand_simple_binop (GET_MODE (x), PLUS, new, 1500169702Skan GEN_INT (offset), NULL_RTX, 1501169702Skan 1, OPTAB_LIB_WIDEN); 1502169702Skan seq = get_insns (); 1503169702Skan end_sequence (); 1504169702Skan emit_insn_before (seq, insn); 150518334Speter } 1506169702Skan break; 150718334Speter 1508169702Skan case SUBREG: 1509169702Skan new = instantiate_new_reg (SUBREG_REG (x), &offset); 1510169702Skan if (new == NULL) 1511169702Skan continue; 1512169702Skan if (offset != 0) 151318334Speter { 1514169702Skan start_sequence (); 1515169702Skan new = expand_simple_binop (GET_MODE (new), PLUS, new, 1516169702Skan GEN_INT (offset), NULL_RTX, 1517169702Skan 1, OPTAB_LIB_WIDEN); 1518169702Skan seq = get_insns (); 1519169702Skan end_sequence (); 1520169702Skan emit_insn_before (seq, insn); 152118334Speter } 1522169702Skan x = simplify_gen_subreg (recog_data.operand_mode[i], new, 1523169702Skan GET_MODE (new), SUBREG_BYTE (x)); 1524169702Skan break; 152518334Speter 1526169702Skan default: 1527169702Skan continue; 152818334Speter } 152918334Speter 1530169702Skan /* At this point, X contains the new value for the operand. 1531169702Skan Validate the new value vs the insn predicate. Note that 1532169702Skan asm insns will have insn_code -1 here. */ 1533169702Skan if (!safe_insn_predicate (insn_code, i, x)) 153452268Sobrien { 1535169702Skan start_sequence (); 1536169702Skan x = force_reg (insn_data[insn_code].operand[i].mode, x); 1537169702Skan seq = get_insns (); 1538169702Skan end_sequence (); 1539169702Skan if (seq) 1540169702Skan emit_insn_before (seq, insn); 154152268Sobrien } 154252268Sobrien 1543169702Skan *recog_data.operand_loc[i] = recog_data.operand[i] = x; 1544169702Skan any_change = true; 1545169702Skan } 154690091Sobrien 1547169702Skan if (any_change) 1548169702Skan { 1549169702Skan /* Propagate operand changes into the duplicates. */ 1550169702Skan for (i = 0; i < recog_data.n_dups; ++i) 1551169702Skan *recog_data.dup_loc[i] 1552169702Skan = recog_data.operand[(unsigned)recog_data.dup_num[i]]; 155318334Speter 1554169702Skan /* Force re-recognition of the instruction for validation. */ 1555169702Skan INSN_CODE (insn) = -1; 155618334Speter } 155718334Speter 1558169702Skan if (asm_noperands (PATTERN (insn)) >= 0) 155918334Speter { 1560169702Skan if (!check_asm_operands (PATTERN (insn))) 156118334Speter { 1562169702Skan error_for_asm (insn, "impossible constraint in %<asm%>"); 1563169702Skan delete_insn (insn); 156418334Speter } 156518334Speter } 1566169702Skan else 1567169702Skan { 1568169702Skan if (recog_memoized (insn) < 0) 1569169702Skan fatal_insn_not_found (insn); 1570169702Skan } 157118334Speter} 157218334Speter 1573169702Skan/* Subroutine of instantiate_decls. Given RTL representing a decl, 1574169702Skan do any instantiation required. */ 157596283Sobrien 1576169702Skanstatic void 1577169702Skaninstantiate_decl (rtx x) 157818334Speter{ 1579169702Skan rtx addr; 158018334Speter 1581169702Skan if (x == 0) 1582169702Skan return; 158318334Speter 1584169702Skan /* If this is a CONCAT, recurse for the pieces. */ 1585169702Skan if (GET_CODE (x) == CONCAT) 1586169702Skan { 1587169702Skan instantiate_decl (XEXP (x, 0)); 1588169702Skan instantiate_decl (XEXP (x, 1)); 1589169702Skan return; 1590169702Skan } 159196283Sobrien 1592169702Skan /* If this is not a MEM, no need to do anything. Similarly if the 1593169702Skan address is a constant or a register that is not a virtual register. */ 1594169702Skan if (!MEM_P (x)) 1595169702Skan return; 159690091Sobrien 1597169702Skan addr = XEXP (x, 0); 1598169702Skan if (CONSTANT_P (addr) 1599169702Skan || (REG_P (addr) 1600169702Skan && (REGNO (addr) < FIRST_VIRTUAL_REGISTER 1601169702Skan || REGNO (addr) > LAST_VIRTUAL_REGISTER))) 1602169702Skan return; 1603117404Skan 1604169702Skan for_each_rtx (&XEXP (x, 0), instantiate_virtual_regs_in_rtx, NULL); 160518334Speter} 160618334Speter 1607169702Skan/* Helper for instantiate_decls called via walk_tree: Process all decls 1608169702Skan in the given DECL_VALUE_EXPR. */ 160918334Speter 1610169702Skanstatic tree 1611169702Skaninstantiate_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 161218334Speter{ 1613169702Skan tree t = *tp; 1614169702Skan if (! EXPR_P (t)) 161518334Speter { 1616169702Skan *walk_subtrees = 0; 1617169702Skan if (DECL_P (t) && DECL_RTL_SET_P (t)) 1618169702Skan instantiate_decl (DECL_RTL (t)); 161918334Speter } 1620169702Skan return NULL; 162118334Speter} 162218334Speter 1623169702Skan/* Subroutine of instantiate_decls: Process all decls in the given 1624169702Skan BLOCK node and all its subblocks. */ 1625169702Skan 1626169702Skanstatic void 1627169702Skaninstantiate_decls_1 (tree let) 162818334Speter{ 1629169702Skan tree t; 163018334Speter 1631169702Skan for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t)) 163218334Speter { 1633169702Skan if (DECL_RTL_SET_P (t)) 1634169702Skan instantiate_decl (DECL_RTL (t)); 1635169702Skan if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t)) 163618334Speter { 1637169702Skan tree v = DECL_VALUE_EXPR (t); 1638169702Skan walk_tree (&v, instantiate_expr, NULL, NULL); 163918334Speter } 164018334Speter } 164118334Speter 1642169702Skan /* Process all subblocks. */ 1643169702Skan for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t)) 1644169702Skan instantiate_decls_1 (t); 164518334Speter} 164618334Speter 1647169702Skan/* Scan all decls in FNDECL (both variables and parameters) and instantiate 1648169702Skan all virtual registers in their DECL_RTL's. */ 164918334Speter 165018334Speterstatic void 1651169702Skaninstantiate_decls (tree fndecl) 165218334Speter{ 1653169702Skan tree decl; 165418334Speter 1655169702Skan /* Process all parameters of the function. */ 1656169702Skan for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl)) 165718334Speter { 1658169702Skan instantiate_decl (DECL_RTL (decl)); 1659169702Skan instantiate_decl (DECL_INCOMING_RTL (decl)); 1660169702Skan if (DECL_HAS_VALUE_EXPR_P (decl)) 166118334Speter { 1662169702Skan tree v = DECL_VALUE_EXPR (decl); 1663169702Skan walk_tree (&v, instantiate_expr, NULL, NULL); 1664169702Skan } 1665169702Skan } 166618334Speter 1667169702Skan /* Now process all variables defined in the function or its subblocks. */ 1668169702Skan instantiate_decls_1 (DECL_INITIAL (fndecl)); 1669169702Skan} 167018334Speter 1671169702Skan/* Pass through the INSNS of function FNDECL and convert virtual register 1672169702Skan references to hard register references. */ 167318334Speter 1674169702Skanstatic unsigned int 1675169702Skaninstantiate_virtual_regs (void) 1676169702Skan{ 1677169702Skan rtx insn; 167818334Speter 1679169702Skan /* Compute the offsets to use for this function. */ 1680169702Skan in_arg_offset = FIRST_PARM_OFFSET (current_function_decl); 1681169702Skan var_offset = STARTING_FRAME_OFFSET; 1682169702Skan dynamic_offset = STACK_DYNAMIC_OFFSET (current_function_decl); 1683169702Skan out_arg_offset = STACK_POINTER_OFFSET; 1684169702Skan#ifdef FRAME_POINTER_CFA_OFFSET 1685169702Skan cfa_offset = FRAME_POINTER_CFA_OFFSET (current_function_decl); 1686169702Skan#else 1687169702Skan cfa_offset = ARG_POINTER_CFA_OFFSET (current_function_decl); 1688169702Skan#endif 168918334Speter 1690169702Skan /* Initialize recognition, indicating that volatile is OK. */ 1691169702Skan init_recog (); 169218334Speter 1693169702Skan /* Scan through all the insns, instantiating every virtual register still 1694169702Skan present. */ 1695169702Skan for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 1696169702Skan if (INSN_P (insn)) 1697169702Skan { 1698169702Skan /* These patterns in the instruction stream can never be recognized. 1699169702Skan Fortunately, they shouldn't contain virtual registers either. */ 1700169702Skan if (GET_CODE (PATTERN (insn)) == USE 1701169702Skan || GET_CODE (PATTERN (insn)) == CLOBBER 1702169702Skan || GET_CODE (PATTERN (insn)) == ADDR_VEC 1703169702Skan || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC 1704169702Skan || GET_CODE (PATTERN (insn)) == ASM_INPUT) 1705169702Skan continue; 170618334Speter 1707169702Skan instantiate_virtual_regs_in_insn (insn); 170818334Speter 1709169702Skan if (INSN_DELETED_P (insn)) 1710169702Skan continue; 171118334Speter 1712169702Skan for_each_rtx (®_NOTES (insn), instantiate_virtual_regs_in_rtx, NULL); 171318334Speter 1714169702Skan /* Instantiate any virtual registers in CALL_INSN_FUNCTION_USAGE. */ 1715169702Skan if (GET_CODE (insn) == CALL_INSN) 1716169702Skan for_each_rtx (&CALL_INSN_FUNCTION_USAGE (insn), 1717169702Skan instantiate_virtual_regs_in_rtx, NULL); 1718169702Skan } 171918334Speter 1720169702Skan /* Instantiate the virtual registers in the DECLs for debugging purposes. */ 1721169702Skan instantiate_decls (current_function_decl); 172218334Speter 1723169702Skan /* Indicate that, from now on, assign_stack_local should use 1724169702Skan frame_pointer_rtx. */ 1725169702Skan virtuals_instantiated = 1; 1726169702Skan return 0; 1727169702Skan} 172818334Speter 1729169702Skanstruct tree_opt_pass pass_instantiate_virtual_regs = 1730169702Skan{ 1731169702Skan "vregs", /* name */ 1732169702Skan NULL, /* gate */ 1733169702Skan instantiate_virtual_regs, /* execute */ 1734169702Skan NULL, /* sub */ 1735169702Skan NULL, /* next */ 1736169702Skan 0, /* static_pass_number */ 1737169702Skan 0, /* tv_id */ 1738169702Skan 0, /* properties_required */ 1739169702Skan 0, /* properties_provided */ 1740169702Skan 0, /* properties_destroyed */ 1741169702Skan 0, /* todo_flags_start */ 1742169702Skan TODO_dump_func, /* todo_flags_finish */ 1743169702Skan 0 /* letter */ 1744169702Skan}; 174518334Speter 174618334Speter 1747169702Skan/* Return 1 if EXP is an aggregate type (or a value with aggregate type). 1748169702Skan This means a type for which function calls must pass an address to the 1749169702Skan function or get an address back from the function. 1750169702Skan EXP may be a type node or an expression (whose type is tested). */ 175118334Speter 1752169702Skanint 1753169702Skanaggregate_value_p (tree exp, tree fntype) 1754169702Skan{ 1755169702Skan int i, regno, nregs; 1756169702Skan rtx reg; 175718334Speter 1758169702Skan tree type = (TYPE_P (exp)) ? exp : TREE_TYPE (exp); 175918334Speter 1760169702Skan /* DECL node associated with FNTYPE when relevant, which we might need to 1761169702Skan check for by-invisible-reference returns, typically for CALL_EXPR input 1762169702Skan EXPressions. */ 1763169702Skan tree fndecl = NULL_TREE; 1764169702Skan 1765169702Skan if (fntype) 1766169702Skan switch (TREE_CODE (fntype)) 1767169702Skan { 1768169702Skan case CALL_EXPR: 1769169702Skan fndecl = get_callee_fndecl (fntype); 1770169702Skan fntype = fndecl ? TREE_TYPE (fndecl) : 0; 1771169702Skan break; 1772169702Skan case FUNCTION_DECL: 1773169702Skan fndecl = fntype; 1774169702Skan fntype = TREE_TYPE (fndecl); 1775169702Skan break; 1776169702Skan case FUNCTION_TYPE: 1777169702Skan case METHOD_TYPE: 1778169702Skan break; 1779169702Skan case IDENTIFIER_NODE: 1780169702Skan fntype = 0; 1781169702Skan break; 1782169702Skan default: 1783169702Skan /* We don't expect other rtl types here. */ 1784169702Skan gcc_unreachable (); 1785169702Skan } 178618334Speter 1787169702Skan if (TREE_CODE (type) == VOID_TYPE) 1788169702Skan return 0; 178918334Speter 1790169702Skan /* If the front end has decided that this needs to be passed by 1791169702Skan reference, do so. */ 1792169702Skan if ((TREE_CODE (exp) == PARM_DECL || TREE_CODE (exp) == RESULT_DECL) 1793169702Skan && DECL_BY_REFERENCE (exp)) 1794169702Skan return 1; 179518334Speter 1796169702Skan /* If the EXPression is a CALL_EXPR, honor DECL_BY_REFERENCE set on the 1797169702Skan called function RESULT_DECL, meaning the function returns in memory by 1798169702Skan invisible reference. This check lets front-ends not set TREE_ADDRESSABLE 1799169702Skan on the function type, which used to be the way to request such a return 1800169702Skan mechanism but might now be causing troubles at gimplification time if 1801169702Skan temporaries with the function type need to be created. */ 1802169702Skan if (TREE_CODE (exp) == CALL_EXPR && fndecl && DECL_RESULT (fndecl) 1803169702Skan && DECL_BY_REFERENCE (DECL_RESULT (fndecl))) 1804169702Skan return 1; 1805169702Skan 1806169702Skan if (targetm.calls.return_in_memory (type, fntype)) 1807169702Skan return 1; 1808169702Skan /* Types that are TREE_ADDRESSABLE must be constructed in memory, 1809169702Skan and thus can't be returned in registers. */ 1810169702Skan if (TREE_ADDRESSABLE (type)) 1811169702Skan return 1; 1812169702Skan if (flag_pcc_struct_return && AGGREGATE_TYPE_P (type)) 1813169702Skan return 1; 1814169702Skan /* Make sure we have suitable call-clobbered regs to return 1815169702Skan the value in; if not, we must return it in memory. */ 1816169702Skan reg = hard_function_value (type, 0, fntype, 0); 181718334Speter 1818169702Skan /* If we have something other than a REG (e.g. a PARALLEL), then assume 1819169702Skan it is OK. */ 1820169702Skan if (!REG_P (reg)) 1821169702Skan return 0; 182218334Speter 1823169702Skan regno = REGNO (reg); 1824169702Skan nregs = hard_regno_nregs[regno][TYPE_MODE (type)]; 1825169702Skan for (i = 0; i < nregs; i++) 1826169702Skan if (! call_used_regs[regno + i]) 1827169702Skan return 1; 1828169702Skan return 0; 1829169702Skan} 1830169702Skan 1831169702Skan/* Return true if we should assign DECL a pseudo register; false if it 1832169702Skan should live on the local stack. */ 183318334Speter 1834169702Skanbool 1835169702Skanuse_register_for_decl (tree decl) 183652268Sobrien{ 1837169702Skan /* Honor volatile. */ 1838169702Skan if (TREE_SIDE_EFFECTS (decl)) 1839169702Skan return false; 184090091Sobrien 1841169702Skan /* Honor addressability. */ 1842169702Skan if (TREE_ADDRESSABLE (decl)) 1843169702Skan return false; 184490091Sobrien 1845169702Skan /* Only register-like things go in registers. */ 1846169702Skan if (DECL_MODE (decl) == BLKmode) 1847169702Skan return false; 184852268Sobrien 1849169702Skan /* If -ffloat-store specified, don't put explicit float variables 1850169702Skan into registers. */ 1851169702Skan /* ??? This should be checked after DECL_ARTIFICIAL, but tree-ssa 1852169702Skan propagates values across these stores, and it probably shouldn't. */ 1853169702Skan if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (decl))) 1854169702Skan return false; 185552268Sobrien 1856169702Skan /* If we're not interested in tracking debugging information for 1857169702Skan this decl, then we can certainly put it in a register. */ 1858169702Skan if (DECL_IGNORED_P (decl)) 1859169702Skan return true; 186052268Sobrien 1861169702Skan return (optimize || DECL_REGISTER (decl)); 1862169702Skan} 186390091Sobrien 1864169702Skan/* Return true if TYPE should be passed by invisible reference. */ 186590091Sobrien 1866169702Skanbool 1867169702Skanpass_by_reference (CUMULATIVE_ARGS *ca, enum machine_mode mode, 1868169702Skan tree type, bool named_arg) 1869169702Skan{ 1870169702Skan if (type) 1871132732Skan { 1872169702Skan /* If this type contains non-trivial constructors, then it is 1873169702Skan forbidden for the middle-end to create any new copies. */ 1874169702Skan if (TREE_ADDRESSABLE (type)) 1875169702Skan return true; 187690091Sobrien 1877169702Skan /* GCC post 3.4 passes *all* variable sized types by reference. */ 1878169702Skan if (!TYPE_SIZE (type) || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 1879169702Skan return true; 1880132732Skan } 1881132732Skan 1882169702Skan return targetm.calls.pass_by_reference (ca, mode, type, named_arg); 188352268Sobrien} 188452268Sobrien 1885169702Skan/* Return true if TYPE, which is passed by reference, should be callee 1886169702Skan copied instead of caller copied. */ 188752268Sobrien 1888169702Skanbool 1889169702Skanreference_callee_copied (CUMULATIVE_ARGS *ca, enum machine_mode mode, 1890169702Skan tree type, bool named_arg) 189152268Sobrien{ 1892169702Skan if (type && TREE_ADDRESSABLE (type)) 1893169702Skan return false; 1894169702Skan return targetm.calls.callee_copies (ca, mode, type, named_arg); 189552268Sobrien} 189652268Sobrien 1897169702Skan/* Structures to communicate between the subroutines of assign_parms. 1898169702Skan The first holds data persistent across all parameters, the second 1899169702Skan is cleared out for each parameter. */ 190052268Sobrien 1901169702Skanstruct assign_parm_data_all 1902169702Skan{ 1903169702Skan CUMULATIVE_ARGS args_so_far; 1904169702Skan struct args_size stack_args_size; 1905169702Skan tree function_result_decl; 1906169702Skan tree orig_fnargs; 1907169702Skan rtx conversion_insns; 1908169702Skan HOST_WIDE_INT pretend_args_size; 1909169702Skan HOST_WIDE_INT extra_pretend_bytes; 1910169702Skan int reg_parm_stack_space; 1911169702Skan}; 1912169702Skan 1913169702Skanstruct assign_parm_data_one 1914169702Skan{ 1915169702Skan tree nominal_type; 1916169702Skan tree passed_type; 1917169702Skan rtx entry_parm; 1918169702Skan rtx stack_parm; 1919169702Skan enum machine_mode nominal_mode; 1920169702Skan enum machine_mode passed_mode; 1921169702Skan enum machine_mode promoted_mode; 1922169702Skan struct locate_and_pad_arg_data locate; 1923169702Skan int partial; 1924169702Skan BOOL_BITFIELD named_arg : 1; 1925169702Skan BOOL_BITFIELD passed_pointer : 1; 1926169702Skan BOOL_BITFIELD on_stack : 1; 1927169702Skan BOOL_BITFIELD loaded_in_reg : 1; 1928169702Skan}; 1929169702Skan 1930169702Skan/* A subroutine of assign_parms. Initialize ALL. */ 1931169702Skan 193252268Sobrienstatic void 1933169702Skanassign_parms_initialize_all (struct assign_parm_data_all *all) 193452268Sobrien{ 1935169702Skan tree fntype; 193690091Sobrien 1937169702Skan memset (all, 0, sizeof (*all)); 193852268Sobrien 1939169702Skan fntype = TREE_TYPE (current_function_decl); 194052268Sobrien 1941169702Skan#ifdef INIT_CUMULATIVE_INCOMING_ARGS 1942169702Skan INIT_CUMULATIVE_INCOMING_ARGS (all->args_so_far, fntype, NULL_RTX); 1943169702Skan#else 1944169702Skan INIT_CUMULATIVE_ARGS (all->args_so_far, fntype, NULL_RTX, 1945169702Skan current_function_decl, -1); 1946169702Skan#endif 194790091Sobrien 1948169702Skan#ifdef REG_PARM_STACK_SPACE 1949169702Skan all->reg_parm_stack_space = REG_PARM_STACK_SPACE (current_function_decl); 1950169702Skan#endif 195152268Sobrien} 195252268Sobrien 1953169702Skan/* If ARGS contains entries with complex types, split the entry into two 1954169702Skan entries of the component type. Return a new list of substitutions are 1955169702Skan needed, else the old list. */ 195652518Sobrien 1957169702Skanstatic tree 1958169702Skansplit_complex_args (tree args) 195952268Sobrien{ 1960169702Skan tree p; 196152268Sobrien 1962169702Skan /* Before allocating memory, check for the common case of no complex. */ 1963169702Skan for (p = args; p; p = TREE_CHAIN (p)) 196452268Sobrien { 1965169702Skan tree type = TREE_TYPE (p); 1966169702Skan if (TREE_CODE (type) == COMPLEX_TYPE 1967169702Skan && targetm.calls.split_complex_arg (type)) 1968169702Skan goto found; 196990091Sobrien } 1970169702Skan return args; 197190091Sobrien 1972169702Skan found: 1973169702Skan args = copy_list (args); 1974117404Skan 1975169702Skan for (p = args; p; p = TREE_CHAIN (p)) 197652268Sobrien { 1977169702Skan tree type = TREE_TYPE (p); 1978169702Skan if (TREE_CODE (type) == COMPLEX_TYPE 1979169702Skan && targetm.calls.split_complex_arg (type)) 198052268Sobrien { 1981169702Skan tree decl; 1982169702Skan tree subtype = TREE_TYPE (type); 1983169702Skan bool addressable = TREE_ADDRESSABLE (p); 198452518Sobrien 1985169702Skan /* Rewrite the PARM_DECL's type with its component. */ 1986169702Skan TREE_TYPE (p) = subtype; 1987169702Skan DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p)); 1988169702Skan DECL_MODE (p) = VOIDmode; 1989169702Skan DECL_SIZE (p) = NULL; 1990169702Skan DECL_SIZE_UNIT (p) = NULL; 1991169702Skan /* If this arg must go in memory, put it in a pseudo here. 1992169702Skan We can't allow it to go in memory as per normal parms, 1993169702Skan because the usual place might not have the imag part 1994169702Skan adjacent to the real part. */ 1995169702Skan DECL_ARTIFICIAL (p) = addressable; 1996169702Skan DECL_IGNORED_P (p) = addressable; 1997169702Skan TREE_ADDRESSABLE (p) = 0; 1998169702Skan layout_decl (p, 0); 1999132732Skan 2000169702Skan /* Build a second synthetic decl. */ 2001169702Skan decl = build_decl (PARM_DECL, NULL_TREE, subtype); 2002169702Skan DECL_ARG_TYPE (decl) = DECL_ARG_TYPE (p); 2003169702Skan DECL_ARTIFICIAL (decl) = addressable; 2004169702Skan DECL_IGNORED_P (decl) = addressable; 2005169702Skan layout_decl (decl, 0); 200652518Sobrien 2007169702Skan /* Splice it in; skip the new decl. */ 2008169702Skan TREE_CHAIN (decl) = TREE_CHAIN (p); 2009169702Skan TREE_CHAIN (p) = decl; 2010169702Skan p = decl; 2011169702Skan } 2012169702Skan } 201352518Sobrien 2014169702Skan return args; 2015169702Skan} 201652518Sobrien 2017169702Skan/* A subroutine of assign_parms. Adjust the parameter list to incorporate 2018169702Skan the hidden struct return argument, and (abi willing) complex args. 2019169702Skan Return the new parameter list. */ 202052518Sobrien 2021169702Skanstatic tree 2022169702Skanassign_parms_augmented_arg_list (struct assign_parm_data_all *all) 2023169702Skan{ 2024169702Skan tree fndecl = current_function_decl; 2025169702Skan tree fntype = TREE_TYPE (fndecl); 2026169702Skan tree fnargs = DECL_ARGUMENTS (fndecl); 202752518Sobrien 2028169702Skan /* If struct value address is treated as the first argument, make it so. */ 2029169702Skan if (aggregate_value_p (DECL_RESULT (fndecl), fndecl) 2030169702Skan && ! current_function_returns_pcc_struct 2031169702Skan && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0) 2032169702Skan { 2033169702Skan tree type = build_pointer_type (TREE_TYPE (fntype)); 2034169702Skan tree decl; 203590091Sobrien 2036169702Skan decl = build_decl (PARM_DECL, NULL_TREE, type); 2037169702Skan DECL_ARG_TYPE (decl) = type; 2038169702Skan DECL_ARTIFICIAL (decl) = 1; 2039169702Skan DECL_IGNORED_P (decl) = 1; 204052518Sobrien 2041169702Skan TREE_CHAIN (decl) = fnargs; 2042169702Skan fnargs = decl; 2043169702Skan all->function_result_decl = decl; 2044169702Skan } 204552518Sobrien 2046169702Skan all->orig_fnargs = fnargs; 2047132732Skan 2048169702Skan /* If the target wants to split complex arguments into scalars, do so. */ 2049169702Skan if (targetm.calls.split_complex_arg) 2050169702Skan fnargs = split_complex_args (fnargs); 2051132732Skan 2052169702Skan return fnargs; 2053169702Skan} 205452518Sobrien 2055169702Skan/* A subroutine of assign_parms. Examine PARM and pull out type and mode 2056169702Skan data for the parameter. Incorporate ABI specifics such as pass-by- 2057169702Skan reference and type promotion. */ 205852518Sobrien 2059169702Skanstatic void 2060169702Skanassign_parm_find_data_types (struct assign_parm_data_all *all, tree parm, 2061169702Skan struct assign_parm_data_one *data) 2062169702Skan{ 2063169702Skan tree nominal_type, passed_type; 2064169702Skan enum machine_mode nominal_mode, passed_mode, promoted_mode; 2065117404Skan 2066169702Skan memset (data, 0, sizeof (*data)); 206752518Sobrien 2068169702Skan /* NAMED_ARG is a mis-nomer. We really mean 'non-varadic'. */ 2069169702Skan if (!current_function_stdarg) 2070169702Skan data->named_arg = 1; /* No varadic parms. */ 2071169702Skan else if (TREE_CHAIN (parm)) 2072169702Skan data->named_arg = 1; /* Not the last non-varadic parm. */ 2073169702Skan else if (targetm.calls.strict_argument_naming (&all->args_so_far)) 2074169702Skan data->named_arg = 1; /* Only varadic ones are unnamed. */ 2075169702Skan else 2076169702Skan data->named_arg = 0; /* Treat as varadic. */ 207752518Sobrien 2078169702Skan nominal_type = TREE_TYPE (parm); 2079169702Skan passed_type = DECL_ARG_TYPE (parm); 208052518Sobrien 2081169702Skan /* Look out for errors propagating this far. Also, if the parameter's 2082169702Skan type is void then its value doesn't matter. */ 2083169702Skan if (TREE_TYPE (parm) == error_mark_node 2084169702Skan /* This can happen after weird syntax errors 2085169702Skan or if an enum type is defined among the parms. */ 2086169702Skan || TREE_CODE (parm) != PARM_DECL 2087169702Skan || passed_type == NULL 2088169702Skan || VOID_TYPE_P (nominal_type)) 2089169702Skan { 2090169702Skan nominal_type = passed_type = void_type_node; 2091169702Skan nominal_mode = passed_mode = promoted_mode = VOIDmode; 2092169702Skan goto egress; 2093169702Skan } 209490091Sobrien 2095169702Skan /* Find mode of arg as it is passed, and mode of arg as it should be 2096169702Skan during execution of this function. */ 2097169702Skan passed_mode = TYPE_MODE (passed_type); 2098169702Skan nominal_mode = TYPE_MODE (nominal_type); 209952518Sobrien 2100169702Skan /* If the parm is to be passed as a transparent union, use the type of 2101169702Skan the first field for the tests below. We have already verified that 2102169702Skan the modes are the same. */ 2103169702Skan if (TREE_CODE (passed_type) == UNION_TYPE 2104169702Skan && TYPE_TRANSPARENT_UNION (passed_type)) 2105169702Skan passed_type = TREE_TYPE (TYPE_FIELDS (passed_type)); 210652518Sobrien 2107169702Skan /* See if this arg was passed by invisible reference. */ 2108169702Skan if (pass_by_reference (&all->args_so_far, passed_mode, 2109169702Skan passed_type, data->named_arg)) 2110169702Skan { 2111169702Skan passed_type = nominal_type = build_pointer_type (passed_type); 2112169702Skan data->passed_pointer = true; 2113169702Skan passed_mode = nominal_mode = Pmode; 211452268Sobrien } 211552268Sobrien 2116169702Skan /* Find mode as it is passed by the ABI. */ 2117169702Skan promoted_mode = passed_mode; 2118169702Skan if (targetm.calls.promote_function_args (TREE_TYPE (current_function_decl))) 211952268Sobrien { 2120169702Skan int unsignedp = TYPE_UNSIGNED (passed_type); 2121169702Skan promoted_mode = promote_mode (passed_type, promoted_mode, 2122169702Skan &unsignedp, 1); 212352268Sobrien } 212490091Sobrien 2125169702Skan egress: 2126169702Skan data->nominal_type = nominal_type; 2127169702Skan data->passed_type = passed_type; 2128169702Skan data->nominal_mode = nominal_mode; 2129169702Skan data->passed_mode = passed_mode; 2130169702Skan data->promoted_mode = promoted_mode; 213152268Sobrien} 213252268Sobrien 2133169702Skan/* A subroutine of assign_parms. Invoke setup_incoming_varargs. */ 213452518Sobrien 2135169702Skanstatic void 2136169702Skanassign_parms_setup_varargs (struct assign_parm_data_all *all, 2137169702Skan struct assign_parm_data_one *data, bool no_rtl) 213852518Sobrien{ 2139169702Skan int varargs_pretend_bytes = 0; 214052518Sobrien 2141169702Skan targetm.calls.setup_incoming_varargs (&all->args_so_far, 2142169702Skan data->promoted_mode, 2143169702Skan data->passed_type, 2144169702Skan &varargs_pretend_bytes, no_rtl); 214552518Sobrien 2146169702Skan /* If the back-end has requested extra stack space, record how much is 2147169702Skan needed. Do not change pretend_args_size otherwise since it may be 2148169702Skan nonzero from an earlier partial argument. */ 2149169702Skan if (varargs_pretend_bytes > 0) 2150169702Skan all->pretend_args_size = varargs_pretend_bytes; 215152518Sobrien} 215252518Sobrien 2153169702Skan/* A subroutine of assign_parms. Set DATA->ENTRY_PARM corresponding to 2154169702Skan the incoming location of the current parameter. */ 2155169702Skan 2156169702Skanstatic void 2157169702Skanassign_parm_find_entry_rtl (struct assign_parm_data_all *all, 2158169702Skan struct assign_parm_data_one *data) 215990091Sobrien{ 2160169702Skan HOST_WIDE_INT pretend_bytes = 0; 2161169702Skan rtx entry_parm; 2162169702Skan bool in_regs; 216352518Sobrien 2164169702Skan if (data->promoted_mode == VOIDmode) 2165169702Skan { 2166169702Skan data->entry_parm = data->stack_parm = const0_rtx; 2167169702Skan return; 2168169702Skan } 216952518Sobrien 2170169702Skan#ifdef FUNCTION_INCOMING_ARG 2171169702Skan entry_parm = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode, 2172169702Skan data->passed_type, data->named_arg); 2173169702Skan#else 2174169702Skan entry_parm = FUNCTION_ARG (all->args_so_far, data->promoted_mode, 2175169702Skan data->passed_type, data->named_arg); 2176169702Skan#endif 217752518Sobrien 2178169702Skan if (entry_parm == 0) 2179169702Skan data->promoted_mode = data->passed_mode; 218052518Sobrien 2181169702Skan /* Determine parm's home in the stack, in case it arrives in the stack 2182169702Skan or we should pretend it did. Compute the stack position and rtx where 2183169702Skan the argument arrives and its size. 218452518Sobrien 2185169702Skan There is one complexity here: If this was a parameter that would 2186169702Skan have been passed in registers, but wasn't only because it is 2187169702Skan __builtin_va_alist, we want locate_and_pad_parm to treat it as if 2188169702Skan it came in a register so that REG_PARM_STACK_SPACE isn't skipped. 2189169702Skan In this case, we call FUNCTION_ARG with NAMED set to 1 instead of 0 2190169702Skan as it was the previous time. */ 2191169702Skan in_regs = entry_parm != 0; 2192169702Skan#ifdef STACK_PARMS_IN_REG_PARM_AREA 2193169702Skan in_regs = true; 2194169702Skan#endif 2195169702Skan if (!in_regs && !data->named_arg) 2196117404Skan { 2197169702Skan if (targetm.calls.pretend_outgoing_varargs_named (&all->args_so_far)) 2198117404Skan { 2199169702Skan rtx tem; 2200169702Skan#ifdef FUNCTION_INCOMING_ARG 2201169702Skan tem = FUNCTION_INCOMING_ARG (all->args_so_far, data->promoted_mode, 2202169702Skan data->passed_type, true); 2203169702Skan#else 2204169702Skan tem = FUNCTION_ARG (all->args_so_far, data->promoted_mode, 2205169702Skan data->passed_type, true); 2206169702Skan#endif 2207169702Skan in_regs = tem != NULL; 2208117404Skan } 2209117404Skan } 221052518Sobrien 2211169702Skan /* If this parameter was passed both in registers and in the stack, use 2212169702Skan the copy on the stack. */ 2213169702Skan if (targetm.calls.must_pass_in_stack (data->promoted_mode, 2214169702Skan data->passed_type)) 2215169702Skan entry_parm = 0; 221652518Sobrien 2217169702Skan if (entry_parm) 2218169702Skan { 2219169702Skan int partial; 222052518Sobrien 2221169702Skan partial = targetm.calls.arg_partial_bytes (&all->args_so_far, 2222169702Skan data->promoted_mode, 2223169702Skan data->passed_type, 2224169702Skan data->named_arg); 2225169702Skan data->partial = partial; 222652518Sobrien 2227169702Skan /* The caller might already have allocated stack space for the 2228169702Skan register parameters. */ 2229169702Skan if (partial != 0 && all->reg_parm_stack_space == 0) 223052518Sobrien { 2231169702Skan /* Part of this argument is passed in registers and part 2232169702Skan is passed on the stack. Ask the prologue code to extend 2233169702Skan the stack part so that we can recreate the full value. 223452518Sobrien 2235169702Skan PRETEND_BYTES is the size of the registers we need to store. 2236169702Skan CURRENT_FUNCTION_PRETEND_ARGS_SIZE is the amount of extra 2237169702Skan stack space that the prologue should allocate. 223890091Sobrien 2239169702Skan Internally, gcc assumes that the argument pointer is aligned 2240169702Skan to STACK_BOUNDARY bits. This is used both for alignment 2241169702Skan optimizations (see init_emit) and to locate arguments that are 2242169702Skan aligned to more than PARM_BOUNDARY bits. We must preserve this 2243169702Skan invariant by rounding CURRENT_FUNCTION_PRETEND_ARGS_SIZE up to 2244169702Skan a stack boundary. */ 224590091Sobrien 2246169702Skan /* We assume at most one partial arg, and it must be the first 2247169702Skan argument on the stack. */ 2248169702Skan gcc_assert (!all->extra_pretend_bytes && !all->pretend_args_size); 224952268Sobrien 2250169702Skan pretend_bytes = partial; 2251169702Skan all->pretend_args_size = CEIL_ROUND (pretend_bytes, STACK_BYTES); 225290091Sobrien 2253169702Skan /* We want to align relative to the actual stack pointer, so 2254169702Skan don't include this in the stack size until later. */ 2255169702Skan all->extra_pretend_bytes = all->pretend_args_size; 2256169702Skan } 2257169702Skan } 225852518Sobrien 2259169702Skan locate_and_pad_parm (data->promoted_mode, data->passed_type, in_regs, 2260169702Skan entry_parm ? data->partial : 0, current_function_decl, 2261169702Skan &all->stack_args_size, &data->locate); 2262132732Skan 2263169702Skan /* Adjust offsets to include the pretend args. */ 2264169702Skan pretend_bytes = all->extra_pretend_bytes - pretend_bytes; 2265169702Skan data->locate.slot_offset.constant += pretend_bytes; 2266169702Skan data->locate.offset.constant += pretend_bytes; 226790091Sobrien 2268169702Skan data->entry_parm = entry_parm; 2269169702Skan} 227090091Sobrien 2271169702Skan/* A subroutine of assign_parms. If there is actually space on the stack 2272169702Skan for this parm, count it in stack_args_size and return true. */ 227352518Sobrien 2274169702Skanstatic bool 2275169702Skanassign_parm_is_stack_parm (struct assign_parm_data_all *all, 2276169702Skan struct assign_parm_data_one *data) 2277169702Skan{ 2278169702Skan /* Trivially true if we've no incoming register. */ 2279169702Skan if (data->entry_parm == NULL) 2280169702Skan ; 2281169702Skan /* Also true if we're partially in registers and partially not, 2282169702Skan since we've arranged to drop the entire argument on the stack. */ 2283169702Skan else if (data->partial != 0) 2284169702Skan ; 2285169702Skan /* Also true if the target says that it's passed in both registers 2286169702Skan and on the stack. */ 2287169702Skan else if (GET_CODE (data->entry_parm) == PARALLEL 2288169702Skan && XEXP (XVECEXP (data->entry_parm, 0, 0), 0) == NULL_RTX) 2289169702Skan ; 2290169702Skan /* Also true if the target says that there's stack allocated for 2291169702Skan all register parameters. */ 2292169702Skan else if (all->reg_parm_stack_space > 0) 2293169702Skan ; 2294169702Skan /* Otherwise, no, this parameter has no ABI defined stack slot. */ 2295169702Skan else 2296169702Skan return false; 2297132732Skan 2298169702Skan all->stack_args_size.constant += data->locate.size.constant; 2299169702Skan if (data->locate.size.var) 2300169702Skan ADD_PARM_SIZE (all->stack_args_size, data->locate.size.var); 2301132732Skan 2302169702Skan return true; 2303169702Skan} 230472564Sobrien 2305169702Skan/* A subroutine of assign_parms. Given that this parameter is allocated 2306169702Skan stack space by the ABI, find it. */ 230772564Sobrien 2308169702Skanstatic void 2309169702Skanassign_parm_find_stack_rtl (tree parm, struct assign_parm_data_one *data) 2310169702Skan{ 2311169702Skan rtx offset_rtx, stack_parm; 2312169702Skan unsigned int align, boundary; 231372564Sobrien 2314169702Skan /* If we're passing this arg using a reg, make its stack home the 2315169702Skan aligned stack slot. */ 2316169702Skan if (data->entry_parm) 2317169702Skan offset_rtx = ARGS_SIZE_RTX (data->locate.slot_offset); 2318169702Skan else 2319169702Skan offset_rtx = ARGS_SIZE_RTX (data->locate.offset); 232072564Sobrien 2321169702Skan stack_parm = current_function_internal_arg_pointer; 2322169702Skan if (offset_rtx != const0_rtx) 2323169702Skan stack_parm = gen_rtx_PLUS (Pmode, stack_parm, offset_rtx); 2324169702Skan stack_parm = gen_rtx_MEM (data->promoted_mode, stack_parm); 232590091Sobrien 2326169702Skan set_mem_attributes (stack_parm, parm, 1); 232790091Sobrien 2328169702Skan boundary = data->locate.boundary; 2329169702Skan align = BITS_PER_UNIT; 2330169702Skan 2331169702Skan /* If we're padding upward, we know that the alignment of the slot 2332169702Skan is FUNCTION_ARG_BOUNDARY. If we're using slot_offset, we're 2333169702Skan intentionally forcing upward padding. Otherwise we have to come 2334169702Skan up with a guess at the alignment based on OFFSET_RTX. */ 2335169702Skan if (data->locate.where_pad != downward || data->entry_parm) 2336169702Skan align = boundary; 2337169702Skan else if (GET_CODE (offset_rtx) == CONST_INT) 233890091Sobrien { 2339169702Skan align = INTVAL (offset_rtx) * BITS_PER_UNIT | boundary; 2340169702Skan align = align & -align; 234190091Sobrien } 2342169702Skan set_mem_align (stack_parm, align); 234390091Sobrien 2344169702Skan if (data->entry_parm) 2345169702Skan set_reg_attrs_for_parm (data->entry_parm, stack_parm); 2346117404Skan 2347169702Skan data->stack_parm = stack_parm; 234890091Sobrien} 234990091Sobrien 2350169702Skan/* A subroutine of assign_parms. Adjust DATA->ENTRY_RTL such that it's 2351169702Skan always valid and contiguous. */ 235290091Sobrien 2353169702Skanstatic void 2354169702Skanassign_parm_adjust_entry_rtl (struct assign_parm_data_one *data) 2355169702Skan{ 2356169702Skan rtx entry_parm = data->entry_parm; 2357169702Skan rtx stack_parm = data->stack_parm; 235890091Sobrien 2359169702Skan /* If this parm was passed part in regs and part in memory, pretend it 2360169702Skan arrived entirely in memory by pushing the register-part onto the stack. 2361169702Skan In the special case of a DImode or DFmode that is split, we could put 2362169702Skan it together in a pseudoreg directly, but for now that's not worth 2363169702Skan bothering with. */ 2364169702Skan if (data->partial != 0) 236590091Sobrien { 2366169702Skan /* Handle calls that pass values in multiple non-contiguous 2367169702Skan locations. The Irix 6 ABI has examples of this. */ 2368169702Skan if (GET_CODE (entry_parm) == PARALLEL) 2369169702Skan emit_group_store (validize_mem (stack_parm), entry_parm, 2370169702Skan data->passed_type, 2371169702Skan int_size_in_bytes (data->passed_type)); 2372169702Skan else 237390091Sobrien { 2374169702Skan gcc_assert (data->partial % UNITS_PER_WORD == 0); 2375169702Skan move_block_from_reg (REGNO (entry_parm), validize_mem (stack_parm), 2376169702Skan data->partial / UNITS_PER_WORD); 237790091Sobrien } 2378169702Skan 2379169702Skan entry_parm = stack_parm; 238090091Sobrien } 238118334Speter 2382169702Skan /* If we didn't decide this parm came in a register, by default it came 2383169702Skan on the stack. */ 2384169702Skan else if (entry_parm == NULL) 2385169702Skan entry_parm = stack_parm; 238618334Speter 2387169702Skan /* When an argument is passed in multiple locations, we can't make use 2388169702Skan of this information, but we can save some copying if the whole argument 2389169702Skan is passed in a single register. */ 2390169702Skan else if (GET_CODE (entry_parm) == PARALLEL 2391169702Skan && data->nominal_mode != BLKmode 2392169702Skan && data->passed_mode != BLKmode) 2393169702Skan { 2394169702Skan size_t i, len = XVECLEN (entry_parm, 0); 239518334Speter 2396169702Skan for (i = 0; i < len; i++) 2397169702Skan if (XEXP (XVECEXP (entry_parm, 0, i), 0) != NULL_RTX 2398169702Skan && REG_P (XEXP (XVECEXP (entry_parm, 0, i), 0)) 2399169702Skan && (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0)) 2400169702Skan == data->passed_mode) 2401169702Skan && INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0) 2402169702Skan { 2403169702Skan entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0); 2404169702Skan break; 2405169702Skan } 2406169702Skan } 240718334Speter 2408169702Skan data->entry_parm = entry_parm; 240918334Speter} 241018334Speter 2411169702Skan/* A subroutine of assign_parms. Adjust DATA->STACK_RTL such that it's 2412169702Skan always valid and properly aligned. */ 241318334Speter 241418334Speterstatic void 2415169702Skanassign_parm_adjust_stack_rtl (struct assign_parm_data_one *data) 241618334Speter{ 2417169702Skan rtx stack_parm = data->stack_parm; 241818334Speter 2419169702Skan /* If we can't trust the parm stack slot to be aligned enough for its 2420169702Skan ultimate type, don't use that slot after entry. We'll make another 2421169702Skan stack slot, if we need one. */ 2422169702Skan if (stack_parm 2423169702Skan && ((STRICT_ALIGNMENT 2424169702Skan && GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm)) 2425169702Skan || (data->nominal_type 2426169702Skan && TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm) 2427169702Skan && MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY))) 2428169702Skan stack_parm = NULL; 242952268Sobrien 2430169702Skan /* If parm was passed in memory, and we need to convert it on entry, 2431169702Skan don't store it back in that same slot. */ 2432169702Skan else if (data->entry_parm == stack_parm 2433169702Skan && data->nominal_mode != BLKmode 2434169702Skan && data->nominal_mode != data->passed_mode) 2435169702Skan stack_parm = NULL; 243652268Sobrien 2437169702Skan /* If stack protection is in effect for this function, don't leave any 2438169702Skan pointers in their passed stack slots. */ 2439169702Skan else if (cfun->stack_protect_guard 2440169702Skan && (flag_stack_protect == 2 2441169702Skan || data->passed_pointer 2442169702Skan || POINTER_TYPE_P (data->nominal_type))) 2443169702Skan stack_parm = NULL; 244418334Speter 2445169702Skan data->stack_parm = stack_parm; 244618334Speter} 244718334Speter 2448169702Skan/* A subroutine of assign_parms. Return true if the current parameter 2449169702Skan should be stored as a BLKmode in the current frame. */ 245018334Speter 2451169702Skanstatic bool 2452169702Skanassign_parm_setup_block_p (struct assign_parm_data_one *data) 245318334Speter{ 2454169702Skan if (data->nominal_mode == BLKmode) 2455169702Skan return true; 2456169702Skan if (GET_CODE (data->entry_parm) == PARALLEL) 2457169702Skan return true; 245818334Speter 2459169702Skan#ifdef BLOCK_REG_PADDING 2460169702Skan /* Only assign_parm_setup_block knows how to deal with register arguments 2461169702Skan that are padded at the least significant end. */ 2462169702Skan if (REG_P (data->entry_parm) 2463169702Skan && GET_MODE_SIZE (data->promoted_mode) < UNITS_PER_WORD 2464169702Skan && (BLOCK_REG_PADDING (data->passed_mode, data->passed_type, 1) 2465169702Skan == (BYTES_BIG_ENDIAN ? upward : downward))) 2466169702Skan return true; 2467169702Skan#endif 246818334Speter 2469169702Skan return false; 247018334Speter} 247118334Speter 2472169702Skan/* A subroutine of assign_parms. Arrange for the parameter to be 2473169702Skan present and valid in DATA->STACK_RTL. */ 247418334Speter 247518334Speterstatic void 2476169702Skanassign_parm_setup_block (struct assign_parm_data_all *all, 2477169702Skan tree parm, struct assign_parm_data_one *data) 247818334Speter{ 2479169702Skan rtx entry_parm = data->entry_parm; 2480169702Skan rtx stack_parm = data->stack_parm; 2481169702Skan HOST_WIDE_INT size; 2482169702Skan HOST_WIDE_INT size_stored; 2483169702Skan rtx orig_entry_parm = entry_parm; 248418334Speter 2485169702Skan if (GET_CODE (entry_parm) == PARALLEL) 2486169702Skan entry_parm = emit_group_move_into_temps (entry_parm); 2487146908Skan 2488169702Skan /* If we've a non-block object that's nevertheless passed in parts, 2489169702Skan reconstitute it in register operations rather than on the stack. */ 2490169702Skan if (GET_CODE (entry_parm) == PARALLEL 2491169702Skan && data->nominal_mode != BLKmode) 2492146908Skan { 2493169702Skan rtx elt0 = XEXP (XVECEXP (orig_entry_parm, 0, 0), 0); 2494146908Skan 2495169702Skan if ((XVECLEN (entry_parm, 0) > 1 2496169702Skan || hard_regno_nregs[REGNO (elt0)][GET_MODE (elt0)] > 1) 2497169702Skan && use_register_for_decl (parm)) 2498169702Skan { 2499169702Skan rtx parmreg = gen_reg_rtx (data->nominal_mode); 250018334Speter 2501169702Skan push_to_sequence (all->conversion_insns); 250218334Speter 2503169702Skan /* For values returned in multiple registers, handle possible 2504169702Skan incompatible calls to emit_group_store. 250518334Speter 2506169702Skan For example, the following would be invalid, and would have to 2507169702Skan be fixed by the conditional below: 250818334Speter 2509169702Skan emit_group_store ((reg:SF), (parallel:DF)) 2510169702Skan emit_group_store ((reg:SI), (parallel:DI)) 251118334Speter 2512169702Skan An example of this are doubles in e500 v2: 2513169702Skan (parallel:DF (expr_list (reg:SI) (const_int 0)) 2514169702Skan (expr_list (reg:SI) (const_int 4))). */ 2515169702Skan if (data->nominal_mode != data->passed_mode) 2516169702Skan { 2517169702Skan rtx t = gen_reg_rtx (GET_MODE (entry_parm)); 2518169702Skan emit_group_store (t, entry_parm, NULL_TREE, 2519169702Skan GET_MODE_SIZE (GET_MODE (entry_parm))); 2520169702Skan convert_move (parmreg, t, 0); 2521169702Skan } 2522169702Skan else 2523169702Skan emit_group_store (parmreg, entry_parm, data->nominal_type, 2524169702Skan int_size_in_bytes (data->nominal_type)); 252590091Sobrien 2526169702Skan all->conversion_insns = get_insns (); 2527169702Skan end_sequence (); 252818334Speter 2529169702Skan SET_DECL_RTL (parm, parmreg); 253052268Sobrien return; 2531169702Skan } 253252268Sobrien } 253318334Speter 2534169702Skan size = int_size_in_bytes (data->passed_type); 2535169702Skan size_stored = CEIL_ROUND (size, UNITS_PER_WORD); 2536169702Skan if (stack_parm == 0) 2537117404Skan { 2538169702Skan DECL_ALIGN (parm) = MAX (DECL_ALIGN (parm), BITS_PER_WORD); 2539169702Skan stack_parm = assign_stack_local (BLKmode, size_stored, 2540169702Skan DECL_ALIGN (parm)); 2541169702Skan if (GET_MODE_SIZE (GET_MODE (entry_parm)) == size) 2542169702Skan PUT_MODE (stack_parm, GET_MODE (entry_parm)); 2543169702Skan set_mem_attributes (stack_parm, parm, 1); 2544117404Skan } 254518334Speter 2546169702Skan /* If a BLKmode arrives in registers, copy it to a stack slot. Handle 2547169702Skan calls that pass values in multiple non-contiguous locations. */ 2548169702Skan if (REG_P (entry_parm) || GET_CODE (entry_parm) == PARALLEL) 2549169702Skan { 2550169702Skan rtx mem; 255118334Speter 2552169702Skan /* Note that we will be storing an integral number of words. 2553169702Skan So we have to be careful to ensure that we allocate an 2554169702Skan integral number of words. We do this above when we call 2555169702Skan assign_stack_local if space was not allocated in the argument 2556169702Skan list. If it was, this will not work if PARM_BOUNDARY is not 2557169702Skan a multiple of BITS_PER_WORD. It isn't clear how to fix this 2558169702Skan if it becomes a problem. Exception is when BLKmode arrives 2559169702Skan with arguments not conforming to word_mode. */ 256018334Speter 2561169702Skan if (data->stack_parm == 0) 2562169702Skan ; 2563169702Skan else if (GET_CODE (entry_parm) == PARALLEL) 2564169702Skan ; 2565169702Skan else 2566169702Skan gcc_assert (!size || !(PARM_BOUNDARY % BITS_PER_WORD)); 256718334Speter 2568169702Skan mem = validize_mem (stack_parm); 256918334Speter 2570169702Skan /* Handle values in multiple non-contiguous locations. */ 2571169702Skan if (GET_CODE (entry_parm) == PARALLEL) 257290091Sobrien { 2573169702Skan push_to_sequence (all->conversion_insns); 2574169702Skan emit_group_store (mem, entry_parm, data->passed_type, size); 2575169702Skan all->conversion_insns = get_insns (); 257618334Speter end_sequence (); 257718334Speter } 257818334Speter 2579169702Skan else if (size == 0) 2580169702Skan ; 258118334Speter 2582169702Skan /* If SIZE is that of a mode no bigger than a word, just use 2583169702Skan that mode's store operation. */ 2584169702Skan else if (size <= UNITS_PER_WORD) 258518334Speter { 2586169702Skan enum machine_mode mode 2587169702Skan = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0); 258818334Speter 2589169702Skan if (mode != BLKmode 2590169702Skan#ifdef BLOCK_REG_PADDING 2591169702Skan && (size == UNITS_PER_WORD 2592169702Skan || (BLOCK_REG_PADDING (mode, data->passed_type, 1) 2593169702Skan != (BYTES_BIG_ENDIAN ? upward : downward))) 259490091Sobrien#endif 2595169702Skan ) 259618334Speter { 2597169702Skan rtx reg = gen_rtx_REG (mode, REGNO (entry_parm)); 2598169702Skan emit_move_insn (change_address (mem, mode, 0), reg); 259918334Speter } 260018334Speter 2601169702Skan /* Blocks smaller than a word on a BYTES_BIG_ENDIAN 2602169702Skan machine must be aligned to the left before storing 2603169702Skan to memory. Note that the previous test doesn't 2604169702Skan handle all cases (e.g. SIZE == 3). */ 2605169702Skan else if (size != UNITS_PER_WORD 2606169702Skan#ifdef BLOCK_REG_PADDING 2607169702Skan && (BLOCK_REG_PADDING (mode, data->passed_type, 1) 2608169702Skan == downward) 2609169702Skan#else 2610169702Skan && BYTES_BIG_ENDIAN 261118334Speter#endif 2612169702Skan ) 261318334Speter { 2614169702Skan rtx tem, x; 2615169702Skan int by = (UNITS_PER_WORD - size) * BITS_PER_UNIT; 2616169702Skan rtx reg = gen_rtx_REG (word_mode, REGNO (entry_parm)); 261718334Speter 2618169702Skan x = expand_shift (LSHIFT_EXPR, word_mode, reg, 2619169702Skan build_int_cst (NULL_TREE, by), 2620169702Skan NULL_RTX, 1); 2621169702Skan tem = change_address (mem, word_mode, 0); 2622169702Skan emit_move_insn (tem, x); 262318334Speter } 2624169702Skan else 2625169702Skan move_block_from_reg (REGNO (entry_parm), mem, 2626169702Skan size_stored / UNITS_PER_WORD); 262718334Speter } 2628169702Skan else 2629169702Skan move_block_from_reg (REGNO (entry_parm), mem, 2630169702Skan size_stored / UNITS_PER_WORD); 263118334Speter } 2632169702Skan else if (data->stack_parm == 0) 263318334Speter { 2634169702Skan push_to_sequence (all->conversion_insns); 2635169702Skan emit_block_move (stack_parm, data->entry_parm, GEN_INT (size), 2636169702Skan BLOCK_OP_NORMAL); 2637169702Skan all->conversion_insns = get_insns (); 2638169702Skan end_sequence (); 263918334Speter } 264018334Speter 2641169702Skan data->stack_parm = stack_parm; 2642169702Skan SET_DECL_RTL (parm, stack_parm); 264318334Speter} 264418334Speter 2645169702Skan/* A subroutine of assign_parms. Allocate a pseudo to hold the current 2646169702Skan parameter. Get it there. Perform all ABI specified conversions. */ 264718334Speter 2648169702Skanstatic void 2649169702Skanassign_parm_setup_reg (struct assign_parm_data_all *all, tree parm, 2650169702Skan struct assign_parm_data_one *data) 265118334Speter{ 2652169702Skan rtx parmreg; 2653169702Skan enum machine_mode promoted_nominal_mode; 2654169702Skan int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm)); 2655169702Skan bool did_conversion = false; 265618334Speter 2657169702Skan /* Store the parm in a pseudoregister during the function, but we may 2658169702Skan need to do it in a wider mode. */ 265990091Sobrien 2660169702Skan /* This is not really promoting for a call. However we need to be 2661169702Skan consistent with assign_parm_find_data_types and expand_expr_real_1. */ 2662169702Skan promoted_nominal_mode 2663169702Skan = promote_mode (data->nominal_type, data->nominal_mode, &unsignedp, 1); 2664132732Skan 2665169702Skan parmreg = gen_reg_rtx (promoted_nominal_mode); 266652268Sobrien 2667169702Skan if (!DECL_ARTIFICIAL (parm)) 2668169702Skan mark_user_reg (parmreg); 266952268Sobrien 2670169702Skan /* If this was an item that we received a pointer to, 2671169702Skan set DECL_RTL appropriately. */ 2672169702Skan if (data->passed_pointer) 2673169702Skan { 2674169702Skan rtx x = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (data->passed_type)), parmreg); 2675169702Skan set_mem_attributes (x, parm, 1); 2676169702Skan SET_DECL_RTL (parm, x); 2677169702Skan } 267818334Speter else 2679169702Skan SET_DECL_RTL (parm, parmreg); 268018334Speter 2681169702Skan /* Copy the value into the register. */ 2682169702Skan if (data->nominal_mode != data->passed_mode 2683169702Skan || promoted_nominal_mode != data->promoted_mode) 268418334Speter { 2685169702Skan int save_tree_used; 268618334Speter 2687169702Skan /* ENTRY_PARM has been converted to PROMOTED_MODE, its 2688169702Skan mode, by the caller. We now have to convert it to 2689169702Skan NOMINAL_MODE, if different. However, PARMREG may be in 2690169702Skan a different mode than NOMINAL_MODE if it is being stored 2691169702Skan promoted. 269218334Speter 2693169702Skan If ENTRY_PARM is a hard register, it might be in a register 2694169702Skan not valid for operating in its mode (e.g., an odd-numbered 2695169702Skan register for a DFmode). In that case, moves are the only 2696169702Skan thing valid, so we can't do a convert from there. This 2697169702Skan occurs when the calling sequence allow such misaligned 2698169702Skan usages. 269990091Sobrien 2700169702Skan In addition, the conversion may involve a call, which could 2701169702Skan clobber parameters which haven't been copied to pseudo 2702169702Skan registers yet. Therefore, we must first copy the parm to 2703169702Skan a pseudo reg here, and save the conversion until after all 2704169702Skan parameters have been moved. */ 2705132732Skan 2706169702Skan rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm)); 270718334Speter 2708169702Skan emit_move_insn (tempreg, validize_mem (data->entry_parm)); 2709132732Skan 2710169702Skan push_to_sequence (all->conversion_insns); 2711169702Skan tempreg = convert_to_mode (data->nominal_mode, tempreg, unsignedp); 2712132732Skan 2713169702Skan if (GET_CODE (tempreg) == SUBREG 2714169702Skan && GET_MODE (tempreg) == data->nominal_mode 2715169702Skan && REG_P (SUBREG_REG (tempreg)) 2716169702Skan && data->nominal_mode == data->passed_mode 2717169702Skan && GET_MODE (SUBREG_REG (tempreg)) == GET_MODE (data->entry_parm) 2718169702Skan && GET_MODE_SIZE (GET_MODE (tempreg)) 2719169702Skan < GET_MODE_SIZE (GET_MODE (data->entry_parm))) 272090091Sobrien { 2721169702Skan /* The argument is already sign/zero extended, so note it 2722169702Skan into the subreg. */ 2723169702Skan SUBREG_PROMOTED_VAR_P (tempreg) = 1; 2724169702Skan SUBREG_PROMOTED_UNSIGNED_SET (tempreg, unsignedp); 272590091Sobrien } 272618334Speter 2727169702Skan /* TREE_USED gets set erroneously during expand_assignment. */ 2728169702Skan save_tree_used = TREE_USED (parm); 2729169702Skan expand_assignment (parm, make_tree (data->nominal_type, tempreg)); 2730169702Skan TREE_USED (parm) = save_tree_used; 2731169702Skan all->conversion_insns = get_insns (); 2732169702Skan end_sequence (); 273318334Speter 2734169702Skan did_conversion = true; 2735169702Skan } 2736169702Skan else 2737169702Skan emit_move_insn (parmreg, validize_mem (data->entry_parm)); 273818334Speter 2739169702Skan /* If we were passed a pointer but the actual value can safely live 2740169702Skan in a register, put it in one. */ 2741169702Skan if (data->passed_pointer 2742169702Skan && TYPE_MODE (TREE_TYPE (parm)) != BLKmode 2743169702Skan /* If by-reference argument was promoted, demote it. */ 2744169702Skan && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm)) 2745169702Skan || use_register_for_decl (parm))) 2746169702Skan { 2747169702Skan /* We can't use nominal_mode, because it will have been set to 2748169702Skan Pmode above. We must use the actual mode of the parm. */ 2749169702Skan parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm))); 2750169702Skan mark_user_reg (parmreg); 275118334Speter 2752169702Skan if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm))) 275318334Speter { 2754169702Skan rtx tempreg = gen_reg_rtx (GET_MODE (DECL_RTL (parm))); 2755169702Skan int unsigned_p = TYPE_UNSIGNED (TREE_TYPE (parm)); 275618334Speter 2757169702Skan push_to_sequence (all->conversion_insns); 2758169702Skan emit_move_insn (tempreg, DECL_RTL (parm)); 2759169702Skan tempreg = convert_to_mode (GET_MODE (parmreg), tempreg, unsigned_p); 2760169702Skan emit_move_insn (parmreg, tempreg); 2761169702Skan all->conversion_insns = get_insns (); 2762169702Skan end_sequence (); 276318334Speter 2764169702Skan did_conversion = true; 2765132732Skan } 2766169702Skan else 2767169702Skan emit_move_insn (parmreg, DECL_RTL (parm)); 276818334Speter 2769169702Skan SET_DECL_RTL (parm, parmreg); 277018334Speter 2771169702Skan /* STACK_PARM is the pointer, not the parm, and PARMREG is 2772169702Skan now the parm. */ 2773169702Skan data->stack_parm = NULL; 2774169702Skan } 277518334Speter 2776169702Skan /* Mark the register as eliminable if we did no conversion and it was 2777169702Skan copied from memory at a fixed offset, and the arg pointer was not 2778169702Skan copied to a pseudo-reg. If the arg pointer is a pseudo reg or the 2779169702Skan offset formed an invalid address, such memory-equivalences as we 2780169702Skan make here would screw up life analysis for it. */ 2781169702Skan if (data->nominal_mode == data->passed_mode 2782169702Skan && !did_conversion 2783169702Skan && data->stack_parm != 0 2784169702Skan && MEM_P (data->stack_parm) 2785169702Skan && data->locate.offset.var == 0 2786169702Skan && reg_mentioned_p (virtual_incoming_args_rtx, 2787169702Skan XEXP (data->stack_parm, 0))) 2788169702Skan { 2789169702Skan rtx linsn = get_last_insn (); 2790169702Skan rtx sinsn, set; 279118334Speter 2792169702Skan /* Mark complex types separately. */ 2793169702Skan if (GET_CODE (parmreg) == CONCAT) 279418334Speter { 2795169702Skan enum machine_mode submode 2796169702Skan = GET_MODE_INNER (GET_MODE (parmreg)); 2797169702Skan int regnor = REGNO (XEXP (parmreg, 0)); 2798169702Skan int regnoi = REGNO (XEXP (parmreg, 1)); 2799169702Skan rtx stackr = adjust_address_nv (data->stack_parm, submode, 0); 2800169702Skan rtx stacki = adjust_address_nv (data->stack_parm, submode, 2801169702Skan GET_MODE_SIZE (submode)); 2802132732Skan 2803169702Skan /* Scan backwards for the set of the real and 2804169702Skan imaginary parts. */ 2805169702Skan for (sinsn = linsn; sinsn != 0; 2806169702Skan sinsn = prev_nonnote_insn (sinsn)) 2807132732Skan { 2808169702Skan set = single_set (sinsn); 2809169702Skan if (set == 0) 2810169702Skan continue; 2811132732Skan 2812169702Skan if (SET_DEST (set) == regno_reg_rtx [regnoi]) 2813169702Skan REG_NOTES (sinsn) 2814169702Skan = gen_rtx_EXPR_LIST (REG_EQUIV, stacki, 2815169702Skan REG_NOTES (sinsn)); 2816169702Skan else if (SET_DEST (set) == regno_reg_rtx [regnor]) 2817169702Skan REG_NOTES (sinsn) 2818169702Skan = gen_rtx_EXPR_LIST (REG_EQUIV, stackr, 2819169702Skan REG_NOTES (sinsn)); 2820132732Skan } 2821132732Skan } 2822169702Skan else if ((set = single_set (linsn)) != 0 2823169702Skan && SET_DEST (set) == parmreg) 2824169702Skan REG_NOTES (linsn) 2825169702Skan = gen_rtx_EXPR_LIST (REG_EQUIV, 2826169702Skan data->stack_parm, REG_NOTES (linsn)); 2827169702Skan } 2828132732Skan 2829169702Skan /* For pointer data type, suggest pointer register. */ 2830169702Skan if (POINTER_TYPE_P (TREE_TYPE (parm))) 2831169702Skan mark_reg_pointer (parmreg, 2832169702Skan TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm)))); 2833169702Skan} 2834132732Skan 2835169702Skan/* A subroutine of assign_parms. Allocate stack space to hold the current 2836169702Skan parameter. Get it there. Perform all ABI specified conversions. */ 283718334Speter 2838169702Skanstatic void 2839169702Skanassign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, 2840169702Skan struct assign_parm_data_one *data) 2841169702Skan{ 2842169702Skan /* Value must be stored in the stack slot STACK_PARM during function 2843169702Skan execution. */ 2844169702Skan bool to_conversion = false; 2845132732Skan 2846169702Skan if (data->promoted_mode != data->nominal_mode) 2847169702Skan { 2848169702Skan /* Conversion is required. */ 2849169702Skan rtx tempreg = gen_reg_rtx (GET_MODE (data->entry_parm)); 285018334Speter 2851169702Skan emit_move_insn (tempreg, validize_mem (data->entry_parm)); 2852132732Skan 2853169702Skan push_to_sequence (all->conversion_insns); 2854169702Skan to_conversion = true; 2855132732Skan 2856169702Skan data->entry_parm = convert_to_mode (data->nominal_mode, tempreg, 2857169702Skan TYPE_UNSIGNED (TREE_TYPE (parm))); 2858132732Skan 2859169702Skan if (data->stack_parm) 2860169702Skan /* ??? This may need a big-endian conversion on sparc64. */ 2861169702Skan data->stack_parm 2862169702Skan = adjust_address (data->stack_parm, data->nominal_mode, 0); 2863169702Skan } 286418334Speter 2865169702Skan if (data->entry_parm != data->stack_parm) 2866169702Skan { 2867169702Skan rtx src, dest; 286818334Speter 2869169702Skan if (data->stack_parm == 0) 287018334Speter { 2871169702Skan data->stack_parm 2872169702Skan = assign_stack_local (GET_MODE (data->entry_parm), 2873169702Skan GET_MODE_SIZE (GET_MODE (data->entry_parm)), 2874169702Skan TYPE_ALIGN (data->passed_type)); 2875169702Skan set_mem_attributes (data->stack_parm, parm, 1); 287618334Speter } 287718334Speter 2878169702Skan dest = validize_mem (data->stack_parm); 2879169702Skan src = validize_mem (data->entry_parm); 288018334Speter 2881169702Skan if (MEM_P (src)) 2882169702Skan { 2883169702Skan /* Use a block move to handle potentially misaligned entry_parm. */ 2884169702Skan if (!to_conversion) 2885169702Skan push_to_sequence (all->conversion_insns); 2886169702Skan to_conversion = true; 288718334Speter 2888169702Skan emit_block_move (dest, src, 2889169702Skan GEN_INT (int_size_in_bytes (data->passed_type)), 2890169702Skan BLOCK_OP_NORMAL); 289118334Speter } 289218334Speter else 2893169702Skan emit_move_insn (dest, src); 2894169702Skan } 289518334Speter 2896169702Skan if (to_conversion) 2897169702Skan { 2898169702Skan all->conversion_insns = get_insns (); 2899169702Skan end_sequence (); 2900169702Skan } 290118334Speter 2902169702Skan SET_DECL_RTL (parm, data->stack_parm); 2903169702Skan} 290418334Speter 2905169702Skan/* A subroutine of assign_parms. If the ABI splits complex arguments, then 2906169702Skan undo the frobbing that we did in assign_parms_augmented_arg_list. */ 290718334Speter 2908169702Skanstatic void 2909169702Skanassign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) 2910169702Skan{ 2911169702Skan tree parm; 2912169702Skan tree orig_fnargs = all->orig_fnargs; 291318334Speter 2914169702Skan for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm)) 2915169702Skan { 2916169702Skan if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE 2917169702Skan && targetm.calls.split_complex_arg (TREE_TYPE (parm))) 291818334Speter { 2919169702Skan rtx tmp, real, imag; 2920169702Skan enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm)); 292118334Speter 2922169702Skan real = DECL_RTL (fnargs); 2923169702Skan imag = DECL_RTL (TREE_CHAIN (fnargs)); 2924169702Skan if (inner != GET_MODE (real)) 2925132732Skan { 2926169702Skan real = gen_lowpart_SUBREG (inner, real); 2927169702Skan imag = gen_lowpart_SUBREG (inner, imag); 2928132732Skan } 2929132732Skan 2930169702Skan if (TREE_ADDRESSABLE (parm)) 293118334Speter { 2932169702Skan rtx rmem, imem; 2933169702Skan HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (parm)); 293418334Speter 2935169702Skan /* split_complex_arg put the real and imag parts in 2936169702Skan pseudos. Move them to memory. */ 2937169702Skan tmp = assign_stack_local (DECL_MODE (parm), size, 2938169702Skan TYPE_ALIGN (TREE_TYPE (parm))); 2939169702Skan set_mem_attributes (tmp, parm, 1); 2940169702Skan rmem = adjust_address_nv (tmp, inner, 0); 2941169702Skan imem = adjust_address_nv (tmp, inner, GET_MODE_SIZE (inner)); 2942169702Skan push_to_sequence (all->conversion_insns); 2943169702Skan emit_move_insn (rmem, real); 2944169702Skan emit_move_insn (imem, imag); 2945169702Skan all->conversion_insns = get_insns (); 294618334Speter end_sequence (); 294718334Speter } 294818334Speter else 2949169702Skan tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag); 2950169702Skan SET_DECL_RTL (parm, tmp); 295118334Speter 2952169702Skan real = DECL_INCOMING_RTL (fnargs); 2953169702Skan imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs)); 2954169702Skan if (inner != GET_MODE (real)) 295518334Speter { 2956169702Skan real = gen_lowpart_SUBREG (inner, real); 2957169702Skan imag = gen_lowpart_SUBREG (inner, imag); 295818334Speter } 2959169702Skan tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag); 2960169702Skan set_decl_incoming_rtl (parm, tmp); 2961169702Skan fnargs = TREE_CHAIN (fnargs); 2962169702Skan } 2963169702Skan else 2964169702Skan { 2965169702Skan SET_DECL_RTL (parm, DECL_RTL (fnargs)); 2966169702Skan set_decl_incoming_rtl (parm, DECL_INCOMING_RTL (fnargs)); 296718334Speter 2968169702Skan /* Set MEM_EXPR to the original decl, i.e. to PARM, 2969169702Skan instead of the copy of decl, i.e. FNARGS. */ 2970169702Skan if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm))) 2971169702Skan set_mem_expr (DECL_INCOMING_RTL (parm), parm); 2972169702Skan } 297318334Speter 2974169702Skan fnargs = TREE_CHAIN (fnargs); 2975169702Skan } 2976169702Skan} 297718334Speter 2978169702Skan/* Assign RTL expressions to the function's parameters. This may involve 2979169702Skan copying them into registers and using those registers as the DECL_RTL. */ 298018334Speter 2981169702Skanstatic void 2982169702Skanassign_parms (tree fndecl) 2983169702Skan{ 2984169702Skan struct assign_parm_data_all all; 2985169702Skan tree fnargs, parm; 298618334Speter 2987169702Skan current_function_internal_arg_pointer 2988169702Skan = targetm.calls.internal_arg_pointer (); 298918334Speter 2990169702Skan assign_parms_initialize_all (&all); 2991169702Skan fnargs = assign_parms_augmented_arg_list (&all); 299218334Speter 2993169702Skan for (parm = fnargs; parm; parm = TREE_CHAIN (parm)) 2994169702Skan { 2995169702Skan struct assign_parm_data_one data; 299618334Speter 2997169702Skan /* Extract the type of PARM; adjust it according to ABI. */ 2998169702Skan assign_parm_find_data_types (&all, parm, &data); 299918334Speter 3000169702Skan /* Early out for errors and void parameters. */ 3001169702Skan if (data.passed_mode == VOIDmode) 3002169702Skan { 3003169702Skan SET_DECL_RTL (parm, const0_rtx); 3004169702Skan DECL_INCOMING_RTL (parm) = DECL_RTL (parm); 3005169702Skan continue; 3006169702Skan } 300718334Speter 3008169702Skan if (current_function_stdarg && !TREE_CHAIN (parm)) 3009169702Skan assign_parms_setup_varargs (&all, &data, false); 301018334Speter 3011169702Skan /* Find out where the parameter arrives in this function. */ 3012169702Skan assign_parm_find_entry_rtl (&all, &data); 301318334Speter 3014169702Skan /* Find out where stack space for this parameter might be. */ 3015169702Skan if (assign_parm_is_stack_parm (&all, &data)) 3016169702Skan { 3017169702Skan assign_parm_find_stack_rtl (parm, &data); 3018169702Skan assign_parm_adjust_entry_rtl (&data); 3019169702Skan } 302018334Speter 3021169702Skan /* Record permanently how this parm was passed. */ 3022169702Skan set_decl_incoming_rtl (parm, data.entry_parm); 302318334Speter 3024169702Skan /* Update info on where next arg arrives in registers. */ 3025169702Skan FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode, 3026169702Skan data.passed_type, data.named_arg); 302718334Speter 3028169702Skan assign_parm_adjust_stack_rtl (&data); 302918334Speter 3030169702Skan if (assign_parm_setup_block_p (&data)) 3031169702Skan assign_parm_setup_block (&all, parm, &data); 3032169702Skan else if (data.passed_pointer || use_register_for_decl (parm)) 3033169702Skan assign_parm_setup_reg (&all, parm, &data); 303418334Speter else 3035169702Skan assign_parm_setup_stack (&all, parm, &data); 3036132732Skan } 303790091Sobrien 3038169702Skan if (targetm.calls.split_complex_arg && fnargs != all.orig_fnargs) 3039169702Skan assign_parms_unsplit_complex (&all, fnargs); 304018334Speter 304118334Speter /* Output all parameter conversion instructions (possibly including calls) 304218334Speter now that all parameters have been copied out of hard registers. */ 3043169702Skan emit_insn (all.conversion_insns); 304418334Speter 3045132732Skan /* If we are receiving a struct value address as the first argument, set up 3046132732Skan the RTL for the function result. As this might require code to convert 3047132732Skan the transmitted address to Pmode, we do this here to ensure that possible 3048132732Skan preliminary conversions of the address have been emitted already. */ 3049169702Skan if (all.function_result_decl) 3050132732Skan { 3051169702Skan tree result = DECL_RESULT (current_function_decl); 3052169702Skan rtx addr = DECL_RTL (all.function_result_decl); 3053132732Skan rtx x; 3054132732Skan 3055169702Skan if (DECL_BY_REFERENCE (result)) 3056169702Skan x = addr; 3057169702Skan else 3058169702Skan { 3059169702Skan addr = convert_memory_address (Pmode, addr); 3060169702Skan x = gen_rtx_MEM (DECL_MODE (result), addr); 3061169702Skan set_mem_attributes (x, result, 1); 3062169702Skan } 3063132732Skan SET_DECL_RTL (result, x); 3064132732Skan } 3065132732Skan 3066169702Skan /* We have aligned all the args, so add space for the pretend args. */ 3067169702Skan current_function_pretend_args_size = all.pretend_args_size; 3068169702Skan all.stack_args_size.constant += all.extra_pretend_bytes; 3069169702Skan current_function_args_size = all.stack_args_size.constant; 307018334Speter 307118334Speter /* Adjust function incoming argument size for alignment and 307218334Speter minimum length. */ 307318334Speter 307418334Speter#ifdef REG_PARM_STACK_SPACE 307518334Speter current_function_args_size = MAX (current_function_args_size, 307618334Speter REG_PARM_STACK_SPACE (fndecl)); 307718334Speter#endif 307818334Speter 3079169702Skan current_function_args_size = CEIL_ROUND (current_function_args_size, 3080169702Skan PARM_BOUNDARY / BITS_PER_UNIT); 308118334Speter 308218334Speter#ifdef ARGS_GROW_DOWNWARD 308318334Speter current_function_arg_offset_rtx 3084169702Skan = (all.stack_args_size.var == 0 ? GEN_INT (-all.stack_args_size.constant) 3085169702Skan : expand_expr (size_diffop (all.stack_args_size.var, 3086169702Skan size_int (-all.stack_args_size.constant)), 308790091Sobrien NULL_RTX, VOIDmode, 0)); 308818334Speter#else 3089169702Skan current_function_arg_offset_rtx = ARGS_SIZE_RTX (all.stack_args_size); 309018334Speter#endif 309118334Speter 309218334Speter /* See how many bytes, if any, of its args a function should try to pop 309318334Speter on return. */ 309418334Speter 309518334Speter current_function_pops_args = RETURN_POPS_ARGS (fndecl, TREE_TYPE (fndecl), 309618334Speter current_function_args_size); 309718334Speter 309818334Speter /* For stdarg.h function, save info about 309918334Speter regs and stack space used by the named args. */ 310018334Speter 3101169702Skan current_function_args_info = all.args_so_far; 310218334Speter 310318334Speter /* Set the rtx used for the function return value. Put this in its 310418334Speter own variable so any optimizers that need this information don't have 310518334Speter to include tree.h. Do this here so it gets done when an inlined 310618334Speter function gets output. */ 310718334Speter 310890091Sobrien current_function_return_rtx 310990091Sobrien = (DECL_RTL_SET_P (DECL_RESULT (fndecl)) 311090091Sobrien ? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX); 311196283Sobrien 311296283Sobrien /* If scalar return value was computed in a pseudo-reg, or was a named 311396283Sobrien return value that got dumped to the stack, copy that to the hard 311496283Sobrien return register. */ 311596283Sobrien if (DECL_RTL_SET_P (DECL_RESULT (fndecl))) 311696283Sobrien { 311796283Sobrien tree decl_result = DECL_RESULT (fndecl); 311896283Sobrien rtx decl_rtl = DECL_RTL (decl_result); 311996283Sobrien 312096283Sobrien if (REG_P (decl_rtl) 312196283Sobrien ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER 312296283Sobrien : DECL_REGISTER (decl_result)) 312396283Sobrien { 312496283Sobrien rtx real_decl_rtl; 312596283Sobrien 3126169702Skan real_decl_rtl = targetm.calls.function_value (TREE_TYPE (decl_result), 3127169702Skan fndecl, true); 312896283Sobrien REG_FUNCTION_VALUE_P (real_decl_rtl) = 1; 312996283Sobrien /* The delay slot scheduler assumes that current_function_return_rtx 313096283Sobrien holds the hard register containing the return value, not a 313196283Sobrien temporary pseudo. */ 313296283Sobrien current_function_return_rtx = real_decl_rtl; 313396283Sobrien } 313496283Sobrien } 313518334Speter} 3136132732Skan 3137169702Skan/* A subroutine of gimplify_parameters, invoked via walk_tree. 3138169702Skan For all seen types, gimplify their sizes. */ 3139132732Skan 3140132732Skanstatic tree 3141169702Skangimplify_parm_type (tree *tp, int *walk_subtrees, void *data) 3142132732Skan{ 3143169702Skan tree t = *tp; 3144132732Skan 3145169702Skan *walk_subtrees = 0; 3146169702Skan if (TYPE_P (t)) 3147132732Skan { 3148169702Skan if (POINTER_TYPE_P (t)) 3149169702Skan *walk_subtrees = 1; 3150169702Skan else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t)) 3151169702Skan && !TYPE_SIZES_GIMPLIFIED (t)) 3152169702Skan { 3153169702Skan gimplify_type_sizes (t, (tree *) data); 3154169702Skan *walk_subtrees = 1; 3155169702Skan } 3156132732Skan } 3157132732Skan 3158169702Skan return NULL; 3159169702Skan} 3160132732Skan 3161169702Skan/* Gimplify the parameter list for current_function_decl. This involves 3162169702Skan evaluating SAVE_EXPRs of variable sized parameters and generating code 3163169702Skan to implement callee-copies reference parameters. Returns a list of 3164169702Skan statements to add to the beginning of the function, or NULL if nothing 3165169702Skan to do. */ 3166169702Skan 3167169702Skantree 3168169702Skangimplify_parameters (void) 3169169702Skan{ 3170169702Skan struct assign_parm_data_all all; 3171169702Skan tree fnargs, parm, stmts = NULL; 3172169702Skan 3173169702Skan assign_parms_initialize_all (&all); 3174169702Skan fnargs = assign_parms_augmented_arg_list (&all); 3175169702Skan 3176169702Skan for (parm = fnargs; parm; parm = TREE_CHAIN (parm)) 3177132732Skan { 3178169702Skan struct assign_parm_data_one data; 3179169702Skan 3180169702Skan /* Extract the type of PARM; adjust it according to ABI. */ 3181169702Skan assign_parm_find_data_types (&all, parm, &data); 3182169702Skan 3183169702Skan /* Early out for errors and void parameters. */ 3184169702Skan if (data.passed_mode == VOIDmode || DECL_SIZE (parm) == NULL) 3185169702Skan continue; 3186169702Skan 3187169702Skan /* Update info on where next arg arrives in registers. */ 3188169702Skan FUNCTION_ARG_ADVANCE (all.args_so_far, data.promoted_mode, 3189169702Skan data.passed_type, data.named_arg); 3190169702Skan 3191169702Skan /* ??? Once upon a time variable_size stuffed parameter list 3192169702Skan SAVE_EXPRs (amongst others) onto a pending sizes list. This 3193169702Skan turned out to be less than manageable in the gimple world. 3194169702Skan Now we have to hunt them down ourselves. */ 3195169702Skan walk_tree_without_duplicates (&data.passed_type, 3196169702Skan gimplify_parm_type, &stmts); 3197169702Skan 3198169702Skan if (!TREE_CONSTANT (DECL_SIZE (parm))) 3199132732Skan { 3200169702Skan gimplify_one_sizepos (&DECL_SIZE (parm), &stmts); 3201169702Skan gimplify_one_sizepos (&DECL_SIZE_UNIT (parm), &stmts); 3202169702Skan } 3203132732Skan 3204169702Skan if (data.passed_pointer) 3205169702Skan { 3206169702Skan tree type = TREE_TYPE (data.passed_type); 3207169702Skan if (reference_callee_copied (&all.args_so_far, TYPE_MODE (type), 3208169702Skan type, data.named_arg)) 3209169702Skan { 3210169702Skan tree local, t; 3211132732Skan 3212169702Skan /* For constant sized objects, this is trivial; for 3213169702Skan variable-sized objects, we have to play games. */ 3214169702Skan if (TREE_CONSTANT (DECL_SIZE (parm))) 3215169702Skan { 3216169702Skan local = create_tmp_var (type, get_name (parm)); 3217169702Skan DECL_IGNORED_P (local) = 0; 3218169702Skan } 3219169702Skan else 3220169702Skan { 3221169702Skan tree ptr_type, addr, args; 3222132732Skan 3223169702Skan ptr_type = build_pointer_type (type); 3224169702Skan addr = create_tmp_var (ptr_type, get_name (parm)); 3225169702Skan DECL_IGNORED_P (addr) = 0; 3226169702Skan local = build_fold_indirect_ref (addr); 3227169702Skan 3228169702Skan args = tree_cons (NULL, DECL_SIZE_UNIT (parm), NULL); 3229169702Skan t = built_in_decls[BUILT_IN_ALLOCA]; 3230169702Skan t = build_function_call_expr (t, args); 3231169702Skan t = fold_convert (ptr_type, t); 3232169702Skan t = build2 (MODIFY_EXPR, void_type_node, addr, t); 3233169702Skan gimplify_and_add (t, &stmts); 3234169702Skan } 3235169702Skan 3236169702Skan t = build2 (MODIFY_EXPR, void_type_node, local, parm); 3237169702Skan gimplify_and_add (t, &stmts); 3238169702Skan 3239169702Skan SET_DECL_VALUE_EXPR (parm, local); 3240169702Skan DECL_HAS_VALUE_EXPR_P (parm) = 1; 3241169702Skan } 3242132732Skan } 3243132732Skan } 3244132732Skan 3245169702Skan return stmts; 3246132732Skan} 324718334Speter 324818334Speter/* Indicate whether REGNO is an incoming argument to the current function 324918334Speter that was promoted to a wider mode. If so, return the RTX for the 325018334Speter register (to get its mode). PMODE and PUNSIGNEDP are set to the mode 325118334Speter that REGNO is promoted from and whether the promotion was signed or 325218334Speter unsigned. */ 325318334Speter 325418334Speterrtx 3255132732Skanpromoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp) 325618334Speter{ 325718334Speter tree arg; 325818334Speter 325918334Speter for (arg = DECL_ARGUMENTS (current_function_decl); arg; 326018334Speter arg = TREE_CHAIN (arg)) 3261169702Skan if (REG_P (DECL_INCOMING_RTL (arg)) 326218334Speter && REGNO (DECL_INCOMING_RTL (arg)) == regno 326318334Speter && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg))) 326418334Speter { 326518334Speter enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg)); 3266169702Skan int unsignedp = TYPE_UNSIGNED (TREE_TYPE (arg)); 326718334Speter 326818334Speter mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1); 326918334Speter if (mode == GET_MODE (DECL_INCOMING_RTL (arg)) 327018334Speter && mode != DECL_MODE (arg)) 327118334Speter { 327218334Speter *pmode = DECL_MODE (arg); 327318334Speter *punsignedp = unsignedp; 327418334Speter return DECL_INCOMING_RTL (arg); 327518334Speter } 327618334Speter } 327718334Speter 327818334Speter return 0; 327918334Speter} 328018334Speter 328118334Speter 328218334Speter/* Compute the size and offset from the start of the stacked arguments for a 328318334Speter parm passed in mode PASSED_MODE and with type TYPE. 328418334Speter 328518334Speter INITIAL_OFFSET_PTR points to the current offset into the stacked 328618334Speter arguments. 328718334Speter 3288132732Skan The starting offset and size for this parm are returned in 3289132732Skan LOCATE->OFFSET and LOCATE->SIZE, respectively. When IN_REGS is 3290132732Skan nonzero, the offset is that of stack slot, which is returned in 3291132732Skan LOCATE->SLOT_OFFSET. LOCATE->ALIGNMENT_PAD is the amount of 3292132732Skan padding required from the initial offset ptr to the stack slot. 329318334Speter 3294117404Skan IN_REGS is nonzero if the argument will be passed in registers. It will 329518334Speter never be set if REG_PARM_STACK_SPACE is not defined. 329618334Speter 329718334Speter FNDECL is the function in which the argument was defined. 329818334Speter 329918334Speter There are two types of rounding that are done. The first, controlled by 330018334Speter FUNCTION_ARG_BOUNDARY, forces the offset from the start of the argument 330118334Speter list to be aligned to the specific boundary (in bits). This rounding 330218334Speter affects the initial and starting offsets, but not the argument size. 330318334Speter 330418334Speter The second, controlled by FUNCTION_ARG_PADDING and PARM_BOUNDARY, 330518334Speter optionally rounds the size of the parm to PARM_BOUNDARY. The 330618334Speter initial offset is not affected by this rounding, while the size always 330718334Speter is and the starting offset may be. */ 330818334Speter 3309132732Skan/* LOCATE->OFFSET will be negative for ARGS_GROW_DOWNWARD case; 3310132732Skan INITIAL_OFFSET_PTR is positive because locate_and_pad_parm's 331118334Speter callers pass in the total size of args so far as 3312132732Skan INITIAL_OFFSET_PTR. LOCATE->SIZE is always positive. */ 331318334Speter 331418334Spetervoid 3315132732Skanlocate_and_pad_parm (enum machine_mode passed_mode, tree type, int in_regs, 3316132732Skan int partial, tree fndecl ATTRIBUTE_UNUSED, 3317132732Skan struct args_size *initial_offset_ptr, 3318132732Skan struct locate_and_pad_arg_data *locate) 3319132732Skan{ 3320132732Skan tree sizetree; 3321132732Skan enum direction where_pad; 3322169702Skan unsigned int boundary; 3323132732Skan int reg_parm_stack_space = 0; 3324132732Skan int part_size_in_regs; 332590091Sobrien 3326132732Skan#ifdef REG_PARM_STACK_SPACE 3327132732Skan reg_parm_stack_space = REG_PARM_STACK_SPACE (fndecl); 332818334Speter 332918334Speter /* If we have found a stack parm before we reach the end of the 333018334Speter area reserved for registers, skip that area. */ 333118334Speter if (! in_regs) 333218334Speter { 333318334Speter if (reg_parm_stack_space > 0) 333418334Speter { 333518334Speter if (initial_offset_ptr->var) 333618334Speter { 333718334Speter initial_offset_ptr->var 333818334Speter = size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr), 333990091Sobrien ssize_int (reg_parm_stack_space)); 334018334Speter initial_offset_ptr->constant = 0; 334118334Speter } 334218334Speter else if (initial_offset_ptr->constant < reg_parm_stack_space) 334318334Speter initial_offset_ptr->constant = reg_parm_stack_space; 334418334Speter } 334518334Speter } 334618334Speter#endif /* REG_PARM_STACK_SPACE */ 334718334Speter 3348169702Skan part_size_in_regs = (reg_parm_stack_space == 0 ? partial : 0); 334918334Speter 3350132732Skan sizetree 3351132732Skan = type ? size_in_bytes (type) : size_int (GET_MODE_SIZE (passed_mode)); 3352132732Skan where_pad = FUNCTION_ARG_PADDING (passed_mode, type); 3353132732Skan boundary = FUNCTION_ARG_BOUNDARY (passed_mode, type); 3354132732Skan locate->where_pad = where_pad; 3355169702Skan locate->boundary = boundary; 3356132732Skan 3357169702Skan /* Remember if the outgoing parameter requires extra alignment on the 3358169702Skan calling function side. */ 3359169702Skan if (boundary > PREFERRED_STACK_BOUNDARY) 3360169702Skan boundary = PREFERRED_STACK_BOUNDARY; 3361169702Skan if (cfun->stack_alignment_needed < boundary) 3362169702Skan cfun->stack_alignment_needed = boundary; 3363169702Skan 336418334Speter#ifdef ARGS_GROW_DOWNWARD 3365132732Skan locate->slot_offset.constant = -initial_offset_ptr->constant; 336618334Speter if (initial_offset_ptr->var) 3367132732Skan locate->slot_offset.var = size_binop (MINUS_EXPR, ssize_int (0), 3368132732Skan initial_offset_ptr->var); 3369117404Skan 3370132732Skan { 3371132732Skan tree s2 = sizetree; 3372132732Skan if (where_pad != none 3373132732Skan && (!host_integerp (sizetree, 1) 3374132732Skan || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY)) 3375132732Skan s2 = round_up (s2, PARM_BOUNDARY / BITS_PER_UNIT); 3376132732Skan SUB_PARM_SIZE (locate->slot_offset, s2); 3377132732Skan } 3378117404Skan 3379132732Skan locate->slot_offset.constant += part_size_in_regs; 3380132732Skan 3381117404Skan if (!in_regs 3382117404Skan#ifdef REG_PARM_STACK_SPACE 3383117404Skan || REG_PARM_STACK_SPACE (fndecl) > 0 3384117404Skan#endif 3385117404Skan ) 3386132732Skan pad_to_arg_alignment (&locate->slot_offset, boundary, 3387132732Skan &locate->alignment_pad); 3388117404Skan 3389132732Skan locate->size.constant = (-initial_offset_ptr->constant 3390132732Skan - locate->slot_offset.constant); 339118334Speter if (initial_offset_ptr->var) 3392132732Skan locate->size.var = size_binop (MINUS_EXPR, 3393132732Skan size_binop (MINUS_EXPR, 3394132732Skan ssize_int (0), 3395132732Skan initial_offset_ptr->var), 3396132732Skan locate->slot_offset.var); 339790091Sobrien 3398132732Skan /* Pad_below needs the pre-rounded size to know how much to pad 3399132732Skan below. */ 3400132732Skan locate->offset = locate->slot_offset; 3401132732Skan if (where_pad == downward) 3402132732Skan pad_below (&locate->offset, passed_mode, sizetree); 340390091Sobrien 340418334Speter#else /* !ARGS_GROW_DOWNWARD */ 340590091Sobrien if (!in_regs 340690091Sobrien#ifdef REG_PARM_STACK_SPACE 340790091Sobrien || REG_PARM_STACK_SPACE (fndecl) > 0 340890091Sobrien#endif 340990091Sobrien ) 3410132732Skan pad_to_arg_alignment (initial_offset_ptr, boundary, 3411132732Skan &locate->alignment_pad); 3412132732Skan locate->slot_offset = *initial_offset_ptr; 341318334Speter 341418334Speter#ifdef PUSH_ROUNDING 341518334Speter if (passed_mode != BLKmode) 341618334Speter sizetree = size_int (PUSH_ROUNDING (TREE_INT_CST_LOW (sizetree))); 341718334Speter#endif 341818334Speter 341918334Speter /* Pad_below needs the pre-rounded size to know how much to pad below 342018334Speter so this must be done before rounding up. */ 3421132732Skan locate->offset = locate->slot_offset; 3422132732Skan if (where_pad == downward) 3423132732Skan pad_below (&locate->offset, passed_mode, sizetree); 342418334Speter 342518334Speter if (where_pad != none 342690091Sobrien && (!host_integerp (sizetree, 1) 342790091Sobrien || (tree_low_cst (sizetree, 1) * BITS_PER_UNIT) % PARM_BOUNDARY)) 342818334Speter sizetree = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT); 342918334Speter 3430132732Skan ADD_PARM_SIZE (locate->size, sizetree); 3431132732Skan 3432132732Skan locate->size.constant -= part_size_in_regs; 343318334Speter#endif /* ARGS_GROW_DOWNWARD */ 343418334Speter} 343518334Speter 343618334Speter/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY. 343718334Speter BOUNDARY is measured in bits, but must be a multiple of a storage unit. */ 343818334Speter 343918334Speterstatic void 3440132732Skanpad_to_arg_alignment (struct args_size *offset_ptr, int boundary, 3441132732Skan struct args_size *alignment_pad) 344218334Speter{ 344390091Sobrien tree save_var = NULL_TREE; 344490091Sobrien HOST_WIDE_INT save_constant = 0; 344518334Speter int boundary_in_bytes = boundary / BITS_PER_UNIT; 3446132732Skan HOST_WIDE_INT sp_offset = STACK_POINTER_OFFSET; 344790091Sobrien 3448132732Skan#ifdef SPARC_STACK_BOUNDARY_HACK 3449169702Skan /* ??? The SPARC port may claim a STACK_BOUNDARY higher than 3450169702Skan the real alignment of %sp. However, when it does this, the 3451169702Skan alignment of %sp+STACK_POINTER_OFFSET is STACK_BOUNDARY. */ 3452132732Skan if (SPARC_STACK_BOUNDARY_HACK) 3453132732Skan sp_offset = 0; 3454132732Skan#endif 3455132732Skan 345690091Sobrien if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY) 345790091Sobrien { 345890091Sobrien save_var = offset_ptr->var; 345990091Sobrien save_constant = offset_ptr->constant; 346090091Sobrien } 346190091Sobrien 346290091Sobrien alignment_pad->var = NULL_TREE; 346390091Sobrien alignment_pad->constant = 0; 346490091Sobrien 346518334Speter if (boundary > BITS_PER_UNIT) 346618334Speter { 346718334Speter if (offset_ptr->var) 346818334Speter { 3469132732Skan tree sp_offset_tree = ssize_int (sp_offset); 3470132732Skan tree offset = size_binop (PLUS_EXPR, 3471132732Skan ARGS_SIZE_TREE (*offset_ptr), 3472132732Skan sp_offset_tree); 347318334Speter#ifdef ARGS_GROW_DOWNWARD 3474132732Skan tree rounded = round_down (offset, boundary / BITS_PER_UNIT); 347518334Speter#else 3476132732Skan tree rounded = round_up (offset, boundary / BITS_PER_UNIT); 347718334Speter#endif 3478132732Skan 3479132732Skan offset_ptr->var = size_binop (MINUS_EXPR, rounded, sp_offset_tree); 3480132732Skan /* ARGS_SIZE_TREE includes constant term. */ 3481132732Skan offset_ptr->constant = 0; 3482117404Skan if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY) 3483117404Skan alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, 348490091Sobrien save_var); 348518334Speter } 348618334Speter else 348790091Sobrien { 3488132732Skan offset_ptr->constant = -sp_offset + 348918334Speter#ifdef ARGS_GROW_DOWNWARD 3490132732Skan FLOOR_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes); 349118334Speter#else 3492132732Skan CEIL_ROUND (offset_ptr->constant + sp_offset, boundary_in_bytes); 349318334Speter#endif 349490091Sobrien if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY) 349590091Sobrien alignment_pad->constant = offset_ptr->constant - save_constant; 349690091Sobrien } 349718334Speter } 349818334Speter} 349918334Speter 350018334Speterstatic void 3501132732Skanpad_below (struct args_size *offset_ptr, enum machine_mode passed_mode, tree sizetree) 350218334Speter{ 350318334Speter if (passed_mode != BLKmode) 350418334Speter { 350518334Speter if (GET_MODE_BITSIZE (passed_mode) % PARM_BOUNDARY) 350618334Speter offset_ptr->constant 350718334Speter += (((GET_MODE_BITSIZE (passed_mode) + PARM_BOUNDARY - 1) 350818334Speter / PARM_BOUNDARY * PARM_BOUNDARY / BITS_PER_UNIT) 350918334Speter - GET_MODE_SIZE (passed_mode)); 351018334Speter } 351118334Speter else 351218334Speter { 351318334Speter if (TREE_CODE (sizetree) != INTEGER_CST 351418334Speter || (TREE_INT_CST_LOW (sizetree) * BITS_PER_UNIT) % PARM_BOUNDARY) 351518334Speter { 351618334Speter /* Round the size up to multiple of PARM_BOUNDARY bits. */ 351718334Speter tree s2 = round_up (sizetree, PARM_BOUNDARY / BITS_PER_UNIT); 351818334Speter /* Add it in. */ 351918334Speter ADD_PARM_SIZE (*offset_ptr, s2); 352018334Speter SUB_PARM_SIZE (*offset_ptr, sizetree); 352118334Speter } 352218334Speter } 352318334Speter} 352418334Speter 352518334Speter/* Walk the tree of blocks describing the binding levels within a function 3526169702Skan and warn about variables the might be killed by setjmp or vfork. 352718334Speter This is done after calling flow_analysis and before global_alloc 352818334Speter clobbers the pseudo-regs to hard regs. */ 352918334Speter 353018334Spetervoid 3531169702Skansetjmp_vars_warning (tree block) 353218334Speter{ 353390091Sobrien tree decl, sub; 3534169702Skan 353518334Speter for (decl = BLOCK_VARS (block); decl; decl = TREE_CHAIN (decl)) 353618334Speter { 3537169702Skan if (TREE_CODE (decl) == VAR_DECL 3538132732Skan && DECL_RTL_SET_P (decl) 3539169702Skan && REG_P (DECL_RTL (decl)) 354018334Speter && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl)))) 3541169702Skan warning (0, "variable %q+D might be clobbered by %<longjmp%>" 3542169702Skan " or %<vfork%>", 3543169702Skan decl); 354418334Speter } 3545169702Skan 354618334Speter for (sub = BLOCK_SUBBLOCKS (block); sub; sub = TREE_CHAIN (sub)) 3547169702Skan setjmp_vars_warning (sub); 354818334Speter} 354918334Speter 3550169702Skan/* Do the appropriate part of setjmp_vars_warning 355118334Speter but for arguments instead of local variables. */ 355218334Speter 355318334Spetervoid 3554132732Skansetjmp_args_warning (void) 355518334Speter{ 355690091Sobrien tree decl; 355718334Speter for (decl = DECL_ARGUMENTS (current_function_decl); 355818334Speter decl; decl = TREE_CHAIN (decl)) 355918334Speter if (DECL_RTL (decl) != 0 3560169702Skan && REG_P (DECL_RTL (decl)) 356118334Speter && regno_clobbered_at_setjmp (REGNO (DECL_RTL (decl)))) 3562169702Skan warning (0, "argument %q+D might be clobbered by %<longjmp%> or %<vfork%>", 3563169702Skan decl); 356418334Speter} 356518334Speter 356618334Speter 356790091Sobrien/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END}, 356890091Sobrien and create duplicate blocks. */ 356990091Sobrien/* ??? Need an option to either create block fragments or to create 357090091Sobrien abstract origin duplicates of a source block. It really depends 357190091Sobrien on what optimization has been performed. */ 357218334Speter 357390091Sobrienvoid 3574132732Skanreorder_blocks (void) 357590091Sobrien{ 357690091Sobrien tree block = DECL_INITIAL (current_function_decl); 3577169702Skan VEC(tree,heap) *block_stack; 357890091Sobrien 357990091Sobrien if (block == NULL_TREE) 358090091Sobrien return; 358190091Sobrien 3582169702Skan block_stack = VEC_alloc (tree, heap, 10); 358390091Sobrien 358490091Sobrien /* Reset the TREE_ASM_WRITTEN bit for all blocks. */ 3585169702Skan clear_block_marks (block); 358690091Sobrien 358790091Sobrien /* Prune the old trees away, so that they don't get in the way. */ 358890091Sobrien BLOCK_SUBBLOCKS (block) = NULL_TREE; 358990091Sobrien BLOCK_CHAIN (block) = NULL_TREE; 359090091Sobrien 359190091Sobrien /* Recreate the block tree from the note nesting. */ 359290091Sobrien reorder_blocks_1 (get_insns (), block, &block_stack); 359390091Sobrien BLOCK_SUBBLOCKS (block) = blocks_nreverse (BLOCK_SUBBLOCKS (block)); 359490091Sobrien 3595169702Skan VEC_free (tree, heap, block_stack); 359690091Sobrien} 359790091Sobrien 359890091Sobrien/* Helper function for reorder_blocks. Reset TREE_ASM_WRITTEN. */ 359990091Sobrien 3600169702Skanvoid 3601169702Skanclear_block_marks (tree block) 360290091Sobrien{ 360390091Sobrien while (block) 360490091Sobrien { 360590091Sobrien TREE_ASM_WRITTEN (block) = 0; 3606169702Skan clear_block_marks (BLOCK_SUBBLOCKS (block)); 360790091Sobrien block = BLOCK_CHAIN (block); 360890091Sobrien } 360990091Sobrien} 361090091Sobrien 361190091Sobrienstatic void 3612169702Skanreorder_blocks_1 (rtx insns, tree current_block, VEC(tree,heap) **p_block_stack) 361318334Speter{ 361418334Speter rtx insn; 361518334Speter 361690091Sobrien for (insn = insns; insn; insn = NEXT_INSN (insn)) 361790091Sobrien { 3618169702Skan if (NOTE_P (insn)) 361990091Sobrien { 362090091Sobrien if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_BEG) 362190091Sobrien { 362290091Sobrien tree block = NOTE_BLOCK (insn); 3623169702Skan tree origin; 362418334Speter 3625169702Skan origin = (BLOCK_FRAGMENT_ORIGIN (block) 3626169702Skan ? BLOCK_FRAGMENT_ORIGIN (block) 3627169702Skan : block); 3628169702Skan 362990091Sobrien /* If we have seen this block before, that means it now 363090091Sobrien spans multiple address regions. Create a new fragment. */ 363190091Sobrien if (TREE_ASM_WRITTEN (block)) 363290091Sobrien { 363390091Sobrien tree new_block = copy_node (block); 363418334Speter 363590091Sobrien BLOCK_FRAGMENT_ORIGIN (new_block) = origin; 363690091Sobrien BLOCK_FRAGMENT_CHAIN (new_block) 363790091Sobrien = BLOCK_FRAGMENT_CHAIN (origin); 363890091Sobrien BLOCK_FRAGMENT_CHAIN (origin) = new_block; 363918334Speter 364090091Sobrien NOTE_BLOCK (insn) = new_block; 364190091Sobrien block = new_block; 364290091Sobrien } 364390091Sobrien 364490091Sobrien BLOCK_SUBBLOCKS (block) = 0; 364590091Sobrien TREE_ASM_WRITTEN (block) = 1; 3646132732Skan /* When there's only one block for the entire function, 3647132732Skan current_block == block and we mustn't do this, it 3648132732Skan will cause infinite recursion. */ 3649132732Skan if (block != current_block) 3650132732Skan { 3651169702Skan if (block != origin) 3652169702Skan gcc_assert (BLOCK_SUPERCONTEXT (origin) == current_block); 3653169702Skan 3654132732Skan BLOCK_SUPERCONTEXT (block) = current_block; 3655132732Skan BLOCK_CHAIN (block) = BLOCK_SUBBLOCKS (current_block); 3656132732Skan BLOCK_SUBBLOCKS (current_block) = block; 3657169702Skan current_block = origin; 3658132732Skan } 3659169702Skan VEC_safe_push (tree, heap, *p_block_stack, block); 366090091Sobrien } 366190091Sobrien else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_BLOCK_END) 366290091Sobrien { 3663169702Skan NOTE_BLOCK (insn) = VEC_pop (tree, *p_block_stack); 366490091Sobrien BLOCK_SUBBLOCKS (current_block) 366590091Sobrien = blocks_nreverse (BLOCK_SUBBLOCKS (current_block)); 366690091Sobrien current_block = BLOCK_SUPERCONTEXT (current_block); 366790091Sobrien } 366890091Sobrien } 366990091Sobrien } 367018334Speter} 367118334Speter 367218334Speter/* Reverse the order of elements in the chain T of blocks, 367318334Speter and return the new head of the chain (old last element). */ 367418334Speter 3675169702Skantree 3676132732Skanblocks_nreverse (tree t) 367718334Speter{ 367890091Sobrien tree prev = 0, decl, next; 367918334Speter for (decl = t; decl; decl = next) 368018334Speter { 368118334Speter next = BLOCK_CHAIN (decl); 368218334Speter BLOCK_CHAIN (decl) = prev; 368318334Speter prev = decl; 368418334Speter } 368518334Speter return prev; 368618334Speter} 368718334Speter 368890091Sobrien/* Count the subblocks of the list starting with BLOCK. If VECTOR is 368990091Sobrien non-NULL, list them all into VECTOR, in a depth-first preorder 369090091Sobrien traversal of the block tree. Also clear TREE_ASM_WRITTEN in all 369152268Sobrien blocks. */ 369218334Speter 369318334Speterstatic int 3694132732Skanall_blocks (tree block, tree *vector) 369518334Speter{ 369652268Sobrien int n_blocks = 0; 369718334Speter 369852268Sobrien while (block) 369952268Sobrien { 370052268Sobrien TREE_ASM_WRITTEN (block) = 0; 370118334Speter 370252268Sobrien /* Record this block. */ 370352268Sobrien if (vector) 370452268Sobrien vector[n_blocks] = block; 370518334Speter 370652268Sobrien ++n_blocks; 370790091Sobrien 370852268Sobrien /* Record the subblocks, and their subblocks... */ 370952268Sobrien n_blocks += all_blocks (BLOCK_SUBBLOCKS (block), 371052268Sobrien vector ? vector + n_blocks : 0); 371152268Sobrien block = BLOCK_CHAIN (block); 371252268Sobrien } 371352268Sobrien 371418334Speter return n_blocks; 371518334Speter} 371618334Speter 371790091Sobrien/* Return a vector containing all the blocks rooted at BLOCK. The 371890091Sobrien number of elements in the vector is stored in N_BLOCKS_P. The 371990091Sobrien vector is dynamically allocated; it is the caller's responsibility 372090091Sobrien to call `free' on the pointer returned. */ 372190091Sobrien 372290091Sobrienstatic tree * 3723132732Skanget_block_vector (tree block, int *n_blocks_p) 372490091Sobrien{ 372590091Sobrien tree *block_vector; 372690091Sobrien 372790091Sobrien *n_blocks_p = all_blocks (block, NULL); 3728169702Skan block_vector = XNEWVEC (tree, *n_blocks_p); 372990091Sobrien all_blocks (block, block_vector); 373090091Sobrien 373190091Sobrien return block_vector; 373290091Sobrien} 373390091Sobrien 3734132732Skanstatic GTY(()) int next_block_index = 2; 373590091Sobrien 373690091Sobrien/* Set BLOCK_NUMBER for all the blocks in FN. */ 373790091Sobrien 373818334Spetervoid 3739132732Skannumber_blocks (tree fn) 374018334Speter{ 374190091Sobrien int i; 374290091Sobrien int n_blocks; 374390091Sobrien tree *block_vector; 374490091Sobrien 374590091Sobrien /* For SDB and XCOFF debugging output, we start numbering the blocks 374690091Sobrien from 1 within each function, rather than keeping a running 374790091Sobrien count. */ 374890091Sobrien#if defined (SDB_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 374990091Sobrien if (write_symbols == SDB_DEBUG || write_symbols == XCOFF_DEBUG) 375090091Sobrien next_block_index = 1; 375190091Sobrien#endif 375290091Sobrien 375390091Sobrien block_vector = get_block_vector (DECL_INITIAL (fn), &n_blocks); 375490091Sobrien 375590091Sobrien /* The top-level BLOCK isn't numbered at all. */ 375690091Sobrien for (i = 1; i < n_blocks; ++i) 375790091Sobrien /* We number the blocks from two. */ 375890091Sobrien BLOCK_NUMBER (block_vector[i]) = next_block_index++; 375990091Sobrien 376090091Sobrien free (block_vector); 376190091Sobrien 376290091Sobrien return; 376390091Sobrien} 376490091Sobrien 376590091Sobrien/* If VAR is present in a subblock of BLOCK, return the subblock. */ 376690091Sobrien 376790091Sobrientree 3768132732Skandebug_find_var_in_block_tree (tree var, tree block) 376990091Sobrien{ 377090091Sobrien tree t; 377190091Sobrien 377290091Sobrien for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t)) 377390091Sobrien if (t == var) 377490091Sobrien return block; 377590091Sobrien 377690091Sobrien for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t)) 377790091Sobrien { 377890091Sobrien tree ret = debug_find_var_in_block_tree (var, t); 377990091Sobrien if (ret) 378090091Sobrien return ret; 378190091Sobrien } 378290091Sobrien 378390091Sobrien return NULL_TREE; 378490091Sobrien} 378590091Sobrien 3786132732Skan/* Allocate a function structure for FNDECL and set its contents 3787132732Skan to the defaults. */ 378890091Sobrien 3789132732Skanvoid 3790132732Skanallocate_struct_function (tree fndecl) 379190091Sobrien{ 3792132732Skan tree result; 3793169702Skan tree fntype = fndecl ? TREE_TYPE (fndecl) : NULL_TREE; 379490091Sobrien 3795132732Skan cfun = ggc_alloc_cleared (sizeof (struct function)); 379618334Speter 3797132732Skan cfun->stack_alignment_needed = STACK_BOUNDARY; 3798132732Skan cfun->preferred_stack_boundary = STACK_BOUNDARY; 379918334Speter 3800132732Skan current_function_funcdef_no = funcdef_no++; 380118334Speter 3802132732Skan cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL; 380318334Speter 3804132732Skan init_eh_for_function (); 380518334Speter 3806169702Skan lang_hooks.function.init (cfun); 3807132732Skan if (init_machine_status) 3808132732Skan cfun->machine = (*init_machine_status) (); 380918334Speter 3810132732Skan if (fndecl == NULL) 3811132732Skan return; 381218334Speter 3813169702Skan DECL_STRUCT_FUNCTION (fndecl) = cfun; 3814132732Skan cfun->decl = fndecl; 381518334Speter 3816132732Skan result = DECL_RESULT (fndecl); 3817132732Skan if (aggregate_value_p (result, fndecl)) 3818132732Skan { 3819132732Skan#ifdef PCC_STATIC_STRUCT_RETURN 3820132732Skan current_function_returns_pcc_struct = 1; 3821132732Skan#endif 3822132732Skan current_function_returns_struct = 1; 3823132732Skan } 382418334Speter 3825132732Skan current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result)); 382618334Speter 3827169702Skan current_function_stdarg 3828169702Skan = (fntype 3829169702Skan && TYPE_ARG_TYPES (fntype) != 0 3830169702Skan && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) 3831169702Skan != void_type_node)); 3832169702Skan 3833169702Skan /* Assume all registers in stdarg functions need to be saved. */ 3834169702Skan cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE; 3835169702Skan cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; 3836132732Skan} 383718334Speter 3838132732Skan/* Reset cfun, and other non-struct-function variables to defaults as 3839132732Skan appropriate for emitting rtl at the start of a function. */ 384018334Speter 3841132732Skanstatic void 3842132732Skanprepare_function_start (tree fndecl) 3843132732Skan{ 3844169702Skan if (fndecl && DECL_STRUCT_FUNCTION (fndecl)) 3845169702Skan cfun = DECL_STRUCT_FUNCTION (fndecl); 3846132732Skan else 3847132732Skan allocate_struct_function (fndecl); 3848132732Skan init_emit (); 3849132732Skan init_varasm_status (cfun); 3850132732Skan init_expr (); 385118334Speter 3852132732Skan cse_not_expected = ! optimize; 385318334Speter 3854132732Skan /* Caller save not needed yet. */ 3855132732Skan caller_save_needed = 0; 385618334Speter 3857132732Skan /* We haven't done register allocation yet. */ 3858132732Skan reg_renumber = 0; 385918334Speter 386090091Sobrien /* Indicate that we have not instantiated virtual registers yet. */ 386190091Sobrien virtuals_instantiated = 0; 386290091Sobrien 386390091Sobrien /* Indicate that we want CONCATs now. */ 386490091Sobrien generating_concat_p = 1; 386590091Sobrien 386690091Sobrien /* Indicate we have no need of a frame pointer yet. */ 386790091Sobrien frame_pointer_needed = 0; 386890091Sobrien} 386990091Sobrien 387090091Sobrien/* Initialize the rtl expansion mechanism so that we can do simple things 387190091Sobrien like generate sequences. This is used to provide a context during global 387290091Sobrien initialization of some passes. */ 387390091Sobrienvoid 3874132732Skaninit_dummy_function_start (void) 387590091Sobrien{ 3876132732Skan prepare_function_start (NULL); 387790091Sobrien} 387890091Sobrien 387990091Sobrien/* Generate RTL for the start of the function SUBR (a FUNCTION_DECL tree node) 388090091Sobrien and initialize static variables for generating RTL for the statements 388190091Sobrien of the function. */ 388290091Sobrien 388390091Sobrienvoid 3884132732Skaninit_function_start (tree subr) 388590091Sobrien{ 3886132732Skan prepare_function_start (subr); 388790091Sobrien 3888132732Skan /* Prevent ever trying to delete the first instruction of a 3889132732Skan function. Also tell final how to output a linenum before the 3890132732Skan function prologue. Note linenums could be missing, e.g. when 3891132732Skan compiling a Java .class file. */ 3892169702Skan if (! DECL_IS_BUILTIN (subr)) 3893132732Skan emit_line_note (DECL_SOURCE_LOCATION (subr)); 389418334Speter 389518334Speter /* Make sure first insn is a note even if we don't want linenums. 389618334Speter This makes sure the first insn will never be deleted. 389718334Speter Also, final expects a note to appear there. */ 3898132732Skan emit_note (NOTE_INSN_DELETED); 389918334Speter 390018334Speter /* Warn if this value is an aggregate type, 390118334Speter regardless of which calling convention we are using for it. */ 3902169702Skan if (AGGREGATE_TYPE_P (TREE_TYPE (DECL_RESULT (subr)))) 3903169702Skan warning (OPT_Waggregate_return, "function returns an aggregate"); 390490091Sobrien} 390518334Speter 390690091Sobrien/* Make sure all values used by the optimization passes have sane 390790091Sobrien defaults. */ 3908169702Skanunsigned int 3909132732Skaninit_function_for_compilation (void) 391090091Sobrien{ 391190091Sobrien reg_renumber = 0; 391218334Speter 3913169702Skan /* No prologue/epilogue insns yet. Make sure that these vectors are 3914169702Skan empty. */ 3915169702Skan gcc_assert (VEC_length (int, prologue) == 0); 3916169702Skan gcc_assert (VEC_length (int, epilogue) == 0); 3917169702Skan gcc_assert (VEC_length (int, sibcall_epilogue) == 0); 3918169702Skan return 0; 391918334Speter} 392018334Speter 3921169702Skanstruct tree_opt_pass pass_init_function = 3922169702Skan{ 3923169702Skan NULL, /* name */ 3924169702Skan NULL, /* gate */ 3925169702Skan init_function_for_compilation, /* execute */ 3926169702Skan NULL, /* sub */ 3927169702Skan NULL, /* next */ 3928169702Skan 0, /* static_pass_number */ 3929169702Skan 0, /* tv_id */ 3930169702Skan 0, /* properties_required */ 3931169702Skan 0, /* properties_provided */ 3932169702Skan 0, /* properties_destroyed */ 3933169702Skan 0, /* todo_flags_start */ 3934169702Skan 0, /* todo_flags_finish */ 3935169702Skan 0 /* letter */ 3936169702Skan}; 393718334Speter 393818334Speter 393918334Spetervoid 3940132732Skanexpand_main_function (void) 394118334Speter{ 3942169702Skan#if (defined(INVOKE__main) \ 3943169702Skan || (!defined(HAS_INIT_SECTION) \ 3944169702Skan && !defined(INIT_SECTION_ASM_OP) \ 3945169702Skan && !defined(INIT_ARRAY_SECTION_ASM_OP))) 3946169702Skan emit_library_call (init_one_libfunc (NAME__MAIN), LCT_NORMAL, VOIDmode, 0); 3947169702Skan#endif 3948169702Skan} 3949169702Skan 3950169702Skan/* Expand code to initialize the stack_protect_guard. This is invoked at 3951169702Skan the beginning of a function to be protected. */ 395290091Sobrien 3953169702Skan#ifndef HAVE_stack_protect_set 3954169702Skan# define HAVE_stack_protect_set 0 3955169702Skan# define gen_stack_protect_set(x,y) (gcc_unreachable (), NULL_RTX) 395690091Sobrien#endif 3957117404Skan 3958169702Skanvoid 3959169702Skanstack_protect_prologue (void) 3960169702Skan{ 3961169702Skan tree guard_decl = targetm.stack_protect_guard (); 3962169702Skan rtx x, y; 396390091Sobrien 3964169702Skan /* Avoid expand_expr here, because we don't want guard_decl pulled 3965169702Skan into registers unless absolutely necessary. And we know that 3966169702Skan cfun->stack_protect_guard is a local stack slot, so this skips 3967169702Skan all the fluff. */ 3968169702Skan x = validize_mem (DECL_RTL (cfun->stack_protect_guard)); 3969169702Skan y = validize_mem (DECL_RTL (guard_decl)); 3970169702Skan 3971169702Skan /* Allow the target to copy from Y to X without leaking Y into a 3972169702Skan register. */ 3973169702Skan if (HAVE_stack_protect_set) 3974169702Skan { 3975169702Skan rtx insn = gen_stack_protect_set (x, y); 3976169702Skan if (insn) 3977169702Skan { 3978169702Skan emit_insn (insn); 3979169702Skan return; 3980169702Skan } 398190091Sobrien } 398290091Sobrien 3983169702Skan /* Otherwise do a straight move. */ 3984169702Skan emit_move_insn (x, y); 398518334Speter} 398690091Sobrien 3987169702Skan/* Expand code to verify the stack_protect_guard. This is invoked at 3988169702Skan the end of a function to be protected. */ 3989169702Skan 3990169702Skan#ifndef HAVE_stack_protect_test 3991169702Skan# define HAVE_stack_protect_test 0 3992169702Skan# define gen_stack_protect_test(x, y, z) (gcc_unreachable (), NULL_RTX) 3993169702Skan#endif 3994169702Skan 399590091Sobrienvoid 3996169702Skanstack_protect_epilogue (void) 399790091Sobrien{ 3998169702Skan tree guard_decl = targetm.stack_protect_guard (); 3999169702Skan rtx label = gen_label_rtx (); 4000169702Skan rtx x, y, tmp; 400190091Sobrien 4002169702Skan /* Avoid expand_expr here, because we don't want guard_decl pulled 4003169702Skan into registers unless absolutely necessary. And we know that 4004169702Skan cfun->stack_protect_guard is a local stack slot, so this skips 4005169702Skan all the fluff. */ 4006169702Skan x = validize_mem (DECL_RTL (cfun->stack_protect_guard)); 4007169702Skan y = validize_mem (DECL_RTL (guard_decl)); 4008169702Skan 4009169702Skan /* Allow the target to compare Y with X without leaking either into 4010169702Skan a register. */ 4011222207Sbenl if (HAVE_stack_protect_test != 0) 401290091Sobrien { 4013169702Skan tmp = gen_stack_protect_test (x, y, label); 4014169702Skan if (tmp) 4015169702Skan { 4016169702Skan emit_insn (tmp); 4017222207Sbenl goto done; 4018169702Skan } 401990091Sobrien } 4020169702Skan 4021222207Sbenl emit_cmp_and_jump_insns (x, y, EQ, NULL_RTX, ptr_mode, 1, label); 4022222207Sbenl done: 4023222207Sbenl 4024169702Skan /* The noreturn predictor has been moved to the tree level. The rtl-level 4025169702Skan predictors estimate this branch about 20%, which isn't enough to get 4026169702Skan things moved out of line. Since this is the only extant case of adding 4027169702Skan a noreturn function at the rtl level, it doesn't seem worth doing ought 4028169702Skan except adding the prediction by hand. */ 4029169702Skan tmp = get_last_insn (); 4030169702Skan if (JUMP_P (tmp)) 4031169702Skan predict_insn_def (tmp, PRED_NORETURN, TAKEN); 4032169702Skan 4033169702Skan expand_expr_stmt (targetm.stack_protect_fail ()); 4034169702Skan emit_label (label); 403590091Sobrien} 4036169702Skan 403718334Speter/* Start the RTL for a new function, and set variables used for 403818334Speter emitting RTL. 403918334Speter SUBR is the FUNCTION_DECL node. 404018334Speter PARMS_HAVE_CLEANUPS is nonzero if there are cleanups associated with 404118334Speter the function's parameters, which must be run at any return statement. */ 404218334Speter 404318334Spetervoid 4044169702Skanexpand_function_start (tree subr) 404518334Speter{ 404618334Speter /* Make sure volatile mem refs aren't considered 404718334Speter valid operands of arithmetic insns. */ 404818334Speter init_recog_no_volatile (); 404918334Speter 405090091Sobrien current_function_profile 405190091Sobrien = (profile_flag 405290091Sobrien && ! DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (subr)); 405390091Sobrien 405490091Sobrien current_function_limit_stack 405590091Sobrien = (stack_limit_rtx != NULL_RTX && ! DECL_NO_LIMIT_STACK (subr)); 405690091Sobrien 405790091Sobrien /* Make the label for return statements to jump to. Do not special 405890091Sobrien case machines with special return instructions -- they will be 405990091Sobrien handled later during jump, ifcvt, or epilogue creation. */ 406018334Speter return_label = gen_label_rtx (); 406118334Speter 406218334Speter /* Initialize rtx used to return the value. */ 406318334Speter /* Do this before assign_parms so that we copy the struct value address 406418334Speter before any library calls that assign parms might generate. */ 406518334Speter 406618334Speter /* Decide whether to return the value in memory or in a register. */ 4067132732Skan if (aggregate_value_p (DECL_RESULT (subr), subr)) 406818334Speter { 406918334Speter /* Returning something that won't go in a register. */ 407090091Sobrien rtx value_address = 0; 407118334Speter 407218334Speter#ifdef PCC_STATIC_STRUCT_RETURN 407318334Speter if (current_function_returns_pcc_struct) 407418334Speter { 407518334Speter int size = int_size_in_bytes (TREE_TYPE (DECL_RESULT (subr))); 407618334Speter value_address = assemble_static_space (size); 407718334Speter } 407818334Speter else 407918334Speter#endif 408018334Speter { 4081169702Skan rtx sv = targetm.calls.struct_value_rtx (TREE_TYPE (subr), 2); 408218334Speter /* Expect to be passed the address of a place to store the value. 408318334Speter If it is passed as an argument, assign_parms will take care of 408418334Speter it. */ 4085132732Skan if (sv) 408618334Speter { 408718334Speter value_address = gen_reg_rtx (Pmode); 4088132732Skan emit_move_insn (value_address, sv); 408918334Speter } 409018334Speter } 409118334Speter if (value_address) 409218334Speter { 4093169702Skan rtx x = value_address; 4094169702Skan if (!DECL_BY_REFERENCE (DECL_RESULT (subr))) 4095169702Skan { 4096169702Skan x = gen_rtx_MEM (DECL_MODE (DECL_RESULT (subr)), x); 4097169702Skan set_mem_attributes (x, DECL_RESULT (subr), 1); 4098169702Skan } 409990091Sobrien SET_DECL_RTL (DECL_RESULT (subr), x); 410018334Speter } 410118334Speter } 410218334Speter else if (DECL_MODE (DECL_RESULT (subr)) == VOIDmode) 410318334Speter /* If return mode is void, this decl rtl should not be used. */ 410490091Sobrien SET_DECL_RTL (DECL_RESULT (subr), NULL_RTX); 410590091Sobrien else 410618334Speter { 410790091Sobrien /* Compute the return values into a pseudo reg, which we will copy 410890091Sobrien into the true return register after the cleanups are done. */ 4109169702Skan tree return_type = TREE_TYPE (DECL_RESULT (subr)); 4110169702Skan if (TYPE_MODE (return_type) != BLKmode 4111169702Skan && targetm.calls.return_in_msb (return_type)) 4112169702Skan /* expand_function_end will insert the appropriate padding in 4113169702Skan this case. Use the return value's natural (unpadded) mode 4114169702Skan within the function proper. */ 4115169702Skan SET_DECL_RTL (DECL_RESULT (subr), 4116169702Skan gen_reg_rtx (TYPE_MODE (return_type))); 4117169702Skan else 4118169702Skan { 4119169702Skan /* In order to figure out what mode to use for the pseudo, we 4120169702Skan figure out what the mode of the eventual return register will 4121169702Skan actually be, and use that. */ 4122169702Skan rtx hard_reg = hard_function_value (return_type, subr, 0, 1); 412318334Speter 4124169702Skan /* Structures that are returned in registers are not 4125169702Skan aggregate_value_p, so we may see a PARALLEL or a REG. */ 4126169702Skan if (REG_P (hard_reg)) 4127169702Skan SET_DECL_RTL (DECL_RESULT (subr), 4128169702Skan gen_reg_rtx (GET_MODE (hard_reg))); 4129169702Skan else 4130169702Skan { 4131169702Skan gcc_assert (GET_CODE (hard_reg) == PARALLEL); 4132169702Skan SET_DECL_RTL (DECL_RESULT (subr), gen_group_rtx (hard_reg)); 4133169702Skan } 4134169702Skan } 413518334Speter 4136117404Skan /* Set DECL_REGISTER flag so that expand_function_end will copy the 4137117404Skan result to the real return register(s). */ 4138117404Skan DECL_REGISTER (DECL_RESULT (subr)) = 1; 413918334Speter } 414018334Speter 414118334Speter /* Initialize rtx for parameters and local variables. 414218334Speter In some cases this requires emitting insns. */ 414390091Sobrien assign_parms (subr); 414418334Speter 4145169702Skan /* If function gets a static chain arg, store it. */ 4146169702Skan if (cfun->static_chain_decl) 4147169702Skan { 4148169702Skan tree parm = cfun->static_chain_decl; 4149169702Skan rtx local = gen_reg_rtx (Pmode); 415018334Speter 4151169702Skan set_decl_incoming_rtl (parm, static_chain_incoming_rtx); 4152169702Skan SET_DECL_RTL (parm, local); 4153169702Skan mark_reg_pointer (local, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm)))); 415418334Speter 4155169702Skan emit_move_insn (local, static_chain_incoming_rtx); 4156169702Skan } 4157169702Skan 4158169702Skan /* If the function receives a non-local goto, then store the 4159169702Skan bits we need to restore the frame pointer. */ 4160169702Skan if (cfun->nonlocal_goto_save_area) 4161169702Skan { 4162169702Skan tree t_save; 4163169702Skan rtx r_save; 4164169702Skan 4165169702Skan /* ??? We need to do this save early. Unfortunately here is 4166169702Skan before the frame variable gets declared. Help out... */ 4167169702Skan expand_var (TREE_OPERAND (cfun->nonlocal_goto_save_area, 0)); 4168169702Skan 4169169702Skan t_save = build4 (ARRAY_REF, ptr_type_node, 4170169702Skan cfun->nonlocal_goto_save_area, 4171169702Skan integer_zero_node, NULL_TREE, NULL_TREE); 4172169702Skan r_save = expand_expr (t_save, NULL_RTX, VOIDmode, EXPAND_WRITE); 4173169702Skan r_save = convert_memory_address (Pmode, r_save); 4174169702Skan 4175169702Skan emit_move_insn (r_save, virtual_stack_vars_rtx); 4176169702Skan update_nonlocal_goto_save_area (); 4177169702Skan } 4178169702Skan 417918334Speter /* The following was moved from init_function_start. 418018334Speter The move is supposed to make sdb output more accurate. */ 418118334Speter /* Indicate the beginning of the function body, 418218334Speter as opposed to parm setup. */ 4183132732Skan emit_note (NOTE_INSN_FUNCTION_BEG); 418418334Speter 4185169702Skan gcc_assert (NOTE_P (get_last_insn ())); 4186169702Skan 418718334Speter parm_birth_insn = get_last_insn (); 418818334Speter 418996283Sobrien if (current_function_profile) 419096283Sobrien { 419190091Sobrien#ifdef PROFILE_HOOK 4192117404Skan PROFILE_HOOK (current_function_funcdef_no); 419390091Sobrien#endif 419496283Sobrien } 419590091Sobrien 4196169702Skan /* After the display initializations is where the stack checking 4197169702Skan probe should go. */ 4198169702Skan if(flag_stack_check) 4199169702Skan stack_check_probe_note = emit_note (NOTE_INSN_DELETED); 420018334Speter 420118334Speter /* Make sure there is a line number after the function entry setup code. */ 420218334Speter force_next_line_note (); 420318334Speter} 420418334Speter 420590091Sobrien/* Undo the effects of init_dummy_function_start. */ 420690091Sobrienvoid 4207132732Skanexpand_dummy_function_end (void) 420890091Sobrien{ 420990091Sobrien /* End any sequences that failed to be closed due to syntax errors. */ 421090091Sobrien while (in_sequence_p ()) 421190091Sobrien end_sequence (); 421290091Sobrien 421390091Sobrien /* Outside function body, can't compute type's actual size 421490091Sobrien until next function's body starts. */ 421590091Sobrien 421690091Sobrien free_after_parsing (cfun); 421790091Sobrien free_after_compilation (cfun); 421890091Sobrien cfun = 0; 421990091Sobrien} 422090091Sobrien 422190091Sobrien/* Call DOIT for each hard register used as a return value from 422290091Sobrien the current function. */ 422390091Sobrien 422490091Sobrienvoid 4225132732Skandiddle_return_value (void (*doit) (rtx, void *), void *arg) 422690091Sobrien{ 422790091Sobrien rtx outgoing = current_function_return_rtx; 422890091Sobrien 422990091Sobrien if (! outgoing) 423090091Sobrien return; 423190091Sobrien 4232169702Skan if (REG_P (outgoing)) 423390091Sobrien (*doit) (outgoing, arg); 423490091Sobrien else if (GET_CODE (outgoing) == PARALLEL) 423590091Sobrien { 423690091Sobrien int i; 423790091Sobrien 423890091Sobrien for (i = 0; i < XVECLEN (outgoing, 0); i++) 423990091Sobrien { 424090091Sobrien rtx x = XEXP (XVECEXP (outgoing, 0, i), 0); 424190091Sobrien 4242169702Skan if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER) 424390091Sobrien (*doit) (x, arg); 424490091Sobrien } 424590091Sobrien } 424690091Sobrien} 424790091Sobrien 424890091Sobrienstatic void 4249132732Skando_clobber_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED) 425090091Sobrien{ 425190091Sobrien emit_insn (gen_rtx_CLOBBER (VOIDmode, reg)); 425290091Sobrien} 425390091Sobrien 425490091Sobrienvoid 4255132732Skanclobber_return_register (void) 425690091Sobrien{ 425790091Sobrien diddle_return_value (do_clobber_return_reg, NULL); 425890091Sobrien 425990091Sobrien /* In case we do use pseudo to return value, clobber it too. */ 426090091Sobrien if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl))) 426190091Sobrien { 426290091Sobrien tree decl_result = DECL_RESULT (current_function_decl); 426390091Sobrien rtx decl_rtl = DECL_RTL (decl_result); 426490091Sobrien if (REG_P (decl_rtl) && REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER) 426590091Sobrien { 426690091Sobrien do_clobber_return_reg (decl_rtl, NULL); 426790091Sobrien } 426890091Sobrien } 426990091Sobrien} 427090091Sobrien 427190091Sobrienstatic void 4272132732Skando_use_return_reg (rtx reg, void *arg ATTRIBUTE_UNUSED) 427390091Sobrien{ 427490091Sobrien emit_insn (gen_rtx_USE (VOIDmode, reg)); 427590091Sobrien} 427690091Sobrien 4277169702Skanstatic void 4278132732Skanuse_return_register (void) 427990091Sobrien{ 428090091Sobrien diddle_return_value (do_use_return_reg, NULL); 428190091Sobrien} 428290091Sobrien 4283132732Skan/* Possibly warn about unused parameters. */ 4284132732Skanvoid 4285132732Skando_warn_unused_parameter (tree fn) 4286132732Skan{ 4287132732Skan tree decl; 4288132732Skan 4289132732Skan for (decl = DECL_ARGUMENTS (fn); 4290132732Skan decl; decl = TREE_CHAIN (decl)) 4291132732Skan if (!TREE_USED (decl) && TREE_CODE (decl) == PARM_DECL 4292132732Skan && DECL_NAME (decl) && !DECL_ARTIFICIAL (decl)) 4293169702Skan warning (OPT_Wunused_parameter, "unused parameter %q+D", decl); 4294132732Skan} 4295132732Skan 4296117404Skanstatic GTY(()) rtx initial_trampoline; 4297117404Skan 4298132732Skan/* Generate RTL for the end of the current function. */ 429918334Speter 430018334Spetervoid 4301132732Skanexpand_function_end (void) 430218334Speter{ 430390091Sobrien rtx clobber_after; 430418334Speter 430590091Sobrien /* If arg_pointer_save_area was referenced only from a nested 430690091Sobrien function, we will not have initialized it yet. Do that now. */ 430790091Sobrien if (arg_pointer_save_area && ! cfun->arg_pointer_save_area_init) 430890091Sobrien get_arg_pointer_save_area (cfun); 430990091Sobrien 431052268Sobrien /* If we are doing stack checking and this function makes calls, 431152268Sobrien do a stack probe at the start of the function to ensure we have enough 431252268Sobrien space for another stack frame. */ 431352268Sobrien if (flag_stack_check && ! STACK_CHECK_BUILTIN) 431452268Sobrien { 431552268Sobrien rtx insn, seq; 431652268Sobrien 431752268Sobrien for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) 4318169702Skan if (CALL_P (insn)) 431952268Sobrien { 432052268Sobrien start_sequence (); 432152268Sobrien probe_stack_range (STACK_CHECK_PROTECT, 432252268Sobrien GEN_INT (STACK_CHECK_MAX_FRAME_SIZE)); 432352268Sobrien seq = get_insns (); 432452268Sobrien end_sequence (); 4325169702Skan emit_insn_before (seq, stack_check_probe_note); 432652268Sobrien break; 432752268Sobrien } 432852268Sobrien } 432952268Sobrien 4330132732Skan /* Possibly warn about unused parameters. 4331132732Skan When frontend does unit-at-a-time, the warning is already 4332132732Skan issued at finalization time. */ 4333132732Skan if (warn_unused_parameter 4334132732Skan && !lang_hooks.callgraph.expand_function) 4335132732Skan do_warn_unused_parameter (current_function_decl); 433618334Speter 433718334Speter /* End any sequences that failed to be closed due to syntax errors. */ 433818334Speter while (in_sequence_p ()) 433918334Speter end_sequence (); 434018334Speter 434118334Speter clear_pending_stack_adjust (); 434218334Speter do_pending_stack_adjust (); 434318334Speter 434418334Speter /* Mark the end of the function body. 434518334Speter If control reaches this insn, the function can drop through 434618334Speter without returning a value. */ 4347132732Skan emit_note (NOTE_INSN_FUNCTION_END); 434818334Speter 434952268Sobrien /* Must mark the last line number note in the function, so that the test 435052268Sobrien coverage code can avoid counting the last line twice. This just tells 435152268Sobrien the code to ignore the immediately following line note, since there 435252268Sobrien already exists a copy of this note somewhere above. This line number 435352268Sobrien note is still needed for debugging though, so we can't delete it. */ 435452268Sobrien if (flag_test_coverage) 4355132732Skan emit_note (NOTE_INSN_REPEATED_LINE_NUMBER); 435652268Sobrien 435718334Speter /* Output a linenumber for the end of the function. 435818334Speter SDB depends on this. */ 4359132732Skan force_next_line_note (); 4360132732Skan emit_line_note (input_location); 436118334Speter 436290091Sobrien /* Before the return label (if any), clobber the return 436390091Sobrien registers so that they are not propagated live to the rest of 436490091Sobrien the function. This can only happen with functions that drop 436590091Sobrien through; if there had been a return statement, there would 436690091Sobrien have either been a return rtx, or a jump to the return label. 436790091Sobrien 436890091Sobrien We delay actual code generation after the current_function_value_rtx 436990091Sobrien is computed. */ 437090091Sobrien clobber_after = get_last_insn (); 437190091Sobrien 4372169702Skan /* Output the label for the actual return from the function. */ 4373169702Skan emit_label (return_label); 437418334Speter 4375124167Sbde#ifdef TARGET_PROFILER_EPILOGUE 4376124160Skan if (current_function_profile && TARGET_PROFILER_EPILOGUE) 4377124160Skan { 4378124160Skan static rtx mexitcount_libfunc; 4379124160Skan static int initialized; 4380124160Skan 4381124160Skan if (!initialized) 4382124160Skan { 4383124160Skan mexitcount_libfunc = init_one_libfunc (".mexitcount"); 4384169702Skan initialized = 0; 4385124160Skan } 4386124160Skan emit_library_call (mexitcount_libfunc, LCT_NORMAL, VOIDmode, 0); 4387124160Skan } 4388124167Sbde#endif 4389124160Skan 4390169702Skan if (USING_SJLJ_EXCEPTIONS) 4391132732Skan { 4392169702Skan /* Let except.c know where it should emit the call to unregister 4393169702Skan the function context for sjlj exceptions. */ 4394169702Skan if (flag_exceptions) 4395169702Skan sjlj_emit_function_exit_after (get_last_insn ()); 4396132732Skan } 4397169702Skan else 4398169702Skan { 4399169702Skan /* @@@ This is a kludge. We want to ensure that instructions that 4400169702Skan may trap are not moved into the epilogue by scheduling, because 4401169702Skan we don't always emit unwind information for the epilogue. 4402169702Skan However, not all machine descriptions define a blockage insn, so 4403169702Skan emit an ASM_INPUT to act as one. */ 4404169702Skan if (flag_non_call_exceptions) 4405169702Skan emit_insn (gen_rtx_ASM_INPUT (VOIDmode, "")); 4406169702Skan } 440718334Speter 4408169702Skan /* If this is an implementation of throw, do what's necessary to 4409169702Skan communicate between __builtin_eh_return and the epilogue. */ 4410169702Skan expand_eh_return (); 4411169702Skan 441290091Sobrien /* If scalar return value was computed in a pseudo-reg, or was a named 441390091Sobrien return value that got dumped to the stack, copy that to the hard 441490091Sobrien return register. */ 441590091Sobrien if (DECL_RTL_SET_P (DECL_RESULT (current_function_decl))) 441618334Speter { 441790091Sobrien tree decl_result = DECL_RESULT (current_function_decl); 441890091Sobrien rtx decl_rtl = DECL_RTL (decl_result); 441918334Speter 442090091Sobrien if (REG_P (decl_rtl) 442190091Sobrien ? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER 442290091Sobrien : DECL_REGISTER (decl_result)) 442390091Sobrien { 442496283Sobrien rtx real_decl_rtl = current_function_return_rtx; 442590091Sobrien 442696283Sobrien /* This should be set in assign_parms. */ 4427169702Skan gcc_assert (REG_FUNCTION_VALUE_P (real_decl_rtl)); 442852268Sobrien 442990091Sobrien /* If this is a BLKmode structure being returned in registers, 443090091Sobrien then use the mode computed in expand_return. Note that if 4431117404Skan decl_rtl is memory, then its mode may have been changed, 443290091Sobrien but that current_function_return_rtx has not. */ 443390091Sobrien if (GET_MODE (real_decl_rtl) == BLKmode) 443496283Sobrien PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl)); 443590091Sobrien 4436169702Skan /* If a non-BLKmode return value should be padded at the least 4437169702Skan significant end of the register, shift it left by the appropriate 4438169702Skan amount. BLKmode results are handled using the group load/store 4439169702Skan machinery. */ 4440169702Skan if (TYPE_MODE (TREE_TYPE (decl_result)) != BLKmode 4441169702Skan && targetm.calls.return_in_msb (TREE_TYPE (decl_result))) 4442169702Skan { 4443169702Skan emit_move_insn (gen_rtx_REG (GET_MODE (decl_rtl), 4444169702Skan REGNO (real_decl_rtl)), 4445169702Skan decl_rtl); 4446169702Skan shift_return_value (GET_MODE (decl_rtl), true, real_decl_rtl); 4447169702Skan } 444890091Sobrien /* If a named return value dumped decl_return to memory, then 4449117404Skan we may need to re-do the PROMOTE_MODE signed/unsigned 445090091Sobrien extension. */ 4451169702Skan else if (GET_MODE (real_decl_rtl) != GET_MODE (decl_rtl)) 445290091Sobrien { 4453169702Skan int unsignedp = TYPE_UNSIGNED (TREE_TYPE (decl_result)); 445490091Sobrien 4455132732Skan if (targetm.calls.promote_function_return (TREE_TYPE (current_function_decl))) 4456132732Skan promote_mode (TREE_TYPE (decl_result), GET_MODE (decl_rtl), 4457132732Skan &unsignedp, 1); 445890091Sobrien 445990091Sobrien convert_move (real_decl_rtl, decl_rtl, unsignedp); 446090091Sobrien } 446190091Sobrien else if (GET_CODE (real_decl_rtl) == PARALLEL) 4462117404Skan { 4463117404Skan /* If expand_function_start has created a PARALLEL for decl_rtl, 4464117404Skan move the result to the real return registers. Otherwise, do 4465117404Skan a group load from decl_rtl for a named return. */ 4466117404Skan if (GET_CODE (decl_rtl) == PARALLEL) 4467117404Skan emit_group_move (real_decl_rtl, decl_rtl); 4468117404Skan else 4469117404Skan emit_group_load (real_decl_rtl, decl_rtl, 4470132732Skan TREE_TYPE (decl_result), 4471117404Skan int_size_in_bytes (TREE_TYPE (decl_result))); 4472117404Skan } 4473169702Skan /* In the case of complex integer modes smaller than a word, we'll 4474169702Skan need to generate some non-trivial bitfield insertions. Do that 4475169702Skan on a pseudo and not the hard register. */ 4476169702Skan else if (GET_CODE (decl_rtl) == CONCAT 4477169702Skan && GET_MODE_CLASS (GET_MODE (decl_rtl)) == MODE_COMPLEX_INT 4478169702Skan && GET_MODE_BITSIZE (GET_MODE (decl_rtl)) <= BITS_PER_WORD) 4479169702Skan { 4480169702Skan int old_generating_concat_p; 4481169702Skan rtx tmp; 4482169702Skan 4483169702Skan old_generating_concat_p = generating_concat_p; 4484169702Skan generating_concat_p = 0; 4485169702Skan tmp = gen_reg_rtx (GET_MODE (decl_rtl)); 4486169702Skan generating_concat_p = old_generating_concat_p; 4487169702Skan 4488169702Skan emit_move_insn (tmp, decl_rtl); 4489169702Skan emit_move_insn (real_decl_rtl, tmp); 4490169702Skan } 449190091Sobrien else 449290091Sobrien emit_move_insn (real_decl_rtl, decl_rtl); 449390091Sobrien } 449418334Speter } 449518334Speter 449618334Speter /* If returning a structure, arrange to return the address of the value 449718334Speter in a place where debuggers expect to find it. 449818334Speter 449918334Speter If returning a structure PCC style, 450018334Speter the caller also depends on this value. 450118334Speter And current_function_returns_pcc_struct is not necessarily set. */ 450218334Speter if (current_function_returns_struct 450318334Speter || current_function_returns_pcc_struct) 450418334Speter { 4505169702Skan rtx value_address = DECL_RTL (DECL_RESULT (current_function_decl)); 450618334Speter tree type = TREE_TYPE (DECL_RESULT (current_function_decl)); 4507169702Skan rtx outgoing; 450818334Speter 4509169702Skan if (DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) 4510169702Skan type = TREE_TYPE (type); 4511169702Skan else 4512169702Skan value_address = XEXP (value_address, 0); 4513169702Skan 4514169702Skan outgoing = targetm.calls.function_value (build_pointer_type (type), 4515169702Skan current_function_decl, true); 4516169702Skan 451718334Speter /* Mark this as a function return value so integrate will delete the 451818334Speter assignment and USE below when inlining this function. */ 451918334Speter REG_FUNCTION_VALUE_P (outgoing) = 1; 452018334Speter 452190091Sobrien /* The address may be ptr_mode and OUTGOING may be Pmode. */ 4522132732Skan value_address = convert_memory_address (GET_MODE (outgoing), 4523132732Skan value_address); 452490091Sobrien 452518334Speter emit_move_insn (outgoing, value_address); 452690091Sobrien 452790091Sobrien /* Show return register used to hold result (in this case the address 452890091Sobrien of the result. */ 452990091Sobrien current_function_return_rtx = outgoing; 453018334Speter } 453118334Speter 453290091Sobrien /* Emit the actual code to clobber return register. */ 453390091Sobrien { 4534169702Skan rtx seq; 4535117404Skan 453690091Sobrien start_sequence (); 453790091Sobrien clobber_return_register (); 4538169702Skan expand_naked_return (); 4539117404Skan seq = get_insns (); 454090091Sobrien end_sequence (); 454118334Speter 4542169702Skan emit_insn_after (seq, clobber_after); 454390091Sobrien } 454418334Speter 4545169702Skan /* Output the label for the naked return from the function. */ 4546169702Skan emit_label (naked_return_label); 4547132732Skan 4548169702Skan /* If stack protection is enabled for this function, check the guard. */ 4549169702Skan if (cfun->stack_protect_guard) 4550169702Skan stack_protect_epilogue (); 4551169702Skan 4552169702Skan /* If we had calls to alloca, and this machine needs 4553169702Skan an accurate stack pointer to exit the function, 4554169702Skan insert some code to save and restore the stack pointer. */ 4555169702Skan if (! EXIT_IGNORE_STACK 4556169702Skan && current_function_calls_alloca) 4557169702Skan { 4558169702Skan rtx tem = 0; 4559169702Skan 4560169702Skan emit_stack_save (SAVE_FUNCTION, &tem, parm_birth_insn); 4561169702Skan emit_stack_restore (SAVE_FUNCTION, tem, NULL_RTX); 4562169702Skan } 4563169702Skan 456490091Sobrien /* ??? This should no longer be necessary since stupid is no longer with 456590091Sobrien us, but there are some parts of the compiler (eg reload_combine, and 456690091Sobrien sh mach_dep_reorg) that still try and compute their own lifetime info 456790091Sobrien instead of using the general framework. */ 456890091Sobrien use_return_register (); 456918334Speter} 457018334Speter 457190091Sobrienrtx 4572132732Skanget_arg_pointer_save_area (struct function *f) 457390091Sobrien{ 457490091Sobrien rtx ret = f->x_arg_pointer_save_area; 457518334Speter 457690091Sobrien if (! ret) 457790091Sobrien { 457890091Sobrien ret = assign_stack_local_1 (Pmode, GET_MODE_SIZE (Pmode), 0, f); 457990091Sobrien f->x_arg_pointer_save_area = ret; 458090091Sobrien } 458118334Speter 458290091Sobrien if (f == cfun && ! f->arg_pointer_save_area_init) 458390091Sobrien { 458490091Sobrien rtx seq; 458590091Sobrien 4586117404Skan /* Save the arg pointer at the beginning of the function. The 458790091Sobrien generated stack slot may not be a valid memory address, so we 458890091Sobrien have to check it and fix it if necessary. */ 458990091Sobrien start_sequence (); 459090091Sobrien emit_move_insn (validize_mem (ret), virtual_incoming_args_rtx); 4591117404Skan seq = get_insns (); 459290091Sobrien end_sequence (); 459390091Sobrien 459490091Sobrien push_topmost_sequence (); 4595169702Skan emit_insn_after (seq, entry_of_function ()); 459690091Sobrien pop_topmost_sequence (); 459790091Sobrien } 459890091Sobrien 459990091Sobrien return ret; 460090091Sobrien} 460190091Sobrien 4602117404Skan/* Extend a vector that records the INSN_UIDs of INSNS 4603117404Skan (a list of one or more insns). */ 460490091Sobrien 460590091Sobrienstatic void 4606169702Skanrecord_insns (rtx insns, VEC(int,heap) **vecp) 460718334Speter{ 4608117404Skan rtx tmp; 4609117404Skan 4610169702Skan for (tmp = insns; tmp != NULL_RTX; tmp = NEXT_INSN (tmp)) 4611169702Skan VEC_safe_push (int, heap, *vecp, INSN_UID (tmp)); 461218334Speter} 461318334Speter 4614132732Skan/* Set the locator of the insn chain starting at INSN to LOC. */ 4615132732Skanstatic void 4616132732Skanset_insn_locators (rtx insn, int loc) 4617132732Skan{ 4618132732Skan while (insn != NULL_RTX) 4619132732Skan { 4620132732Skan if (INSN_P (insn)) 4621132732Skan INSN_LOCATOR (insn) = loc; 4622132732Skan insn = NEXT_INSN (insn); 4623132732Skan } 4624132732Skan} 4625132732Skan 4626117404Skan/* Determine how many INSN_UIDs in VEC are part of INSN. Because we can 4627117404Skan be running after reorg, SEQUENCE rtl is possible. */ 462818334Speter 462918334Speterstatic int 4630169702Skancontains (rtx insn, VEC(int,heap) **vec) 463118334Speter{ 463290091Sobrien int i, j; 463318334Speter 4634169702Skan if (NONJUMP_INSN_P (insn) 463518334Speter && GET_CODE (PATTERN (insn)) == SEQUENCE) 463618334Speter { 463718334Speter int count = 0; 463818334Speter for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--) 4639169702Skan for (j = VEC_length (int, *vec) - 1; j >= 0; --j) 4640169702Skan if (INSN_UID (XVECEXP (PATTERN (insn), 0, i)) 4641169702Skan == VEC_index (int, *vec, j)) 464218334Speter count++; 464318334Speter return count; 464418334Speter } 464518334Speter else 464618334Speter { 4647169702Skan for (j = VEC_length (int, *vec) - 1; j >= 0; --j) 4648169702Skan if (INSN_UID (insn) == VEC_index (int, *vec, j)) 464918334Speter return 1; 465018334Speter } 465118334Speter return 0; 465218334Speter} 465318334Speter 465490091Sobrienint 4655132732Skanprologue_epilogue_contains (rtx insn) 465690091Sobrien{ 4657169702Skan if (contains (insn, &prologue)) 465890091Sobrien return 1; 4659169702Skan if (contains (insn, &epilogue)) 466090091Sobrien return 1; 466190091Sobrien return 0; 466290091Sobrien} 466390091Sobrien 466490091Sobrienint 4665132732Skansibcall_epilogue_contains (rtx insn) 466690091Sobrien{ 466790091Sobrien if (sibcall_epilogue) 4668169702Skan return contains (insn, &sibcall_epilogue); 466990091Sobrien return 0; 467090091Sobrien} 467190091Sobrien 467290091Sobrien#ifdef HAVE_return 467390091Sobrien/* Insert gen_return at the end of block BB. This also means updating 467490091Sobrien block_for_insn appropriately. */ 467590091Sobrien 467690091Sobrienstatic void 4677132732Skanemit_return_into_block (basic_block bb, rtx line_note) 467890091Sobrien{ 4679132732Skan emit_jump_insn_after (gen_return (), BB_END (bb)); 468090091Sobrien if (line_note) 4681132732Skan emit_note_copy_after (line_note, PREV_INSN (BB_END (bb))); 468290091Sobrien} 468390091Sobrien#endif /* HAVE_return */ 468490091Sobrien 468590091Sobrien#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX) 468690091Sobrien 4687169702Skan/* These functions convert the epilogue into a variant that does not 4688169702Skan modify the stack pointer. This is used in cases where a function 4689169702Skan returns an object whose size is not known until it is computed. 4690169702Skan The called function leaves the object on the stack, leaves the 4691169702Skan stack depressed, and returns a pointer to the object. 469290091Sobrien 4693169702Skan What we need to do is track all modifications and references to the 4694169702Skan stack pointer, deleting the modifications and changing the 4695169702Skan references to point to the location the stack pointer would have 4696169702Skan pointed to had the modifications taken place. 469790091Sobrien 4698169702Skan These functions need to be portable so we need to make as few 4699169702Skan assumptions about the epilogue as we can. However, the epilogue 4700169702Skan basically contains three things: instructions to reset the stack 4701169702Skan pointer, instructions to reload registers, possibly including the 4702169702Skan frame pointer, and an instruction to return to the caller. 470390091Sobrien 4704169702Skan We must be sure of what a relevant epilogue insn is doing. We also 4705169702Skan make no attempt to validate the insns we make since if they are 4706169702Skan invalid, we probably can't do anything valid. The intent is that 4707169702Skan these routines get "smarter" as more and more machines start to use 4708169702Skan them and they try operating on different epilogues. 470990091Sobrien 4710169702Skan We use the following structure to track what the part of the 4711169702Skan epilogue that we've already processed has done. We keep two copies 4712169702Skan of the SP equivalence, one for use during the insn we are 4713169702Skan processing and one for use in the next insn. The difference is 4714169702Skan because one part of a PARALLEL may adjust SP and the other may use 4715169702Skan it. */ 471690091Sobrien 471790091Sobrienstruct epi_info 471890091Sobrien{ 471990091Sobrien rtx sp_equiv_reg; /* REG that SP is set from, perhaps SP. */ 472090091Sobrien HOST_WIDE_INT sp_offset; /* Offset from SP_EQUIV_REG of present SP. */ 472190091Sobrien rtx new_sp_equiv_reg; /* REG to be used at end of insn. */ 472290091Sobrien HOST_WIDE_INT new_sp_offset; /* Offset to be used at end of insn. */ 472390091Sobrien rtx equiv_reg_src; /* If nonzero, the value that SP_EQUIV_REG 472490091Sobrien should be set to once we no longer need 472590091Sobrien its value. */ 4726132732Skan rtx const_equiv[FIRST_PSEUDO_REGISTER]; /* Any known constant equivalences 4727132732Skan for registers. */ 472890091Sobrien}; 472990091Sobrien 4730132732Skanstatic void handle_epilogue_set (rtx, struct epi_info *); 4731132732Skanstatic void update_epilogue_consts (rtx, rtx, void *); 4732132732Skanstatic void emit_equiv_load (struct epi_info *); 473390091Sobrien 4734117404Skan/* Modify INSN, a list of one or more insns that is part of the epilogue, to 4735117404Skan no modifications to the stack pointer. Return the new list of insns. */ 473690091Sobrien 473790091Sobrienstatic rtx 4738132732Skankeep_stack_depressed (rtx insns) 473990091Sobrien{ 4740117404Skan int j; 474190091Sobrien struct epi_info info; 4742117404Skan rtx insn, next; 474390091Sobrien 4744132732Skan /* If the epilogue is just a single instruction, it must be OK as is. */ 4745117404Skan if (NEXT_INSN (insns) == NULL_RTX) 4746117404Skan return insns; 474790091Sobrien 474890091Sobrien /* Otherwise, start a sequence, initialize the information we have, and 474990091Sobrien process all the insns we were given. */ 475090091Sobrien start_sequence (); 475190091Sobrien 475290091Sobrien info.sp_equiv_reg = stack_pointer_rtx; 475390091Sobrien info.sp_offset = 0; 475490091Sobrien info.equiv_reg_src = 0; 475590091Sobrien 4756132732Skan for (j = 0; j < FIRST_PSEUDO_REGISTER; j++) 4757132732Skan info.const_equiv[j] = 0; 4758132732Skan 4759117404Skan insn = insns; 4760117404Skan next = NULL_RTX; 4761117404Skan while (insn != NULL_RTX) 476290091Sobrien { 4763117404Skan next = NEXT_INSN (insn); 476490091Sobrien 476590091Sobrien if (!INSN_P (insn)) 476690091Sobrien { 476790091Sobrien add_insn (insn); 4768117404Skan insn = next; 476990091Sobrien continue; 477090091Sobrien } 477190091Sobrien 477290091Sobrien /* If this insn references the register that SP is equivalent to and 477390091Sobrien we have a pending load to that register, we must force out the load 477490091Sobrien first and then indicate we no longer know what SP's equivalent is. */ 477590091Sobrien if (info.equiv_reg_src != 0 477690091Sobrien && reg_referenced_p (info.sp_equiv_reg, PATTERN (insn))) 477790091Sobrien { 477890091Sobrien emit_equiv_load (&info); 477990091Sobrien info.sp_equiv_reg = 0; 478090091Sobrien } 478190091Sobrien 478290091Sobrien info.new_sp_equiv_reg = info.sp_equiv_reg; 478390091Sobrien info.new_sp_offset = info.sp_offset; 478490091Sobrien 478590091Sobrien /* If this is a (RETURN) and the return address is on the stack, 478690091Sobrien update the address and change to an indirect jump. */ 478790091Sobrien if (GET_CODE (PATTERN (insn)) == RETURN 478890091Sobrien || (GET_CODE (PATTERN (insn)) == PARALLEL 478990091Sobrien && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == RETURN)) 479090091Sobrien { 479190091Sobrien rtx retaddr = INCOMING_RETURN_ADDR_RTX; 479290091Sobrien rtx base = 0; 479390091Sobrien HOST_WIDE_INT offset = 0; 479490091Sobrien rtx jump_insn, jump_set; 479590091Sobrien 479690091Sobrien /* If the return address is in a register, we can emit the insn 479790091Sobrien unchanged. Otherwise, it must be a MEM and we see what the 479890091Sobrien base register and offset are. In any case, we have to emit any 479990091Sobrien pending load to the equivalent reg of SP, if any. */ 4800169702Skan if (REG_P (retaddr)) 480190091Sobrien { 480290091Sobrien emit_equiv_load (&info); 480390091Sobrien add_insn (insn); 4804117404Skan insn = next; 480590091Sobrien continue; 480690091Sobrien } 4807169702Skan else 480890091Sobrien { 4809169702Skan rtx ret_ptr; 4810169702Skan gcc_assert (MEM_P (retaddr)); 4811169702Skan 4812169702Skan ret_ptr = XEXP (retaddr, 0); 4813169702Skan 4814169702Skan if (REG_P (ret_ptr)) 4815169702Skan { 4816169702Skan base = gen_rtx_REG (Pmode, REGNO (ret_ptr)); 4817169702Skan offset = 0; 4818169702Skan } 4819169702Skan else 4820169702Skan { 4821169702Skan gcc_assert (GET_CODE (ret_ptr) == PLUS 4822169702Skan && REG_P (XEXP (ret_ptr, 0)) 4823169702Skan && GET_CODE (XEXP (ret_ptr, 1)) == CONST_INT); 4824169702Skan base = gen_rtx_REG (Pmode, REGNO (XEXP (ret_ptr, 0))); 4825169702Skan offset = INTVAL (XEXP (ret_ptr, 1)); 4826169702Skan } 482790091Sobrien } 482890091Sobrien 482990091Sobrien /* If the base of the location containing the return pointer 483090091Sobrien is SP, we must update it with the replacement address. Otherwise, 483190091Sobrien just build the necessary MEM. */ 483290091Sobrien retaddr = plus_constant (base, offset); 483390091Sobrien if (base == stack_pointer_rtx) 483490091Sobrien retaddr = simplify_replace_rtx (retaddr, stack_pointer_rtx, 483590091Sobrien plus_constant (info.sp_equiv_reg, 483690091Sobrien info.sp_offset)); 483790091Sobrien 483890091Sobrien retaddr = gen_rtx_MEM (Pmode, retaddr); 4839169702Skan MEM_NOTRAP_P (retaddr) = 1; 484090091Sobrien 484190091Sobrien /* If there is a pending load to the equivalent register for SP 484290091Sobrien and we reference that register, we must load our address into 484390091Sobrien a scratch register and then do that load. */ 484490091Sobrien if (info.equiv_reg_src 484590091Sobrien && reg_overlap_mentioned_p (info.equiv_reg_src, retaddr)) 484690091Sobrien { 484790091Sobrien unsigned int regno; 484890091Sobrien rtx reg; 484990091Sobrien 485090091Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 485190091Sobrien if (HARD_REGNO_MODE_OK (regno, Pmode) 485290091Sobrien && !fixed_regs[regno] 485390091Sobrien && TEST_HARD_REG_BIT (regs_invalidated_by_call, regno) 4854169702Skan && !REGNO_REG_SET_P 4855169702Skan (EXIT_BLOCK_PTR->il.rtl->global_live_at_start, regno) 485690091Sobrien && !refers_to_regno_p (regno, 4857169702Skan regno + hard_regno_nregs[regno] 4858169702Skan [Pmode], 4859132732Skan info.equiv_reg_src, NULL) 4860132732Skan && info.const_equiv[regno] == 0) 486190091Sobrien break; 486290091Sobrien 4863169702Skan gcc_assert (regno < FIRST_PSEUDO_REGISTER); 486490091Sobrien 486590091Sobrien reg = gen_rtx_REG (Pmode, regno); 486690091Sobrien emit_move_insn (reg, retaddr); 486790091Sobrien retaddr = reg; 486890091Sobrien } 486990091Sobrien 487090091Sobrien emit_equiv_load (&info); 487190091Sobrien jump_insn = emit_jump_insn (gen_indirect_jump (retaddr)); 487290091Sobrien 487390091Sobrien /* Show the SET in the above insn is a RETURN. */ 487490091Sobrien jump_set = single_set (jump_insn); 4875169702Skan gcc_assert (jump_set); 4876169702Skan SET_IS_RETURN_P (jump_set) = 1; 487790091Sobrien } 487890091Sobrien 487990091Sobrien /* If SP is not mentioned in the pattern and its equivalent register, if 488090091Sobrien any, is not modified, just emit it. Otherwise, if neither is set, 488190091Sobrien replace the reference to SP and emit the insn. If none of those are 488290091Sobrien true, handle each SET individually. */ 488390091Sobrien else if (!reg_mentioned_p (stack_pointer_rtx, PATTERN (insn)) 488490091Sobrien && (info.sp_equiv_reg == stack_pointer_rtx 488590091Sobrien || !reg_set_p (info.sp_equiv_reg, insn))) 488690091Sobrien add_insn (insn); 488790091Sobrien else if (! reg_set_p (stack_pointer_rtx, insn) 488890091Sobrien && (info.sp_equiv_reg == stack_pointer_rtx 488990091Sobrien || !reg_set_p (info.sp_equiv_reg, insn))) 489090091Sobrien { 4891169702Skan int changed; 489290091Sobrien 4893169702Skan changed = validate_replace_rtx (stack_pointer_rtx, 4894169702Skan plus_constant (info.sp_equiv_reg, 4895169702Skan info.sp_offset), 4896169702Skan insn); 4897169702Skan gcc_assert (changed); 4898169702Skan 489990091Sobrien add_insn (insn); 490090091Sobrien } 490190091Sobrien else if (GET_CODE (PATTERN (insn)) == SET) 490290091Sobrien handle_epilogue_set (PATTERN (insn), &info); 490390091Sobrien else if (GET_CODE (PATTERN (insn)) == PARALLEL) 490490091Sobrien { 490590091Sobrien for (j = 0; j < XVECLEN (PATTERN (insn), 0); j++) 490690091Sobrien if (GET_CODE (XVECEXP (PATTERN (insn), 0, j)) == SET) 490790091Sobrien handle_epilogue_set (XVECEXP (PATTERN (insn), 0, j), &info); 490890091Sobrien } 490990091Sobrien else 491090091Sobrien add_insn (insn); 491190091Sobrien 491290091Sobrien info.sp_equiv_reg = info.new_sp_equiv_reg; 491390091Sobrien info.sp_offset = info.new_sp_offset; 4914117404Skan 4915132732Skan /* Now update any constants this insn sets. */ 4916132732Skan note_stores (PATTERN (insn), update_epilogue_consts, &info); 4917117404Skan insn = next; 491890091Sobrien } 491990091Sobrien 4920117404Skan insns = get_insns (); 492190091Sobrien end_sequence (); 4922117404Skan return insns; 492390091Sobrien} 492490091Sobrien 492590091Sobrien/* SET is a SET from an insn in the epilogue. P is a pointer to the epi_info 492690091Sobrien structure that contains information about what we've seen so far. We 4927117404Skan process this SET by either updating that data or by emitting one or 492890091Sobrien more insns. */ 492990091Sobrien 493090091Sobrienstatic void 4931132732Skanhandle_epilogue_set (rtx set, struct epi_info *p) 493290091Sobrien{ 493390091Sobrien /* First handle the case where we are setting SP. Record what it is being 4934169702Skan set from, which we must be able to determine */ 493590091Sobrien if (reg_set_p (stack_pointer_rtx, set)) 493690091Sobrien { 4937169702Skan gcc_assert (SET_DEST (set) == stack_pointer_rtx); 493890091Sobrien 4939132732Skan if (GET_CODE (SET_SRC (set)) == PLUS) 494090091Sobrien { 494190091Sobrien p->new_sp_equiv_reg = XEXP (SET_SRC (set), 0); 4942132732Skan if (GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT) 4943132732Skan p->new_sp_offset = INTVAL (XEXP (SET_SRC (set), 1)); 4944132732Skan else 4945169702Skan { 4946169702Skan gcc_assert (REG_P (XEXP (SET_SRC (set), 1)) 4947169702Skan && (REGNO (XEXP (SET_SRC (set), 1)) 4948169702Skan < FIRST_PSEUDO_REGISTER) 4949169702Skan && p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]); 4950169702Skan p->new_sp_offset 4951169702Skan = INTVAL (p->const_equiv[REGNO (XEXP (SET_SRC (set), 1))]); 4952169702Skan } 495390091Sobrien } 495490091Sobrien else 495590091Sobrien p->new_sp_equiv_reg = SET_SRC (set), p->new_sp_offset = 0; 495690091Sobrien 495790091Sobrien /* If we are adjusting SP, we adjust from the old data. */ 495890091Sobrien if (p->new_sp_equiv_reg == stack_pointer_rtx) 495990091Sobrien { 496090091Sobrien p->new_sp_equiv_reg = p->sp_equiv_reg; 496190091Sobrien p->new_sp_offset += p->sp_offset; 496290091Sobrien } 496390091Sobrien 4964169702Skan gcc_assert (p->new_sp_equiv_reg && REG_P (p->new_sp_equiv_reg)); 496590091Sobrien 496690091Sobrien return; 496790091Sobrien } 496890091Sobrien 4969169702Skan /* Next handle the case where we are setting SP's equivalent 4970169702Skan register. We must not already have a value to set it to. We 4971169702Skan could update, but there seems little point in handling that case. 4972169702Skan Note that we have to allow for the case where we are setting the 4973169702Skan register set in the previous part of a PARALLEL inside a single 4974169702Skan insn. But use the old offset for any updates within this insn. 4975169702Skan We must allow for the case where the register is being set in a 4976169702Skan different (usually wider) mode than Pmode). */ 497790091Sobrien else if (p->new_sp_equiv_reg != 0 && reg_set_p (p->new_sp_equiv_reg, set)) 497890091Sobrien { 4979169702Skan gcc_assert (!p->equiv_reg_src 4980169702Skan && REG_P (p->new_sp_equiv_reg) 4981169702Skan && REG_P (SET_DEST (set)) 4982169702Skan && (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) 4983169702Skan <= BITS_PER_WORD) 4984169702Skan && REGNO (p->new_sp_equiv_reg) == REGNO (SET_DEST (set))); 4985169702Skan p->equiv_reg_src 4986169702Skan = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx, 4987169702Skan plus_constant (p->sp_equiv_reg, 4988169702Skan p->sp_offset)); 498990091Sobrien } 499090091Sobrien 499190091Sobrien /* Otherwise, replace any references to SP in the insn to its new value 499290091Sobrien and emit the insn. */ 499390091Sobrien else 499490091Sobrien { 499590091Sobrien SET_SRC (set) = simplify_replace_rtx (SET_SRC (set), stack_pointer_rtx, 499690091Sobrien plus_constant (p->sp_equiv_reg, 499790091Sobrien p->sp_offset)); 499890091Sobrien SET_DEST (set) = simplify_replace_rtx (SET_DEST (set), stack_pointer_rtx, 499990091Sobrien plus_constant (p->sp_equiv_reg, 500090091Sobrien p->sp_offset)); 500190091Sobrien emit_insn (set); 500290091Sobrien } 500390091Sobrien} 500490091Sobrien 5005132732Skan/* Update the tracking information for registers set to constants. */ 5006132732Skan 5007132732Skanstatic void 5008132732Skanupdate_epilogue_consts (rtx dest, rtx x, void *data) 5009132732Skan{ 5010132732Skan struct epi_info *p = (struct epi_info *) data; 5011169702Skan rtx new; 5012132732Skan 5013169702Skan if (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER) 5014132732Skan return; 5015169702Skan 5016169702Skan /* If we are either clobbering a register or doing a partial set, 5017169702Skan show we don't know the value. */ 5018169702Skan else if (GET_CODE (x) == CLOBBER || ! rtx_equal_p (dest, SET_DEST (x))) 5019132732Skan p->const_equiv[REGNO (dest)] = 0; 5020169702Skan 5021169702Skan /* If we are setting it to a constant, record that constant. */ 5022169702Skan else if (GET_CODE (SET_SRC (x)) == CONST_INT) 5023169702Skan p->const_equiv[REGNO (dest)] = SET_SRC (x); 5024169702Skan 5025169702Skan /* If this is a binary operation between a register we have been tracking 5026169702Skan and a constant, see if we can compute a new constant value. */ 5027169702Skan else if (ARITHMETIC_P (SET_SRC (x)) 5028169702Skan && REG_P (XEXP (SET_SRC (x), 0)) 5029169702Skan && REGNO (XEXP (SET_SRC (x), 0)) < FIRST_PSEUDO_REGISTER 5030169702Skan && p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))] != 0 5031169702Skan && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT 5032169702Skan && 0 != (new = simplify_binary_operation 5033169702Skan (GET_CODE (SET_SRC (x)), GET_MODE (dest), 5034169702Skan p->const_equiv[REGNO (XEXP (SET_SRC (x), 0))], 5035169702Skan XEXP (SET_SRC (x), 1))) 5036169702Skan && GET_CODE (new) == CONST_INT) 5037169702Skan p->const_equiv[REGNO (dest)] = new; 5038169702Skan 5039169702Skan /* Otherwise, we can't do anything with this value. */ 5040132732Skan else 5041169702Skan p->const_equiv[REGNO (dest)] = 0; 5042132732Skan} 5043132732Skan 504490091Sobrien/* Emit an insn to do the load shown in p->equiv_reg_src, if needed. */ 504590091Sobrien 504690091Sobrienstatic void 5047132732Skanemit_equiv_load (struct epi_info *p) 504890091Sobrien{ 504990091Sobrien if (p->equiv_reg_src != 0) 5050132732Skan { 5051132732Skan rtx dest = p->sp_equiv_reg; 505290091Sobrien 5053132732Skan if (GET_MODE (p->equiv_reg_src) != GET_MODE (dest)) 5054132732Skan dest = gen_rtx_REG (GET_MODE (p->equiv_reg_src), 5055132732Skan REGNO (p->sp_equiv_reg)); 5056132732Skan 5057132732Skan emit_move_insn (dest, p->equiv_reg_src); 5058132732Skan p->equiv_reg_src = 0; 5059132732Skan } 506090091Sobrien} 506190091Sobrien#endif 506290091Sobrien 506318334Speter/* Generate the prologue and epilogue RTL if the machine supports it. Thread 506418334Speter this into place with notes indicating where the prologue ends and where 506518334Speter the epilogue begins. Update the basic block information when possible. */ 506618334Speter 506718334Spetervoid 5068132732Skanthread_prologue_and_epilogue_insns (rtx f ATTRIBUTE_UNUSED) 506918334Speter{ 507060970Sobrien int inserted = 0; 507190091Sobrien edge e; 507290091Sobrien#if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue) 507390091Sobrien rtx seq; 507490091Sobrien#endif 507560970Sobrien#ifdef HAVE_prologue 507660970Sobrien rtx prologue_end = NULL_RTX; 507760970Sobrien#endif 507890091Sobrien#if defined (HAVE_epilogue) || defined(HAVE_return) 507990091Sobrien rtx epilogue_end = NULL_RTX; 508090091Sobrien#endif 5081169702Skan edge_iterator ei; 508252518Sobrien 508318334Speter#ifdef HAVE_prologue 508418334Speter if (HAVE_prologue) 508518334Speter { 508652518Sobrien start_sequence (); 508790091Sobrien seq = gen_prologue (); 508852518Sobrien emit_insn (seq); 508918334Speter 509052518Sobrien /* Retain a map of the prologue insns. */ 509190091Sobrien record_insns (seq, &prologue); 5092132732Skan prologue_end = emit_note (NOTE_INSN_PROLOGUE_END); 5093171836Skan 5094171836Skan#ifndef PROFILE_BEFORE_PROLOGUE 5095171836Skan /* Ensure that instructions are not moved into the prologue when 5096171836Skan profiling is on. The call to the profiling routine can be 5097171836Skan emitted within the live range of a call-clobbered register. */ 5098171836Skan if (current_function_profile) 5099171836Skan emit_insn (gen_rtx_ASM_INPUT (VOIDmode, "")); 5100171836Skan#endif 510118334Speter 5102117404Skan seq = get_insns (); 510352518Sobrien end_sequence (); 5104132732Skan set_insn_locators (seq, prologue_locator); 510552518Sobrien 510690091Sobrien /* Can't deal with multiple successors of the entry block 510790091Sobrien at the moment. Function should always have at least one 510890091Sobrien entry point. */ 5109169702Skan gcc_assert (single_succ_p (ENTRY_BLOCK_PTR)); 511052518Sobrien 5111169702Skan insert_insn_on_edge (seq, single_succ_edge (ENTRY_BLOCK_PTR)); 511290091Sobrien inserted = 1; 511318334Speter } 511418334Speter#endif 511518334Speter 511690091Sobrien /* If the exit block has no non-fake predecessors, we don't need 511790091Sobrien an epilogue. */ 5118169702Skan FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) 511990091Sobrien if ((e->flags & EDGE_FAKE) == 0) 512090091Sobrien break; 512190091Sobrien if (e == NULL) 512290091Sobrien goto epilogue_done; 512390091Sobrien 512490091Sobrien#ifdef HAVE_return 512590091Sobrien if (optimize && HAVE_return) 512618334Speter { 512790091Sobrien /* If we're allowed to generate a simple return instruction, 512890091Sobrien then by definition we don't need a full epilogue. Examine 512990091Sobrien the block that falls through to EXIT. If it does not 513090091Sobrien contain any code, examine its predecessors and try to 513190091Sobrien emit (conditional) return instructions. */ 513218334Speter 513390091Sobrien basic_block last; 513490091Sobrien rtx label; 513552518Sobrien 5136169702Skan FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) 513790091Sobrien if (e->flags & EDGE_FALLTHRU) 513890091Sobrien break; 513990091Sobrien if (e == NULL) 514090091Sobrien goto epilogue_done; 514190091Sobrien last = e->src; 514290091Sobrien 514390091Sobrien /* Verify that there are no active instructions in the last block. */ 5144132732Skan label = BB_END (last); 5145169702Skan while (label && !LABEL_P (label)) 514618334Speter { 514790091Sobrien if (active_insn_p (label)) 514852518Sobrien break; 514990091Sobrien label = PREV_INSN (label); 515090091Sobrien } 515118334Speter 5152169702Skan if (BB_HEAD (last) == label && LABEL_P (label)) 515390091Sobrien { 5154169702Skan edge_iterator ei2; 515590091Sobrien rtx epilogue_line_note = NULL_RTX; 515652518Sobrien 515790091Sobrien /* Locate the line number associated with the closing brace, 515890091Sobrien if we can find one. */ 515990091Sobrien for (seq = get_last_insn (); 516090091Sobrien seq && ! active_insn_p (seq); 516190091Sobrien seq = PREV_INSN (seq)) 5162169702Skan if (NOTE_P (seq) && NOTE_LINE_NUMBER (seq) > 0) 516390091Sobrien { 516490091Sobrien epilogue_line_note = seq; 516590091Sobrien break; 516690091Sobrien } 516752518Sobrien 5168169702Skan for (ei2 = ei_start (last->preds); (e = ei_safe_edge (ei2)); ) 516990091Sobrien { 517090091Sobrien basic_block bb = e->src; 517190091Sobrien rtx jump; 517252518Sobrien 517390091Sobrien if (bb == ENTRY_BLOCK_PTR) 5174169702Skan { 5175169702Skan ei_next (&ei2); 5176169702Skan continue; 5177169702Skan } 517852518Sobrien 5179132732Skan jump = BB_END (bb); 5180169702Skan if (!JUMP_P (jump) || JUMP_LABEL (jump) != label) 5181169702Skan { 5182169702Skan ei_next (&ei2); 5183169702Skan continue; 5184169702Skan } 518552518Sobrien 518690091Sobrien /* If we have an unconditional jump, we can replace that 518790091Sobrien with a simple return instruction. */ 518890091Sobrien if (simplejump_p (jump)) 518990091Sobrien { 519090091Sobrien emit_return_into_block (bb, epilogue_line_note); 519190091Sobrien delete_insn (jump); 519290091Sobrien } 519352518Sobrien 519490091Sobrien /* If we have a conditional jump, we can try to replace 519590091Sobrien that with a conditional return instruction. */ 519690091Sobrien else if (condjump_p (jump)) 519790091Sobrien { 5198117404Skan if (! redirect_jump (jump, 0, 0)) 5199169702Skan { 5200169702Skan ei_next (&ei2); 5201169702Skan continue; 5202169702Skan } 520318334Speter 520490091Sobrien /* If this block has only one successor, it both jumps 520590091Sobrien and falls through to the fallthru block, so we can't 520690091Sobrien delete the edge. */ 5207169702Skan if (single_succ_p (bb)) 5208169702Skan { 5209169702Skan ei_next (&ei2); 5210169702Skan continue; 5211169702Skan } 521290091Sobrien } 521390091Sobrien else 5214169702Skan { 5215169702Skan ei_next (&ei2); 5216169702Skan continue; 5217169702Skan } 521818334Speter 521990091Sobrien /* Fix up the CFG for the successful change we just made. */ 522090091Sobrien redirect_edge_succ (e, EXIT_BLOCK_PTR); 522190091Sobrien } 522218334Speter 522390091Sobrien /* Emit a return insn for the exit fallthru block. Whether 522490091Sobrien this is still reachable will be determined later. */ 522518334Speter 5226132732Skan emit_barrier_after (BB_END (last)); 522790091Sobrien emit_return_into_block (last, epilogue_line_note); 5228132732Skan epilogue_end = BB_END (last); 5229169702Skan single_succ_edge (last)->flags &= ~EDGE_FALLTHRU; 523090091Sobrien goto epilogue_done; 523190091Sobrien } 523290091Sobrien } 523390091Sobrien#endif 5234169702Skan /* Find the edge that falls through to EXIT. Other edges may exist 5235169702Skan due to RETURN instructions, but those don't need epilogues. 5236169702Skan There really shouldn't be a mixture -- either all should have 5237169702Skan been converted or none, however... */ 5238169702Skan 5239169702Skan FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) 5240169702Skan if (e->flags & EDGE_FALLTHRU) 5241169702Skan break; 5242169702Skan if (e == NULL) 5243169702Skan goto epilogue_done; 5244169702Skan 524590091Sobrien#ifdef HAVE_epilogue 524690091Sobrien if (HAVE_epilogue) 524790091Sobrien { 524890091Sobrien start_sequence (); 5249132732Skan epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG); 525052518Sobrien 525190091Sobrien seq = gen_epilogue (); 525290091Sobrien 525390091Sobrien#ifdef INCOMING_RETURN_ADDR_RTX 525490091Sobrien /* If this function returns with the stack depressed and we can support 525590091Sobrien it, massage the epilogue to actually do that. */ 525690091Sobrien if (TREE_CODE (TREE_TYPE (current_function_decl)) == FUNCTION_TYPE 525790091Sobrien && TYPE_RETURNS_STACK_DEPRESSED (TREE_TYPE (current_function_decl))) 525890091Sobrien seq = keep_stack_depressed (seq); 525990091Sobrien#endif 526090091Sobrien 526190091Sobrien emit_jump_insn (seq); 526290091Sobrien 526390091Sobrien /* Retain a map of the epilogue insns. */ 526490091Sobrien record_insns (seq, &epilogue); 5265132732Skan set_insn_locators (seq, epilogue_locator); 526690091Sobrien 5267117404Skan seq = get_insns (); 526890091Sobrien end_sequence (); 526990091Sobrien 527090091Sobrien insert_insn_on_edge (seq, e); 527190091Sobrien inserted = 1; 527218334Speter } 5273169702Skan else 527418334Speter#endif 5275169702Skan { 5276169702Skan basic_block cur_bb; 5277169702Skan 5278169702Skan if (! next_active_insn (BB_END (e->src))) 5279169702Skan goto epilogue_done; 5280169702Skan /* We have a fall-through edge to the exit block, the source is not 5281169702Skan at the end of the function, and there will be an assembler epilogue 5282169702Skan at the end of the function. 5283169702Skan We can't use force_nonfallthru here, because that would try to 5284169702Skan use return. Inserting a jump 'by hand' is extremely messy, so 5285169702Skan we take advantage of cfg_layout_finalize using 5286169702Skan fixup_fallthru_exit_predecessor. */ 5287169702Skan cfg_layout_initialize (0); 5288169702Skan FOR_EACH_BB (cur_bb) 5289169702Skan if (cur_bb->index >= NUM_FIXED_BLOCKS 5290169702Skan && cur_bb->next_bb->index >= NUM_FIXED_BLOCKS) 5291169702Skan cur_bb->aux = cur_bb->next_bb; 5292169702Skan cfg_layout_finalize (); 5293169702Skan } 529490091Sobrienepilogue_done: 529552518Sobrien 529660970Sobrien if (inserted) 529752518Sobrien commit_edge_insertions (); 529860970Sobrien 529990091Sobrien#ifdef HAVE_sibcall_epilogue 530090091Sobrien /* Emit sibling epilogues before any sibling call sites. */ 5301169702Skan for (ei = ei_start (EXIT_BLOCK_PTR->preds); (e = ei_safe_edge (ei)); ) 530290091Sobrien { 530390091Sobrien basic_block bb = e->src; 5304132732Skan rtx insn = BB_END (bb); 530590091Sobrien 5306169702Skan if (!CALL_P (insn) 530790091Sobrien || ! SIBLING_CALL_P (insn)) 5308169702Skan { 5309169702Skan ei_next (&ei); 5310169702Skan continue; 5311169702Skan } 531290091Sobrien 531390091Sobrien start_sequence (); 5314117404Skan emit_insn (gen_sibcall_epilogue ()); 5315117404Skan seq = get_insns (); 531690091Sobrien end_sequence (); 531790091Sobrien 5318117404Skan /* Retain a map of the epilogue insns. Used in life analysis to 5319117404Skan avoid getting rid of sibcall epilogue insns. Do this before we 5320117404Skan actually emit the sequence. */ 5321117404Skan record_insns (seq, &sibcall_epilogue); 5322132732Skan set_insn_locators (seq, epilogue_locator); 5323117404Skan 5324169702Skan emit_insn_before (seq, insn); 5325169702Skan ei_next (&ei); 532690091Sobrien } 532790091Sobrien#endif 532890091Sobrien 532960970Sobrien#ifdef HAVE_prologue 5330132732Skan /* This is probably all useless now that we use locators. */ 533160970Sobrien if (prologue_end) 533260970Sobrien { 533360970Sobrien rtx insn, prev; 533460970Sobrien 533560970Sobrien /* GDB handles `break f' by setting a breakpoint on the first 533690091Sobrien line note after the prologue. Which means (1) that if 533760970Sobrien there are line number notes before where we inserted the 533890091Sobrien prologue we should move them, and (2) we should generate a 533990091Sobrien note before the end of the first basic block, if there isn't 534090091Sobrien one already there. 534160970Sobrien 5342117404Skan ??? This behavior is completely broken when dealing with 534390091Sobrien multiple entry functions. We simply place the note always 534490091Sobrien into first basic block and let alternate entry points 534590091Sobrien to be missed. 534690091Sobrien */ 534790091Sobrien 534890091Sobrien for (insn = prologue_end; insn; insn = prev) 534960970Sobrien { 535060970Sobrien prev = PREV_INSN (insn); 5351169702Skan if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) 535260970Sobrien { 535360970Sobrien /* Note that we cannot reorder the first insn in the 535460970Sobrien chain, since rest_of_compilation relies on that 535590091Sobrien remaining constant. */ 535660970Sobrien if (prev == NULL) 535790091Sobrien break; 535890091Sobrien reorder_insns (insn, insn, prologue_end); 535960970Sobrien } 536060970Sobrien } 536160970Sobrien 536290091Sobrien /* Find the last line number note in the first block. */ 5363132732Skan for (insn = BB_END (ENTRY_BLOCK_PTR->next_bb); 536490091Sobrien insn != prologue_end && insn; 536590091Sobrien insn = PREV_INSN (insn)) 5366169702Skan if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) 536790091Sobrien break; 536890091Sobrien 536990091Sobrien /* If we didn't find one, make a copy of the first line number 537090091Sobrien we run across. */ 537190091Sobrien if (! insn) 537260970Sobrien { 537390091Sobrien for (insn = next_active_insn (prologue_end); 537490091Sobrien insn; 537590091Sobrien insn = PREV_INSN (insn)) 5376169702Skan if (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) > 0) 537790091Sobrien { 5378132732Skan emit_note_copy_after (insn, prologue_end); 537990091Sobrien break; 538090091Sobrien } 538160970Sobrien } 538290091Sobrien } 538390091Sobrien#endif 538490091Sobrien#ifdef HAVE_epilogue 538590091Sobrien if (epilogue_end) 538690091Sobrien { 538790091Sobrien rtx insn, next; 538890091Sobrien 538990091Sobrien /* Similarly, move any line notes that appear after the epilogue. 539090091Sobrien There is no need, however, to be quite so anal about the existence 5391132732Skan of such a note. Also move the NOTE_INSN_FUNCTION_END and (possibly) 5392132732Skan NOTE_INSN_FUNCTION_BEG notes, as those can be relevant for debug 5393132732Skan info generation. */ 539490091Sobrien for (insn = epilogue_end; insn; insn = next) 539590091Sobrien { 539690091Sobrien next = NEXT_INSN (insn); 5397169702Skan if (NOTE_P (insn) 5398132732Skan && (NOTE_LINE_NUMBER (insn) > 0 5399132732Skan || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG 5400132732Skan || NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_END)) 540190091Sobrien reorder_insns (insn, insn, PREV_INSN (epilogue_end)); 540290091Sobrien } 540390091Sobrien } 540490091Sobrien#endif 540518334Speter} 540618334Speter 540718334Speter/* Reposition the prologue-end and epilogue-begin notes after instruction 540818334Speter scheduling and delayed branch scheduling. */ 540918334Speter 541018334Spetervoid 5411132732Skanreposition_prologue_and_epilogue_notes (rtx f ATTRIBUTE_UNUSED) 541218334Speter{ 541318334Speter#if defined (HAVE_prologue) || defined (HAVE_epilogue) 541496283Sobrien rtx insn, last, note; 541590091Sobrien int len; 541690091Sobrien 5417169702Skan if ((len = VEC_length (int, prologue)) > 0) 541818334Speter { 541996283Sobrien last = 0, note = 0; 542018334Speter 542190091Sobrien /* Scan from the beginning until we reach the last prologue insn. 542290091Sobrien We apparently can't depend on basic_block_{head,end} after 542390091Sobrien reorg has run. */ 542496283Sobrien for (insn = f; insn; insn = NEXT_INSN (insn)) 542518334Speter { 5426169702Skan if (NOTE_P (insn)) 542718334Speter { 542890091Sobrien if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END) 542990091Sobrien note = insn; 543090091Sobrien } 5431169702Skan else if (contains (insn, &prologue)) 543290091Sobrien { 543396283Sobrien last = insn; 543496283Sobrien if (--len == 0) 543596283Sobrien break; 543696283Sobrien } 543796283Sobrien } 5438117404Skan 543996283Sobrien if (last) 544096283Sobrien { 544196283Sobrien /* Find the prologue-end note if we haven't already, and 544296283Sobrien move it to just after the last prologue insn. */ 544396283Sobrien if (note == 0) 544496283Sobrien { 544596283Sobrien for (note = last; (note = NEXT_INSN (note));) 5446169702Skan if (NOTE_P (note) 544796283Sobrien && NOTE_LINE_NUMBER (note) == NOTE_INSN_PROLOGUE_END) 544896283Sobrien break; 544996283Sobrien } 545052518Sobrien 545196283Sobrien /* Avoid placing note between CODE_LABEL and BASIC_BLOCK note. */ 5452169702Skan if (LABEL_P (last)) 545396283Sobrien last = NEXT_INSN (last); 545496283Sobrien reorder_insns (note, note, last); 545518334Speter } 545690091Sobrien } 545718334Speter 5458169702Skan if ((len = VEC_length (int, epilogue)) > 0) 545990091Sobrien { 546096283Sobrien last = 0, note = 0; 546190091Sobrien 546290091Sobrien /* Scan from the end until we reach the first epilogue insn. 546390091Sobrien We apparently can't depend on basic_block_{head,end} after 546490091Sobrien reorg has run. */ 546596283Sobrien for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 546618334Speter { 5467169702Skan if (NOTE_P (insn)) 546818334Speter { 546990091Sobrien if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EPILOGUE_BEG) 547090091Sobrien note = insn; 547190091Sobrien } 5472169702Skan else if (contains (insn, &epilogue)) 547390091Sobrien { 547496283Sobrien last = insn; 547596283Sobrien if (--len == 0) 547696283Sobrien break; 547796283Sobrien } 547896283Sobrien } 547952518Sobrien 548096283Sobrien if (last) 548196283Sobrien { 548296283Sobrien /* Find the epilogue-begin note if we haven't already, and 548396283Sobrien move it to just before the first epilogue insn. */ 548496283Sobrien if (note == 0) 548596283Sobrien { 548696283Sobrien for (note = insn; (note = PREV_INSN (note));) 5487169702Skan if (NOTE_P (note) 548896283Sobrien && NOTE_LINE_NUMBER (note) == NOTE_INSN_EPILOGUE_BEG) 548996283Sobrien break; 549096283Sobrien } 549152518Sobrien 549296283Sobrien if (PREV_INSN (last) != note) 549396283Sobrien reorder_insns (note, note, PREV_INSN (last)); 549418334Speter } 549518334Speter } 549618334Speter#endif /* HAVE_prologue or HAVE_epilogue */ 549718334Speter} 549890091Sobrien 5499169702Skan/* Resets insn_block_boundaries array. */ 550090091Sobrien 550190091Sobrienvoid 5502169702Skanreset_block_changes (void) 550390091Sobrien{ 5504169702Skan cfun->ib_boundaries_block = VEC_alloc (tree, gc, 100); 5505169702Skan VEC_quick_push (tree, cfun->ib_boundaries_block, NULL_TREE); 550690091Sobrien} 5507117404Skan 5508169702Skan/* Record the boundary for BLOCK. */ 5509169702Skanvoid 5510169702Skanrecord_block_change (tree block) 5511169702Skan{ 5512169702Skan int i, n; 5513169702Skan tree last_block; 5514169702Skan 5515169702Skan if (!block) 5516169702Skan return; 5517169702Skan 5518169702Skan if(!cfun->ib_boundaries_block) 5519169702Skan return; 5520169702Skan 5521169702Skan last_block = VEC_pop (tree, cfun->ib_boundaries_block); 5522169702Skan n = get_max_uid (); 5523169702Skan for (i = VEC_length (tree, cfun->ib_boundaries_block); i < n; i++) 5524169702Skan VEC_safe_push (tree, gc, cfun->ib_boundaries_block, last_block); 5525169702Skan 5526169702Skan VEC_safe_push (tree, gc, cfun->ib_boundaries_block, block); 5527169702Skan} 5528169702Skan 5529169702Skan/* Finishes record of boundaries. */ 5530169702Skanvoid 5531169702Skanfinalize_block_changes (void) 5532169702Skan{ 5533169702Skan record_block_change (DECL_INITIAL (current_function_decl)); 5534169702Skan} 5535169702Skan 5536169702Skan/* For INSN return the BLOCK it belongs to. */ 5537169702Skanvoid 5538169702Skancheck_block_change (rtx insn, tree *block) 5539169702Skan{ 5540169702Skan unsigned uid = INSN_UID (insn); 5541169702Skan 5542169702Skan if (uid >= VEC_length (tree, cfun->ib_boundaries_block)) 5543169702Skan return; 5544169702Skan 5545169702Skan *block = VEC_index (tree, cfun->ib_boundaries_block, uid); 5546169702Skan} 5547169702Skan 5548169702Skan/* Releases the ib_boundaries_block records. */ 5549169702Skanvoid 5550169702Skanfree_block_changes (void) 5551169702Skan{ 5552169702Skan VEC_free (tree, gc, cfun->ib_boundaries_block); 5553169702Skan} 5554169702Skan 5555132732Skan/* Returns the name of the current function. */ 5556132732Skanconst char * 5557132732Skancurrent_function_name (void) 5558132732Skan{ 5559169702Skan return lang_hooks.decl_printable_name (cfun->decl, 2); 5560132732Skan} 5561169702Skan 5562132732Skan 5563169702Skanstatic unsigned int 5564169702Skanrest_of_handle_check_leaf_regs (void) 5565169702Skan{ 5566169702Skan#ifdef LEAF_REGISTERS 5567169702Skan current_function_uses_only_leaf_regs 5568169702Skan = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); 5569169702Skan#endif 5570169702Skan return 0; 5571169702Skan} 5572169702Skan 5573169702Skan/* Insert a TYPE into the used types hash table of CFUN. */ 5574169702Skanstatic void 5575169702Skanused_types_insert_helper (tree type, struct function *func) 5576169702Skan{ 5577169702Skan if (type != NULL && func != NULL) 5578169702Skan { 5579169702Skan void **slot; 5580169702Skan 5581169702Skan if (func->used_types_hash == NULL) 5582169702Skan func->used_types_hash = htab_create_ggc (37, htab_hash_pointer, 5583169702Skan htab_eq_pointer, NULL); 5584169702Skan slot = htab_find_slot (func->used_types_hash, type, INSERT); 5585169702Skan if (*slot == NULL) 5586169702Skan *slot = type; 5587169702Skan } 5588169702Skan} 5589169702Skan 5590169702Skan/* Given a type, insert it into the used hash table in cfun. */ 5591169702Skanvoid 5592169702Skanused_types_insert (tree t) 5593169702Skan{ 5594169702Skan while (POINTER_TYPE_P (t) || TREE_CODE (t) == ARRAY_TYPE) 5595169702Skan t = TREE_TYPE (t); 5596169702Skan t = TYPE_MAIN_VARIANT (t); 5597169702Skan if (debug_info_level > DINFO_LEVEL_NONE) 5598169702Skan used_types_insert_helper (t, cfun); 5599169702Skan} 5600169702Skan 5601169702Skanstruct tree_opt_pass pass_leaf_regs = 5602169702Skan{ 5603169702Skan NULL, /* name */ 5604169702Skan NULL, /* gate */ 5605169702Skan rest_of_handle_check_leaf_regs, /* execute */ 5606169702Skan NULL, /* sub */ 5607169702Skan NULL, /* next */ 5608169702Skan 0, /* static_pass_number */ 5609169702Skan 0, /* tv_id */ 5610169702Skan 0, /* properties_required */ 5611169702Skan 0, /* properties_provided */ 5612169702Skan 0, /* properties_destroyed */ 5613169702Skan 0, /* todo_flags_start */ 5614169702Skan 0, /* todo_flags_finish */ 5615169702Skan 0 /* letter */ 5616169702Skan}; 5617169702Skan 5618169702Skan 5619117404Skan#include "gt-function.h" 5620