⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 function.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Expands front end tree to back end RTL for GNU C-Compiler   Copyright (C) 1987, 88, 89, 91-94, 1995 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* This file handles the generation of rtl code from tree structure   at the level of the function as a whole.   It creates the rtl expressions for parameters and auto variables   and has full responsibility for allocating stack slots.   `expand_function_start' is called at the beginning of a function,   before the function body is parsed, and `expand_function_end' is   called after parsing the body.   Call `assign_stack_local' to allocate a stack slot for a local variable.   This is usually done during the RTL generation for the function body,   but it can also be done in the reload pass when a pseudo-register does   not get a hard register.   Call `put_var_into_stack' when you learn, belatedly, that a variable   previously given a pseudo-register must in fact go in the stack.   This function changes the DECL_RTL to be a stack slot instead of a reg   then scans all the RTL instructions so far generated to correct them.  */#include "config.h"#include <stdio.h>#include "rtl.h"#include "tree.h"#include "flags.h"#include "function.h"#include "insn-flags.h"#include "expr.h"#include "insn-codes.h"#include "regs.h"#include "hard-reg-set.h"#include "insn-config.h"#include "recog.h"#include "output.h"#include "basic-block.h"#include "obstack.h"#include "bytecode.h"/* Some systems use __main in a way incompatible with its use in gcc, in these   cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to   give the same symbol without quotes for an alternative entry point.  You   must define both, or neither. */#ifndef NAME__MAIN#define NAME__MAIN "__main"#define SYMBOL__MAIN __main#endif/* Round a value to the lowest integer less than it that is a multiple of   the required alignment.  Avoid using division in case the value is   negative.  Assume the alignment is a power of two.  */#define FLOOR_ROUND(VALUE,ALIGN) ((VALUE) & ~((ALIGN) - 1))/* Similar, but round to the next highest integer that meets the   alignment.  */#define CEIL_ROUND(VALUE,ALIGN)	(((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))/* NEED_SEPARATE_AP means that we cannot derive ap from the value of fp   during rtl generation.  If they are different register numbers, this is   always true.  It may also be true if   FIRST_PARM_OFFSET - STARTING_FRAME_OFFSET is not a constant during rtl   generation.  See fix_lexical_addr for details.  */#if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM#define NEED_SEPARATE_AP#endif/* 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 current_function_pops_args;/* Nonzero if function being compiled needs to be given an address   where the value should be stored.  */int current_function_returns_struct;/* Nonzero if function being compiled needs to   return the address of where it has put a structure value.  */int current_function_returns_pcc_struct;/* Nonzero if function being compiled needs to be passed a static chain.  */int current_function_needs_context;/* Nonzero if function being compiled can call setjmp.  */int current_function_calls_setjmp;/* Nonzero if function being compiled can call longjmp.  */int current_function_calls_longjmp;/* Nonzero if function being compiled receives nonlocal gotos   from nested functions.  */int current_function_has_nonlocal_label;/* Nonzero if function being compiled has nonlocal gotos to parent   function.  */int current_function_has_nonlocal_goto;/* Nonzero if function being compiled contains nested functions.  */int current_function_contains_functions;/* Nonzero if function being compiled can call alloca,   either as a subroutine or builtin.  */int current_function_calls_alloca;/* Nonzero if the current function returns a pointer type */int current_function_returns_pointer;/* If some insns can be deferred to the delay slots of the epilogue, the   delay list for them is recorded here.  */rtx current_function_epilogue_delay_list;/* 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 current_function_args_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 current_function_pretend_args_size;/* # of bytes of outgoing arguments.  If ACCUMULATE_OUTGOING_ARGS is   defined, the needed space is pushed by the prologue. */int current_function_outgoing_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 current_function_arg_offset_rtx;/* Nonzero if current function uses varargs.h or equivalent.   Zero for functions that use stdarg.h.  */int current_function_varargs;/* Nonzero if current function uses stdarg.h or equivalent.   Zero for functions that use varargs.h.  */int current_function_stdarg;/* Quantities of various kinds of registers   used for the current function's args.  */CUMULATIVE_ARGS current_function_args_info;/* Name of function now being compiled.  */char *current_function_name;/* If non-zero, an RTL expression for that location at which the current   function returns its result.  Always equal to   DECL_RTL (DECL_RESULT (current_function_decl)), but provided   independently of the tree structures.  */rtx current_function_return_rtx;/* Nonzero if the current function uses the constant pool.  */int current_function_uses_const_pool;/* Nonzero if the current function uses pic_offset_table_rtx.  */int current_function_uses_pic_offset_table;/* The arg pointer hard register, or the pseudo into which it was copied.  */rtx current_function_internal_arg_pointer;/* The FUNCTION_DECL for an inline function currently being expanded.  */tree inline_function_decl;/* Number of function calls seen so far in current function.  */int function_call_count;/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels   (labels to which there can be nonlocal gotos from nested functions)   in this function.  */tree nonlocal_labels;/* RTX for stack slot that holds the current handler for nonlocal gotos.   Zero when function does not have nonlocal labels.  */rtx nonlocal_goto_handler_slot;/* RTX for stack slot that holds the stack pointer value to restore   for a nonlocal goto.   Zero when function does not have nonlocal labels.  */rtx nonlocal_goto_stack_level;/* Label that will go on parm cleanup code, if any.   Jumping to this label runs cleanup code for parameters, if   such code must be run.  Following this code is the logical return label.  */rtx cleanup_label;/* 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 return_label;/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.   So we can mark them all live at the end of the function, if nonopt.  */rtx save_expr_regs;/* List (chain of EXPR_LISTs) of all stack slots in this function.   Made for the sake of unshare_all_rtl.  */rtx stack_slot_list;/* Chain of all RTL_EXPRs that have insns in them.  */tree rtl_expr_chain;/* Label to jump back to for tail recursion, or 0 if we have   not yet needed one for this function.  */rtx tail_recursion_label;/* Place after which to insert the tail_recursion_label if we need one.  */rtx tail_recursion_reentry;/* 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 arg_pointer_save_area;/* 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.  */int frame_offset;/* List (chain of TREE_LISTs) of static chains for containing functions.   Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx   in an RTL_EXPR in the TREE_VALUE.  */static tree context_display;/* List (chain of TREE_LISTs) of trampolines for nested functions.   The trampoline sets up the static chain and jumps to the function.   We supply the trampoline's address when the function's address is requested.   Each link has a FUNCTION_DECL in the TREE_PURPOSE and a reg rtx   in an RTL_EXPR in the TREE_VALUE.  */static tree trampoline_list;/* Insn after which register parms and SAVE_EXPRs are born, if nonopt.  */static rtx parm_birth_insn;#if 0/* Nonzero if a stack slot has been generated whose address is not   actually valid.  It means that the generated rtl must all be scanned   to detect and correct the invalid addresses where they occur.  */static int invalid_stack_slot;#endif/* Last insn of those whose job was to put parms into their nominal homes.  */static rtx last_parm_insn;/* 1 + last pseudo register number used for loading a copy   of a parameter of this function.  */static int max_parm_reg;/* Vector indexed by REGNO, containing location on stack in which   to put the parm which is nominally in pseudo register REGNO,   if we discover that that parm must go in the stack.  */static rtx *parm_reg_stack_loc;#if 0  /* Turned off because 0 seems to work just as well.  *//* Cleanup lists are required for binding levels regardless of whether   that binding level has cleanups or not.  This node serves as the   cleanup list whenever an empty list is required.  */static tree empty_cleanup_list;#endif/* Nonzero once virtual register instantiation has been done.   assign_stack_local uses frame_pointer_rtx when this is nonzero.  */static int virtuals_instantiated;/* These variables hold pointers to functions to   save and restore machine-specific data,   in push_function_context and pop_function_context.  */void (*save_machine_status) ();void (*restore_machine_status) ();/* Nonzero if we need to distinguish between the return value of this function   and the return value of a function called by this function.  This helps   integrate.c  */extern int rtx_equal_function_value_matters;extern tree sequence_rtl_expr;extern tree bc_runtime_type_code ();extern rtx bc_build_calldesc ();extern char *bc_emit_trampoline ();extern char *bc_end_function ();/* In order to evaluate some expressions, such as function calls returning   structures in memory, we need to temporarily allocate stack locations.   We record each allocated temporary in the following structure.   Associated with each temporary slot is a nesting level.  When we pop up   one level, all temporaries associated with the previous level are freed.   Normally, all temporaries are freed after the execution of the statement   in which they were created.  However, if we are inside a ({...}) grouping,   the result may be in a temporary and hence must be preserved.  If the   result could be in a temporary, we preserve it if we can determine which   one it is in.  If we cannot determine which temporary may contain the   result, all temporaries are preserved.  A temporary is preserved by   pretending it was allocated at the previous nesting level.   Automatic variables are also assigned temporary slots, at the nesting   level where they are defined.  They are marked a "kept" so that   free_temp_slots will not free them.  */struct temp_slot{  /* Points to next temporary slot.  */  struct temp_slot *next;  /* The rtx to used to reference the slot. */  rtx slot;  /* The rtx used to represent the address if not the address of the     slot above.  May be an EXPR_LIST if multiple addresses exist.  */  rtx address;  /* The size, in units, of the slot.  */  int size;  /* The value of `sequence_rtl_expr' when this temporary is allocated.  */  tree rtl_expr;  /* Non-zero if this temporary is currently in use.  */  char in_use;  /* Non-zero if this temporary has its address taken.  */  char addr_taken;  /* Nesting level at which this slot is being used.  */  int level;  /* Non-zero if this should survive a call to free_temp_slots.  */  int keep;  /* The offset of the slot from the frame_pointer, including extra space     for alignment.  This info is for combine_temp_slots.  */  int base_offset;  /* The size of the slot, including extra space for alignment.  This     info is for combine_temp_slots.  */  int full_size;};/* List of all temporaries allocated, both available and in use.  */struct temp_slot *temp_slots;/* Current nesting level for temporaries.  */int temp_slot_level;/* The FUNCTION_DECL node for the current function.  */static tree this_function_decl;/* Callinfo pointer for the current function.  */static rtx this_function_callinfo;/* The label in the bytecode file of this function's actual bytecode.   Not an rtx.  */static char *this_function_bytecode;/* The call description vector for the current function.  */static rtx this_function_calldesc;/* Size of the local variables allocated for the current function.  */int local_vars_size;/* Current depth of the bytecode evaluation stack.  */int stack_depth;/* Maximum depth of the evaluation stack in this function.  */int max_stack_depth;/* Current depth in statement expressions.  */static int stmt_expr_depth;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -