From: Franz Sirl Date: Mon, 22 Jan 2001 22:47:25 +0000 (+0000) Subject: rs6000.h (INIT_EXPANDERS): Delete. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=71f123ca191d1ddd41c5c6ebcafa9514cb00295b;p=gcc.git rs6000.h (INIT_EXPANDERS): Delete. 2001-01-22 Franz Sirl * rs6000.h (INIT_EXPANDERS): Delete. (RETURN_ADDR_RTX): Call rs6000_return_addr(). * rs6000.c (rs6000_override_options): Call *_machine_status from here... (rs6000_init_expanders): ...instead of here. Delete. (rs6000_mark_machine_status): New function. (rs6000_init_machine_status): Use xcalloc. (rs6000_return_addr): Generate RTX for the return address. (rs6000_ra_ever_killed): New, check if LR was ever destroyed. (rs6000_stack_info): Use it. From-SVN: r39188 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5e2f57d45a4..26d488d3518 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2001-01-22 Franz Sirl + + * rs6000.h (INIT_EXPANDERS): Delete. + (RETURN_ADDR_RTX): Call rs6000_return_addr(). + * rs6000.c (rs6000_override_options): Call *_machine_status from + here... + (rs6000_init_expanders): ...instead of here. Delete. + (rs6000_mark_machine_status): New function. + (rs6000_init_machine_status): Use xcalloc. + (rs6000_return_addr): Generate RTX for the return address. + (rs6000_ra_ever_killed): New, check if LR was ever destroyed. + (rs6000_stack_info): Use it. + 2001-01-22 Thomas Pfaff * gthr-win32.h: Include errno.h to get a declaration for diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 318adb28e7f..3fa0e0a43c1 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -122,6 +122,8 @@ static void toc_hash_mark_table PARAMS ((void *)); static int constant_pool_expr_1 PARAMS ((rtx, int *, int *)); static void rs6000_free_machine_status PARAMS ((struct function *)); static void rs6000_init_machine_status PARAMS ((struct function *)); +static void rs6000_mark_machine_status PARAMS ((struct function *)); +static int rs6000_ra_ever_killed PARAMS ((void)); /* Default register names. */ char rs6000_reg_names[][8] = @@ -399,6 +401,11 @@ rs6000_override_options (default_cpu) if (TARGET_TOC) ASM_GENERATE_INTERNAL_LABEL (toc_label_name, "LCTOC", 1); + + /* Arrange to save and restore machine status around nested functions. */ + init_machine_status = rs6000_init_machine_status; + mark_machine_status = rs6000_mark_machine_status; + free_machine_status = rs6000_free_machine_status; } void @@ -3619,7 +3626,7 @@ rs6000_got_register (value) return pic_offset_table_rtx; } -/* Functions to save and restore sysv_varargs_p. +/* Functions to init, mark and free struct machine_function. These will be called, via pointer variables, from push_function_context and pop_function_context. */ @@ -3627,9 +3634,15 @@ static void rs6000_init_machine_status (p) struct function *p; { - p->machine = (machine_function *) xmalloc (sizeof (machine_function)); + p->machine = (machine_function *) xcalloc (1, sizeof (machine_function)); +} - p->machine->sysv_varargs_p = 0; +static void +rs6000_mark_machine_status (p) + struct function *p; +{ + if (p->machine) + ggc_mark_rtx (p->machine->ra_rtx); } static void @@ -3643,17 +3656,6 @@ rs6000_free_machine_status (p) p->machine = NULL; } - -/* Do anything needed before RTL is emitted for each function. */ - -void -rs6000_init_expanders () -{ - /* Arrange to save and restore machine status around nested functions. */ - init_machine_status = rs6000_init_machine_status; - free_machine_status = rs6000_free_machine_status; -} - /* Print an operand. Recognize special options, documented below. */ @@ -4824,10 +4826,11 @@ rs6000_stack_info () info_ptr->fp_size = 8 * (64 - info_ptr->first_fp_reg_save); /* Does this function call anything? */ - info_ptr->calls_p = ! current_function_is_leaf; + info_ptr->calls_p = (! current_function_is_leaf + || cfun->machine->ra_needs_full_frame); /* Determine if we need to save the link register */ - if (regs_ever_live[LINK_REGISTER_REGNUM] + if (rs6000_ra_ever_killed () || (DEFAULT_ABI == ABI_AIX && profile_flag) #ifdef TARGET_RELOCATABLE || (TARGET_RELOCATABLE && (get_pool_size () != 0)) @@ -5043,6 +5046,66 @@ debug_stack_info (info) fprintf (stderr, "\n"); } + +rtx +rs6000_return_addr (count, frame) + int count; + rtx frame; +{ + rtx init, reg; + + /* Currently we don't optimize very well between prolog and body code and + for PIC code the code can be actually quite bad, so don't try to be + too clever here. */ + if (count != 0 || flag_pic != 0) + { + cfun->machine->ra_needs_full_frame = 1; + return + gen_rtx_MEM (Pmode, + memory_address (Pmode, + plus_constant (copy_to_reg (gen_rtx_MEM (Pmode, + memory_address (Pmode, frame))), + RETURN_ADDRESS_OFFSET))); + } + + reg = cfun->machine->ra_rtx; + if (reg == NULL) + { + /* No rtx yet. Invent one, and initialize it from LR in + the prologue. */ + reg = gen_reg_rtx (Pmode); + cfun->machine->ra_rtx = reg; + init = gen_rtx_SET (VOIDmode, reg, + gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); + + /* Emit the insn to the prologue with the other argument copies. */ + push_topmost_sequence (); + emit_insn_after (init, get_insns ()); + pop_topmost_sequence (); + } + + return reg; +} + +static int +rs6000_ra_ever_killed () +{ + rtx top; + +#ifdef ASM_OUTPUT_MI_THUNK + if (current_function_is_thunk) + return 0; +#endif + if (!cfun->machine->ra_rtx || cfun->machine->ra_needs_full_frame) + return regs_ever_live[LINK_REGISTER_REGNUM]; + + push_topmost_sequence (); + top = get_insns (); + pop_topmost_sequence (); + + return reg_set_between_p (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), + top, NULL_RTX); +} /* Add a REG_MAYBE_DEAD note to the insn. */ static void @@ -5553,7 +5616,7 @@ rs6000_emit_prologue() /* If we use the link register, get it into r0. */ if (info->lr_save_p) - emit_move_insn (gen_rtx_REG (Pmode, 0), + emit_move_insn (gen_rtx_REG (Pmode, 0), gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM)); /* If we need to save CR, put it into r12. */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 27079b3944c..54e987424e4 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1229,10 +1229,6 @@ typedef struct rs6000_stack { /* Align an address */ #define RS6000_ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) -/* Initialize data used by insn expanders. This is called from - init_emit, once for each function, before code is generated. */ -#define INIT_EXPANDERS rs6000_init_expanders () - /* Size of V.4 varargs area in bytes */ #define RS6000_VARARGS_SIZE \ ((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8) @@ -1388,6 +1384,10 @@ typedef struct machine_function { /* Whether a System V.4 varargs area was created. */ int sysv_varargs_p; + /* Set if a return address rtx for loading from LR was created. */ + struct rtx_def *ra_rtx; + /* Flags if __builtin_return_address (n) with n >= 1 was used. */ + int ra_needs_full_frame; } machine_function; /* Define a data type for recording info about an argument list @@ -1649,17 +1649,12 @@ typedef struct rs6000_args /* The current return address is in link register (65). The return address of anything farther back is accessed normally at an offset of 8 from the frame pointer. */ -#define RETURN_ADDR_RTX(COUNT, FRAME) \ - (((COUNT) == -1) \ - ? gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM) \ - : gen_rtx_MEM (Pmode, \ - memory_address \ - (Pmode, \ - plus_constant (copy_to_reg \ - (gen_rtx_MEM (Pmode, \ - memory_address (Pmode, \ - (FRAME)))), \ - RETURN_ADDRESS_OFFSET)))) +#define RETURN_ADDR_RTX(COUNT, FRAME) \ + (rs6000_return_addr (COUNT, FRAME)) + +extern struct rtx_def* rs6000_return_addr (int, struct rtx_def *rtx); + + /* Definitions for register eliminations.