X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gcc%2Ffunction.h;h=b0c2b8b9beaef41b28c6f17cdd3c30537cb4c7b0;hb=7adcbafe45f8001b698967defe682687b52c0007;hp=d1f4ffc1fd4ccf7fce03bb0fe8adf2836c9a3621;hpb=74bf76ed78a14069969e94233f05e7840806aed8;p=thirdparty%2Fgcc.git diff --git a/gcc/function.h b/gcc/function.h index d1f4ffc1fd4c..b0c2b8b9beae 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -1,5 +1,5 @@ /* Structure for saving state for a nested function. - Copyright (C) 1989-2013 Free Software Foundation, Inc. + Copyright (C) 1989-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -20,12 +20,6 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_FUNCTION_H #define GCC_FUNCTION_H -#include "hashtab.h" -#include "vec.h" -#include "machmode.h" -#include "tm.h" /* For CUMULATIVE_ARGS. */ -#include "hard-reg-set.h" /* For HARD_REG_SET in struct rtl_data. */ -#include "input.h" /* For location_t. */ /* Stack of pending (incomplete) sequences saved by `start_sequence'. Each element describes one pending sequence. @@ -34,12 +28,14 @@ along with GCC; see the file COPYING3. If not see struct GTY(()) sequence_stack { /* First and last insns in the chain of the saved sequence. */ - rtx first; - rtx last; + rtx_insn *first; + rtx_insn *last; struct sequence_stack *next; }; struct GTY(()) emit_status { + void ensure_regno_capacity (); + /* This is reset to LAST_VIRTUAL_REGISTER + 1 at the start of each function. After rtl generation, it is 1 plus the largest register number used. */ int x_reg_rtx_no; @@ -47,19 +43,17 @@ struct GTY(()) emit_status { /* Lowest label number in current function. */ int x_first_label_num; - /* The ends of the doubly-linked chain of rtl for the current function. - Both are reset to null at the start of rtl generation for the function. + /* seq.first and seq.last are the ends of the doubly-linked chain of + rtl for the current function. Both are reset to null at the + start of rtl generation for the function. - start_sequence saves both of these on `sequence_stack' and then starts - a new, nested sequence of insns. */ - rtx x_first_insn; - rtx x_last_insn; + start_sequence saves both of these on seq.next and then starts + a new, nested sequence of insns. - /* Stack of pending (incomplete) sequences saved by `start_sequence'. - Each element describes one pending sequence. - The main insn-chain is saved in the last element of the chain, - unless the chain is empty. */ - struct sequence_stack *sequence_stack; + seq.next is a stack of pending (incomplete) sequences saved by + start_sequence. Each element describes one pending sequence. + The main insn-chain is the last element of the chain. */ + struct sequence_stack seq; /* INSN_UID for next insn emitted. Reset to 1 for each function compiled. */ @@ -94,14 +88,13 @@ extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx; /* For backward compatibility... eventually these should all go away. */ #define reg_rtx_no (crtl->emit.x_reg_rtx_no) -#define seq_stack (crtl->emit.sequence_stack) #define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO]) struct GTY(()) expr_status { /* Number of units that we should eventually pop off the stack. These are the arguments to function calls that have already returned. */ - int x_pending_stack_adjust; + poly_int64_pod x_pending_stack_adjust; /* Under some ABIs, it is the caller's responsibility to pop arguments pushed for function calls. A naive implementation would simply pop @@ -124,7 +117,7 @@ struct GTY(()) expr_status { boundary can be momentarily unaligned while pushing the arguments. Record the delta since last aligned boundary here in order to get stack alignment in the nested function calls working right. */ - int x_stack_pointer_delta; + poly_int64_pod x_stack_pointer_delta; /* Nonzero means __builtin_saveregs has already been done in this function. The value is the pseudoreg containing the value __builtin_saveregs @@ -135,7 +128,7 @@ struct GTY(()) expr_status { rtx x_apply_args_value; /* List of labels that must never be deleted. */ - rtx x_forced_labels; + vec *x_forced_labels; }; typedef struct call_site_record_d *call_site_record; @@ -144,10 +137,10 @@ typedef struct call_site_record_d *call_site_record; struct GTY(()) rtl_eh { rtx ehr_stackadj; rtx ehr_handler; - rtx ehr_label; + rtx_code_label *ehr_label; rtx sjlj_fc; - rtx sjlj_exit_after; + rtx_insn *sjlj_exit_after; vec *action_record_data; @@ -162,14 +155,9 @@ struct GTY(()) rtl_eh { #define stack_pointer_delta (crtl->expr.x_stack_pointer_delta) struct gimple_df; -struct temp_slot; -typedef struct temp_slot *temp_slot_p; struct call_site_record_d; -struct dw_fde_struct; - -struct ipa_opt_pass_d; -typedef struct ipa_opt_pass_d *ipa_opt_pass; - +struct dw_fde_node; +class range_query; struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ @@ -180,34 +168,6 @@ struct GTY(()) varasm_status { unsigned int deferred_constants; }; -/* Information mainlined about RTL representation of incoming arguments. */ -struct GTY(()) incoming_args { - /* Number of bytes of args popped by function being compiled on its return. - Zero if no bytes are to be popped. - May affect compilation of return insn or of function epilogue. */ - int pops_args; - - /* If function's args have a fixed size, this is that size, in bytes. - Otherwise, it is -1. - May affect compilation of return insn or of function epilogue. */ - int size; - - /* # bytes the prologue should push and pretend that the caller pushed them. - The prologue must do this, but only if parms can be passed in - registers. */ - int pretend_args_size; - - /* This is the offset from the arg pointer to the place where the first - anonymous arg can be found, if there is one. */ - rtx arg_offset_rtx; - - /* Quantities of various kinds of registers - used for the current function's args. */ - CUMULATIVE_ARGS info; - - /* The arg pointer hard register, or the pseudo into which it was copied. */ - rtx internal_arg_pointer; -}; /* Data for function partitioning. */ struct GTY(()) function_subsections { @@ -224,268 +184,32 @@ struct GTY(()) function_subsections { /* Describe an empty area of space in the stack frame. These can be chained into a list; this is used to keep track of space wasted for alignment reasons. */ -struct GTY(()) frame_space +class GTY(()) frame_space { - struct frame_space *next; +public: + class frame_space *next; - HOST_WIDE_INT start; - HOST_WIDE_INT length; + poly_int64 start; + poly_int64 length; }; -/* Datastructures maintained for currently processed function in RTL form. */ -struct GTY(()) rtl_data { - struct expr_status expr; - struct emit_status emit; - struct varasm_status varasm; - struct incoming_args args; - struct function_subsections subsections; - struct rtl_eh eh; - - /* For function.c */ - - /* # of bytes of outgoing arguments. If ACCUMULATE_OUTGOING_ARGS is - defined, the needed space is pushed by the prologue. */ - int outgoing_args_size; - - /* If nonzero, an RTL expression for the location at which the current - function returns its result. If the current function returns its - result in a register, current_function_return_rtx will always be - the hard register containing the result. */ - rtx return_rtx; - - /* Vector of initial-value pairs. Each pair consists of a pseudo - register of approprite mode that stores the initial value a hard - register REGNO, and that hard register itself. */ - /* ??? This could be a VEC but there is currently no way to define an - opaque VEC type. */ - struct initial_value_struct *hard_reg_initial_vals; - - /* A variable living at the top of the frame that holds a known value. - Used for detecting stack clobbers. */ - tree stack_protect_guard; - - /* List (chain of EXPR_LIST) of labels heading the current handlers for - nonlocal gotos. */ - rtx x_nonlocal_goto_handler_labels; - - /* Label that will go on function epilogue. - Jumping to this label serves as a "return" instruction - on machines which require execution of the epilogue on all returns. */ - rtx x_return_label; - - /* Label that will go on the end of function epilogue. - Jumping to this label serves as a "naked return" instruction - on machines which require execution of the epilogue on all returns. */ - rtx x_naked_return_label; - - /* List (chain of EXPR_LISTs) of all stack slots in this function. - Made for the sake of unshare_all_rtl. */ - rtx x_stack_slot_list; - - /* List of empty areas in the stack frame. */ - struct frame_space *frame_space_list; - - /* Place after which to insert the tail_recursion_label if we need one. */ - rtx x_stack_check_probe_note; - - /* Location at which to save the argument pointer if it will need to be - referenced. There are two cases where this is done: if nonlocal gotos - exist, or if vars stored at an offset from the argument pointer will be - needed by inner routines. */ - rtx x_arg_pointer_save_area; - - /* Dynamic Realign Argument Pointer used for realigning stack. */ - rtx drap_reg; - - /* Offset to end of allocated area of stack frame. - If stack grows down, this is the address of the last stack slot allocated. - If stack grows up, this is the address for the next slot. */ - HOST_WIDE_INT x_frame_offset; - - /* Insn after which register parms and SAVE_EXPRs are born, if nonopt. */ - rtx x_parm_birth_insn; - - /* List of all used temporaries allocated, by level. */ - vec *x_used_temp_slots; - - /* List of available temp slots. */ - struct temp_slot *x_avail_temp_slots; - - /* Current nesting level for temporaries. */ - int x_temp_slot_level; - - /* The largest alignment needed on the stack, including requirement - for outgoing stack alignment. */ - unsigned int stack_alignment_needed; - - /* Preferred alignment of the end of stack frame, which is preferred - to call other functions. */ - unsigned int preferred_stack_boundary; - - /* The minimum alignment of parameter stack. */ - unsigned int parm_stack_boundary; - - /* The largest alignment of slot allocated on the stack. */ - unsigned int max_used_stack_slot_alignment; - - /* The stack alignment estimated before reload, with consideration of - following factors: - 1. Alignment of local stack variables (max_used_stack_slot_alignment) - 2. Alignment requirement to call other functions - (preferred_stack_boundary) - 3. Alignment of non-local stack variables but might be spilled in - local stack. */ - unsigned int stack_alignment_estimated; - - /* For reorg. */ - - /* Nonzero if function being compiled called builtin_return_addr or - builtin_frame_address with nonzero count. */ - bool accesses_prior_frames; - - /* Nonzero if the function calls __builtin_eh_return. */ - bool calls_eh_return; - - /* Nonzero if function saves all registers, e.g. if it has a nonlocal - label that can reach the exit block via non-exceptional paths. */ - bool saves_all_registers; - - /* Nonzero if function being compiled has nonlocal gotos to parent - function. */ - bool has_nonlocal_goto; - - /* Nonzero if function being compiled has an asm statement. */ - bool has_asm_statement; - - /* This bit is used by the exception handling logic. It is set if all - calls (if any) are sibling calls. Such functions do not have to - have EH tables generated, as they cannot throw. A call to such a - function, however, should be treated as throwing if any of its callees - can throw. */ - bool all_throwers_are_sibcalls; +/* Describe emitted calls for -fcallgraph-info. */ +struct GTY(()) callinfo_callee +{ + location_t location; + tree decl; +}; - /* Nonzero if stack limit checking should be enabled in the current - function. */ - bool limit_stack; - - /* Nonzero if profiling code should be generated. */ - bool profile; - - /* Nonzero if the current function uses the constant pool. */ - bool uses_const_pool; - - /* Nonzero if the current function uses pic_offset_table_rtx. */ - bool uses_pic_offset_table; - - /* Nonzero if the current function needs an lsda for exception handling. */ - bool uses_eh_lsda; - - /* Set when the tail call has been produced. */ - bool tail_call_emit; - - /* Nonzero if code to initialize arg_pointer_save_area has been emitted. */ - bool arg_pointer_save_area_init; - - /* Nonzero if current function must be given a frame pointer. - Set in reload1.c or lra-eliminations.c if anything is allocated - on the stack there. */ - bool frame_pointer_needed; - - /* When set, expand should optimize for speed. */ - bool maybe_hot_insn_p; - - /* Nonzero if function stack realignment is needed. This flag may be - set twice: before and after reload. It is set before reload wrt - stack alignment estimation before reload. It will be changed after - reload if by then criteria of stack realignment is different. - The value set after reload is the accurate one and is finalized. */ - bool stack_realign_needed; - - /* Nonzero if function stack realignment is tried. This flag is set - only once before reload. It affects register elimination. This - is used to generate DWARF debug info for stack variables. */ - bool stack_realign_tried; - - /* Nonzero if function being compiled needs dynamic realigned - argument pointer (drap) if stack needs realigning. */ - bool need_drap; - - /* Nonzero if function stack realignment estimation is done, namely - stack_realign_needed flag has been set before reload wrt estimated - stack alignment info. */ - bool stack_realign_processed; - - /* Nonzero if function stack realignment has been finalized, namely - stack_realign_needed flag has been set and finalized after reload. */ - bool stack_realign_finalized; - - /* True if dbr_schedule has already been called for this function. */ - bool dbr_scheduled_p; - - /* True if current function can not throw. Unlike - TREE_NOTHROW (current_function_decl) it is set even for overwritable - function where currently compiled version of it is nothrow. */ - bool nothrow; - - /* True if we performed shrink-wrapping for the current function. */ - bool shrink_wrapped; - - /* Nonzero if function being compiled doesn't modify the stack pointer - (ignoring the prologue and epilogue). This is only valid after - pass_stack_ptr_mod has run. */ - bool sp_is_unchanging; - - /* Nonzero if function being compiled doesn't contain any calls - (ignoring the prologue and epilogue). This is set prior to - local register allocation and is valid for the remaining - compiler passes. */ - bool is_leaf; - - /* Nonzero if the function being compiled is a leaf function which only - uses leaf registers. This is valid after reload (specifically after - sched2) and is useful only if the port defines LEAF_REGISTERS. */ - bool uses_only_leaf_regs; - - /* Nonzero if the function being compiled has undergone hot/cold partitioning - (under flag_reorder_blocks_and_partition) and has at least one cold - block. */ - bool has_bb_partition; - - /* Nonzero if the function being compiled has completed the bb reordering - pass. */ - bool bb_reorder_complete; - - /* Like regs_ever_live, but 1 if a reg is set or clobbered from an - asm. Unlike regs_ever_live, elements of this array corresponding - to eliminable regs (like the frame pointer) are set if an asm - sets them. */ - HARD_REG_SET asm_clobbers; +/* Describe dynamic allocation for -fcallgraph-info=da. */ +struct GTY(()) callinfo_dalloc +{ + location_t location; + char const *name; }; -#define return_label (crtl->x_return_label) -#define naked_return_label (crtl->x_naked_return_label) -#define stack_slot_list (crtl->x_stack_slot_list) -#define parm_birth_insn (crtl->x_parm_birth_insn) -#define frame_offset (crtl->x_frame_offset) -#define stack_check_probe_note (crtl->x_stack_check_probe_note) -#define arg_pointer_save_area (crtl->x_arg_pointer_save_area) -#define used_temp_slots (crtl->x_used_temp_slots) -#define avail_temp_slots (crtl->x_avail_temp_slots) -#define temp_slot_level (crtl->x_temp_slot_level) -#define nonlocal_goto_handler_labels (crtl->x_nonlocal_goto_handler_labels) -#define frame_pointer_needed (crtl->frame_pointer_needed) -#define stack_realign_fp (crtl->stack_realign_needed && !crtl->need_drap) -#define stack_realign_drap (crtl->stack_realign_needed && crtl->need_drap) - -extern GTY(()) struct rtl_data x_rtl; - -/* Accessor to RTL datastructures. We keep them statically allocated now since - we never keep multiple functions. For threaded compiler we might however - want to do differently. */ -#define crtl (&x_rtl) - -struct GTY(()) stack_usage +class GTY(()) stack_usage { +public: /* # of bytes of static stack space allocated by the function. */ HOST_WIDE_INT static_stack_size; @@ -493,13 +217,21 @@ struct GTY(()) stack_usage meaningful only if has_unbounded_dynamic_stack_size is zero. */ HOST_WIDE_INT dynamic_stack_size; - /* # of bytes of space pushed onto the stack after the prologue. If - !ACCUMULATE_OUTGOING_ARGS, it contains the outgoing arguments. */ - int pushed_stack_size; + /* Upper bound on the number of bytes pushed onto the stack after the + prologue. If !ACCUMULATE_OUTGOING_ARGS, it contains the outgoing + arguments. */ + poly_int64 pushed_stack_size; /* Nonzero if the amount of stack space allocated dynamically cannot be bounded at compile-time. */ unsigned int has_unbounded_dynamic_stack_size : 1; + + /* Functions called within the function, if callgraph is enabled. */ + vec *callees; + + /* Dynamic allocations encountered within the function, if callgraph + da is enabled. */ + vec *dallocs; }; #define current_function_static_stack_size (cfun->su->static_stack_size) @@ -529,12 +261,22 @@ struct GTY(()) function { /* The loops in this function. */ struct loops *x_current_loops; + /* Filled by the GIMPLE and RTL FEs, pass to start compilation with. */ + char *pass_startwith; + /* The stack usage of this function. */ - struct stack_usage *su; + class stack_usage *su; /* Value histograms attached to particular statements. */ htab_t GTY((skip)) value_histograms; + /* Different from normal TODO_flags which are handled right at the + beginning or the end of one pass execution, the pending_TODOs + are passed down in the pipeline until one of its consumers can + perform the requested action. Consumers should then clear the + flags for the actions that they have taken. */ + unsigned int pending_TODOs; + /* For function.c. */ /* Points to the FUNCTION_DECL of this function. */ @@ -561,16 +303,28 @@ struct GTY(()) function { struct language_function * language; /* Used types hash table. */ - htab_t GTY ((param_is (union tree_node))) used_types_hash; + hash_set *GTY (()) used_types_hash; /* Dwarf2 Frame Description Entry, containing the Call Frame Instructions used for unwinding. Only set when either dwarf2 unwinding or dwarf2 debugging is enabled. */ - struct dw_fde_struct *fde; + struct dw_fde_node *fde; + + /* Range query mechanism for functions. The default is to pick up + global ranges. If a pass wants on-demand ranges OTOH, it must + call enable/disable_ranger(). The pointer is never null. It + should be queried by calling get_range_query(). */ + range_query * GTY ((skip)) x_range_query; /* Last statement uid. */ int last_stmt_uid; + /* Debug marker counter. Count begin stmt markers. We don't have + to keep it exact, it's more of a rough estimate to enable us to + decide whether they are too many to copy during inlining, or when + expanding to RTL. */ + int debug_marker_count; + /* Function sequence number for profiling, debugging, etc. */ int funcdef_no; @@ -589,6 +343,9 @@ struct GTY(()) function { a string describing the reason for failure. */ const char * GTY((skip)) cannot_be_copied_reason; + /* Last assigned dependence info clique. */ + unsigned short last_clique; + /* Collected bit flags. */ /* Number of units of general registers that need saving in stdarg @@ -607,10 +364,17 @@ struct GTY(()) function { either as a subroutine or builtin. */ unsigned int calls_alloca : 1; + /* Nonzero if function being compiled can call __builtin_eh_return. */ + unsigned int calls_eh_return : 1; + /* Nonzero if function being compiled receives nonlocal gotos from nested functions. */ unsigned int has_nonlocal_label : 1; + /* Nonzero if function being compiled has a forced label + placed into static storage. */ + unsigned int has_forced_label_in_static : 1; + /* Nonzero if we've set cannot_be_copied_reason. I.e. if (cannot_be_copied_set && !cannot_be_copied_reason), the function can in fact be copied. */ @@ -652,25 +416,43 @@ struct GTY(()) function { unsigned int is_thunk : 1; /* Nonzero if the current function contains any loops with - loop->force_vect set. */ - unsigned int has_force_vect_loops : 1; + loop->force_vectorize set. */ + unsigned int has_force_vectorize_loops : 1; /* Nonzero if the current function contains any loops with nonzero value in loop->simduid. */ unsigned int has_simduid_loops : 1; + + /* Nonzero when the tail call has been identified. */ + unsigned int tail_call_marked : 1; + + /* Nonzero if the current function contains a #pragma GCC unroll. */ + unsigned int has_unroll : 1; + + /* Set when the function was compiled with generation of debug + (begin stmt, inline entry, ...) markers enabled. */ + unsigned int debug_nonbind_markers : 1; + + /* Set if this is a coroutine-related function. */ + unsigned int coroutine_component : 1; + + /* Set if there are any OMP_TARGET regions in the function. */ + unsigned int has_omp_target : 1; }; /* Add the decl D to the local_decls list of FUN. */ -static inline void -add_local_decl (struct function *fun, tree d) -{ - vec_safe_push (fun->local_decls, d); -} +void add_local_decl (struct function *fun, tree d); #define FOR_EACH_LOCAL_DECL(FUN, I, D) \ FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D) +/* Record a final call to CALLEE at LOCATION. */ +void record_final_call (tree callee, location_t location); + +/* Record a dynamic allocation made for DECL_OR_EXP. */ +void record_dynamic_alloc (tree decl_or_exp); + /* If va_list_[gf]pr_size is set to this, it means we don't know how many units need to be saved. */ #define VA_LIST_MAX_GPR_SIZE 255 @@ -690,32 +472,30 @@ extern int virtuals_instantiated; /* Nonzero if at least one trampoline has been created. */ extern int trampolines_created; -struct GTY(()) types_used_by_vars_entry { +struct GTY((for_user)) types_used_by_vars_entry { tree type; tree var_decl; }; +struct used_type_hasher : ggc_ptr_hash +{ + static hashval_t hash (types_used_by_vars_entry *); + static bool equal (types_used_by_vars_entry *, types_used_by_vars_entry *); +}; + /* Hash table making the relationship between a global variable and the types it references in its initializer. The key of the entry is a referenced type, and the value is the DECL of the global variable. types_use_by_vars_do_hash and types_used_by_vars_eq below are the hash and equality functions to use for this hash table. */ -extern GTY((param_is (struct types_used_by_vars_entry))) htab_t - types_used_by_vars_hash; +extern GTY(()) hash_table *types_used_by_vars_hash; -hashval_t types_used_by_vars_do_hash (const void*); -int types_used_by_vars_eq (const void *, const void *); void types_used_by_var_decl_insert (tree type, tree var_decl); /* During parsing of a global variable, this vector contains the types referenced by the global variable. */ extern GTY(()) vec *types_used_by_cur_var_decl; -/* cfun shouldn't be set directly; use one of these functions instead. */ -extern void set_cfun (struct function *new_cfun); -extern void push_cfun (struct function *new_cfun); -extern void pop_cfun (void); -extern void instantiate_decl_rtl (rtx x); /* Return the loop tree of FN. */ @@ -742,75 +522,201 @@ set_loops_for_fn (struct function *fn, struct loops *loops) #define n_bbs_in_dom_tree (cfun->cfg->x_n_bbs_in_dom_tree) #define VALUE_HISTOGRAMS(fun) (fun)->value_histograms -/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END}, - and create duplicate blocks. */ -extern void reorder_blocks (void); +/* A pointer to a function to create target specific, per-function + data structures. */ +extern struct machine_function * (*init_machine_status) (void); -/* Set BLOCK_NUMBER for all the blocks in FN. */ -extern void number_blocks (tree); +/* Structure to record the size of a sequence of arguments + as the sum of a tree-expression and a constant. This structure is + also used to store offsets from the stack, which might be negative, + so the variable part must be ssizetype, not sizetype. */ -extern void clear_block_marks (tree); -extern tree blocks_nreverse (tree); -extern tree block_chainon (tree, tree); +struct args_size +{ + poly_int64_pod constant; + tree var; +}; + +/* Package up various arg related fields of struct args for + locate_and_pad_parm. */ +struct locate_and_pad_arg_data +{ + /* Size of this argument on the stack, rounded up for any padding it + gets. If REG_PARM_STACK_SPACE is defined, then register parms are + counted here, otherwise they aren't. */ + struct args_size size; + /* Offset of this argument from beginning of stack-args. */ + struct args_size offset; + /* Offset to the start of the stack slot. Different from OFFSET + if this arg pads downward. */ + struct args_size slot_offset; + /* The amount that the stack pointer needs to be adjusted to + force alignment for the next argument. */ + struct args_size alignment_pad; + /* Which way we should pad this arg. */ + pad_direction where_pad; + /* slot_offset is at least this aligned. */ + unsigned int boundary; +}; + +/* Add the value of the tree INC to the `struct args_size' TO. */ + +#define ADD_PARM_SIZE(TO, INC) \ +do { \ + tree inc = (INC); \ + if (tree_fits_shwi_p (inc)) \ + (TO).constant += tree_to_shwi (inc); \ + else if ((TO).var == 0) \ + (TO).var = fold_convert (ssizetype, inc); \ + else \ + (TO).var = size_binop (PLUS_EXPR, (TO).var, \ + fold_convert (ssizetype, inc)); \ +} while (0) + +#define SUB_PARM_SIZE(TO, DEC) \ +do { \ + tree dec = (DEC); \ + if (tree_fits_shwi_p (dec)) \ + (TO).constant -= tree_to_shwi (dec); \ + else if ((TO).var == 0) \ + (TO).var = size_binop (MINUS_EXPR, ssize_int (0), \ + fold_convert (ssizetype, dec)); \ + else \ + (TO).var = size_binop (MINUS_EXPR, (TO).var, \ + fold_convert (ssizetype, dec)); \ +} while (0) + +/* Convert the implicit sum in a `struct args_size' into a tree + of type ssizetype. */ +#define ARGS_SIZE_TREE(SIZE) \ +((SIZE).var == 0 ? ssize_int ((SIZE).constant) \ + : size_binop (PLUS_EXPR, fold_convert (ssizetype, (SIZE).var), \ + ssize_int ((SIZE).constant))) + +/* Convert the implicit sum in a `struct args_size' into an rtx. */ +#define ARGS_SIZE_RTX(SIZE) \ +((SIZE).var == 0 ? gen_int_mode ((SIZE).constant, Pmode) \ + : expand_normal (ARGS_SIZE_TREE (SIZE))) + +#define ASLK_REDUCE_ALIGN 1 +#define ASLK_RECORD_PAD 2 + +/* If pointers to member functions use the least significant bit to + indicate whether a function is virtual, ensure a pointer + to this function will have that bit clear. */ +#define MINIMUM_METHOD_BOUNDARY \ + ((TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) \ + ? MAX (FUNCTION_BOUNDARY, 2 * BITS_PER_UNIT) : FUNCTION_BOUNDARY) + +enum stack_clash_probes { + NO_PROBE_NO_FRAME, + NO_PROBE_SMALL_FRAME, + PROBE_INLINE, + PROBE_LOOP +}; + +extern void dump_stack_clash_frame_info (enum stack_clash_probes, bool); + + +extern void push_function_context (void); +extern void pop_function_context (void); + +/* Save and restore status information for a nested function. */ +extern void free_after_parsing (struct function *); +extern void free_after_compilation (struct function *); /* Return size needed for stack frame based on slots so far allocated. This size counts from zero. It is not rounded to STACK_BOUNDARY; the caller may have to do that. */ -extern HOST_WIDE_INT get_frame_size (void); +extern poly_int64 get_frame_size (void); /* Issue an error message and return TRUE if frame OFFSET overflows in the signed target pointer arithmetics for function FUNC. Otherwise return FALSE. */ -extern bool frame_offset_overflow (HOST_WIDE_INT, tree); +extern bool frame_offset_overflow (poly_int64, tree); + +extern unsigned int spill_slot_alignment (machine_mode); + +extern rtx assign_stack_local_1 (machine_mode, poly_int64, int, int); +extern rtx assign_stack_local (machine_mode, poly_int64, int); +extern rtx assign_stack_temp_for_type (machine_mode, poly_int64, tree); +extern rtx assign_stack_temp (machine_mode, poly_int64); +extern rtx assign_temp (tree, int, int); +extern void update_temp_slot_address (rtx, rtx); +extern void preserve_temp_slots (rtx); +extern void free_temp_slots (void); +extern void push_temp_slots (void); +extern void pop_temp_slots (void); +extern void init_temp_slots (void); +extern rtx get_hard_reg_initial_reg (rtx); +extern rtx get_hard_reg_initial_val (machine_mode, unsigned int); +extern rtx has_hard_reg_initial_val (machine_mode, unsigned int); -/* A pointer to a function to create target specific, per-function - data structures. */ -extern struct machine_function * (*init_machine_status) (void); +/* Called from gimple_expand_cfg. */ +extern unsigned int emit_initial_value_sets (void); -/* Save and restore status information for a nested function. */ -extern void free_after_parsing (struct function *); -extern void free_after_compilation (struct function *); +extern bool initial_value_entry (int i, rtx *, rtx *); +extern void instantiate_decl_rtl (rtx x); +extern int aggregate_value_p (const_tree, const_tree); +extern bool use_register_for_decl (const_tree); +extern gimple_seq gimplify_parameters (gimple_seq *); +extern void locate_and_pad_parm (machine_mode, tree, int, int, int, + tree, struct args_size *, + struct locate_and_pad_arg_data *); +extern void generate_setjmp_warnings (void); -extern void init_varasm_status (void); +/* Identify BLOCKs referenced by more than one NOTE_INSN_BLOCK_{BEG,END}, + and create duplicate blocks. */ +extern void reorder_blocks (void); +extern void clear_block_marks (tree); +extern tree blocks_nreverse (tree); +extern tree block_chainon (tree, tree); -#ifdef RTX_CODE +/* Set BLOCK_NUMBER for all the blocks in FN. */ +extern void number_blocks (tree); + +/* cfun shouldn't be set directly; use one of these functions instead. */ +extern void set_cfun (struct function *new_cfun, bool force = false); +extern void push_cfun (struct function *new_cfun); +extern void pop_cfun (void); + +extern int get_next_funcdef_no (void); +extern int get_last_funcdef_no (void); +extern void allocate_struct_function (tree, bool); +extern void push_struct_function (tree fndecl); +extern void push_dummy_function (bool); +extern void pop_dummy_function (void); +extern void init_dummy_function_start (void); +extern void init_function_start (tree); +extern void stack_protect_epilogue (void); +extern void expand_function_start (tree); +extern void expand_dummy_function_end (void); + +extern void thread_prologue_and_epilogue_insns (void); extern void diddle_return_value (void (*)(rtx, void*), void*); extern void clobber_return_register (void); -#endif - +extern void expand_function_end (void); extern rtx get_arg_pointer_save_area (void); +extern void maybe_copy_prologue_epilogue_insn (rtx, rtx); +extern int prologue_contains (const rtx_insn *); +extern int epilogue_contains (const rtx_insn *); +extern int prologue_epilogue_contains (const rtx_insn *); +extern void record_prologue_seq (rtx_insn *); +extern void record_epilogue_seq (rtx_insn *); +extern void emit_return_into_block (bool simple_p, basic_block bb); +extern void set_return_jump_label (rtx_insn *); +extern bool active_insn_between (rtx_insn *head, rtx_insn *tail); +extern vec convert_jumps_to_returns (basic_block last_bb, bool simple_p, + vec unconverted); +extern basic_block emit_return_for_exit (edge exit_fallthru_edge, + bool simple_p); +extern void reposition_prologue_and_epilogue_notes (void); /* Returns the name of the current function. */ extern const char *fndecl_name (tree); extern const char *function_name (struct function *); extern const char *current_function_name (void); -extern void do_warn_unused_parameter (tree); - -extern bool pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, - tree, bool); -extern bool reference_callee_copied (CUMULATIVE_ARGS *, enum machine_mode, - tree, bool); - extern void used_types_insert (tree); -extern int get_next_funcdef_no (void); -extern int get_last_funcdef_no (void); - -#ifdef HAVE_simple_return -extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET); -#endif - -extern rtx get_hard_reg_initial_val (enum machine_mode, unsigned int); -extern rtx has_hard_reg_initial_val (enum machine_mode, unsigned int); -extern rtx get_hard_reg_initial_reg (rtx); -extern bool initial_value_entry (int i, rtx *, rtx *); - -/* Called from gimple_expand_cfg. */ -extern unsigned int emit_initial_value_sets (void); - -/* In predict.c */ -extern bool optimize_function_for_size_p (struct function *); -extern bool optimize_function_for_speed_p (struct function *); - #endif /* GCC_FUNCTION_H */