X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=gcc%2Ffunction.h;h=b0c2b8b9beaef41b28c6f17cdd3c30537cb4c7b0;hb=7adcbafe45f8001b698967defe682687b52c0007;hp=81d76bf55e83ae252322672b15735be1eee4968a;hpb=d38ff8dd18174f7e28303dcb3981cc375277f518;p=thirdparty%2Fgcc.git diff --git a/gcc/function.h b/gcc/function.h index 81d76bf55e83..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-2015 Free Software Foundation, Inc. + Copyright (C) 1989-2022 Free Software Foundation, Inc. This file is part of GCC. @@ -34,6 +34,8 @@ struct GTY(()) sequence_stack { }; 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; @@ -92,7 +94,7 @@ extern GTY ((length ("crtl->emit.x_reg_rtx_no"))) rtx * regno_reg_rtx; 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 @@ -115,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 @@ -126,7 +128,7 @@ struct GTY(()) expr_status { rtx x_apply_args_value; /* List of labels that must never be deleted. */ - rtx_insn_list *x_forced_labels; + vec *x_forced_labels; }; typedef struct call_site_record_d *call_site_record; @@ -153,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_node; - -class ipa_opt_pass_d; -typedef ipa_opt_pass_d *ipa_opt_pass; - +class range_query; struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ @@ -171,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 { @@ -215,271 +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; - /* If nonxero, an RTL expression for the lcoation at which the current - function returns bounds for its result. */ - rtx return_bnd; - - /* 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 INSN_LIST) of labels heading the current handlers for - nonlocal gotos. */ - rtx_insn_list *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_code_label *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_code_label *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_expr_list *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_note *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_insn *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; @@ -487,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) @@ -523,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. */ @@ -546,9 +294,6 @@ struct GTY(()) function { /* Vector of function local variables, functions, types and constants. */ vec *local_decls; - /* In a Cilk function, the VAR_DECL for the frame descriptor. */ - tree cilk_frame_decl; - /* For md files. */ /* tm.h can use this to store whatever it likes. */ @@ -565,9 +310,21 @@ struct GTY(()) function { debugging is enabled. */ 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; @@ -607,16 +364,17 @@ struct GTY(()) function { either as a subroutine or builtin. */ unsigned int calls_alloca : 1; - /* This will indicate whether a function is a cilk function */ - unsigned int is_cilk_function : 1; + /* Nonzero if function being compiled can call __builtin_eh_return. */ + unsigned int calls_eh_return : 1; - /* Nonzero if this is a Cilk function that spawns. */ - unsigned int calls_cilk_spawn : 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. */ @@ -665,8 +423,21 @@ struct GTY(()) function { nonzero value in loop->simduid. */ unsigned int has_simduid_loops : 1; - /* Set when the tail call has been identified. */ + /* 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. */ @@ -676,6 +447,12 @@ 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 @@ -700,7 +477,7 @@ struct GTY((for_user)) types_used_by_vars_entry { tree var_decl; }; -struct used_type_hasher : ggc_hasher +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 *); @@ -749,8 +526,6 @@ set_loops_for_fn (struct function *fn, struct loops *loops) data structures. */ extern struct machine_function * (*init_machine_status) (void); -enum direction {none, upward, downward}; - /* 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, @@ -758,7 +533,7 @@ enum direction {none, upward, downward}; struct args_size { - HOST_WIDE_INT constant; + poly_int64_pod constant; tree var; }; @@ -779,7 +554,7 @@ struct locate_and_pad_arg_data force alignment for the next argument. */ struct args_size alignment_pad; /* Which way we should pad this arg. */ - enum direction where_pad; + pad_direction where_pad; /* slot_offset is at least this aligned. */ unsigned int boundary; }; @@ -820,12 +595,27 @@ do { \ /* Convert the implicit sum in a `struct args_size' into an rtx. */ #define ARGS_SIZE_RTX(SIZE) \ -((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \ +((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); @@ -838,17 +628,19 @@ 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, HOST_WIDE_INT, int, int); -extern rtx assign_stack_local (machine_mode, HOST_WIDE_INT, int); -extern rtx assign_stack_temp_for_type (machine_mode, HOST_WIDE_INT, tree); -extern rtx assign_stack_temp (machine_mode, HOST_WIDE_INT); +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); @@ -867,11 +659,7 @@ 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 bool pass_by_reference (CUMULATIVE_ARGS *, machine_mode, - tree, bool); -extern bool reference_callee_copied (CUMULATIVE_ARGS *, machine_mode, - tree, bool); -extern gimple_seq gimplify_parameters (void); +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 *); @@ -888,7 +676,7 @@ extern tree block_chainon (tree, tree); 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); +extern void set_cfun (struct function *new_cfun, bool force = false); extern void push_cfun (struct function *new_cfun); extern void pop_cfun (void); @@ -905,17 +693,16 @@ extern void expand_function_start (tree); extern void expand_dummy_function_end (void); extern void thread_prologue_and_epilogue_insns (void); - -#ifdef RTX_CODE extern void diddle_return_value (void (*)(rtx, void*), void*); extern void clobber_return_register (void); -#endif - -extern void do_warn_unused_parameter (tree); 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_epilogue_contains (const_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);