From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2178) id 0456F3858C2C; Tue, 3 Jan 2023 15:47:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0456F3858C2C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1672760870; bh=AYWStotfcB8TgeNmvibTVr8b93GsJk2ZCVj+5zewpB4=; h=From:To:Subject:Date:From; b=bjwnmIcn4C3Cm5Kk0WzU1yKj9lZC5LTxUmt5Q/twgx5U1NgApsOg/8i+mBKCR3r2a fvhVZS0+0yPLhBVSX06jmUg6wRkSuC7MNi4oEF9B7qfhF1a4IeDDSS6jnWu3S3dWBb MMX8PoNTJDatEXJbcL1Gyi9D6uU1dHuHGB0fmRjU= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Florian Weimer To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4981] Revert "Compute a table of DWARF register sizes at compile" X-Act-Checkin: gcc X-Git-Author: Florian Weimer X-Git-Refname: refs/heads/master X-Git-Oldrev: d010efbfb89721bc9ca9e657e980ff0d8e6187af X-Git-Newrev: 455acc43518744b89d6a795bbba5045bd228060b Message-Id: <20230103154750.0456F3858C2C@sourceware.org> Date: Tue, 3 Jan 2023 15:47:50 +0000 (GMT) List-Id: https://gcc.gnu.org/g:455acc43518744b89d6a795bbba5045bd228060b commit r13-4981-g455acc43518744b89d6a795bbba5045bd228060b Author: Florian Weimer Date: Tue Jan 3 16:47:31 2023 +0100 Revert "Compute a table of DWARF register sizes at compile" This reverts commit 3b6cac2b44b384cd2091eaeaebeb3478c253a25d. Diff: --- gcc/config/msp430/msp430.cc | 11 +++++- gcc/config/rs6000/rs6000.cc | 14 ++++++- gcc/doc/tm.texi | 7 ++-- gcc/dwarf2cfi.cc | 93 +++++++++++++++++++++++---------------------- gcc/target.def | 8 ++-- 5 files changed, 75 insertions(+), 58 deletions(-) diff --git a/gcc/config/msp430/msp430.cc b/gcc/config/msp430/msp430.cc index dbea8d7f50f..6c15780a2b6 100644 --- a/gcc/config/msp430/msp430.cc +++ b/gcc/config/msp430/msp430.cc @@ -3202,9 +3202,11 @@ msp430_expand_eh_return (rtx eh_handler) #undef TARGET_INIT_DWARF_REG_SIZES_EXTRA #define TARGET_INIT_DWARF_REG_SIZES_EXTRA msp430_init_dwarf_reg_sizes_extra void -msp430_init_dwarf_reg_sizes_extra (poly_uint16 *sizes) +msp430_init_dwarf_reg_sizes_extra (tree address) { int i; + rtx addr = expand_normal (address); + rtx mem = gen_rtx_MEM (BLKmode, addr); /* This needs to match msp430_unwind_word_mode (above). */ if (!msp430x) @@ -3216,7 +3218,12 @@ msp430_init_dwarf_reg_sizes_extra (poly_uint16 *sizes) unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1); if (rnum < DWARF_FRAME_REGISTERS) - sizes[rnum] = 4; + { + HOST_WIDE_INT offset = rnum * GET_MODE_SIZE (QImode); + + emit_move_insn (adjust_address (mem, QImode, offset), + gen_int_mode (4, QImode)); + } } } diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 875684a3895..6ac3adcec6b 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -23860,17 +23860,27 @@ rs6000_initial_elimination_offset (int from, int to) /* Fill in sizes of registers used by unwinder. */ static void -rs6000_init_dwarf_reg_sizes_extra (poly_uint16 *sizes) +rs6000_init_dwarf_reg_sizes_extra (tree address) { if (TARGET_MACHO && ! TARGET_ALTIVEC) { int i; + machine_mode mode = TYPE_MODE (char_type_node); + rtx addr = expand_expr (address, NULL_RTX, VOIDmode, EXPAND_NORMAL); + rtx mem = gen_rtx_MEM (BLKmode, addr); + rtx value = gen_int_mode (16, mode); /* On Darwin, libgcc may be built to run on both G3 and G4/5. The unwinder still needs to know the size of Altivec registers. */ for (i = FIRST_ALTIVEC_REGNO; i < LAST_ALTIVEC_REGNO+1; i++) - sizes[i] = 16; + { + int column = DWARF_REG_TO_UNWIND_COLUMN + (DWARF2_FRAME_REG_OUT (DWARF_FRAME_REGNUM (i), true)); + HOST_WIDE_INT offset = column * GET_MODE_SIZE (mode); + + emit_move_insn (adjust_address (mem, mode, offset), value); + } } } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b6d7900f212..8fe49c2ba3d 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9840,14 +9840,13 @@ used to return a smaller mode than the raw mode to prevent call clobbered parts of a register altering the frame register size @end deftypefn -@deftypefn {Target Hook} void TARGET_INIT_DWARF_REG_SIZES_EXTRA (poly_uint16 *@var{sizes}) +@deftypefn {Target Hook} void TARGET_INIT_DWARF_REG_SIZES_EXTRA (tree @var{address}) If some registers are represented in Dwarf-2 unwind information in multiple pieces, define this hook to fill in information about the sizes of those pieces in the table used by the unwinder at runtime. -It will be called by @code{generate_dwarf_reg_sizes} after +It will be called by @code{expand_builtin_init_dwarf_reg_sizes} after filling in a single size corresponding to each hard register; -@var{sizes} is the address of the table. It will contain -@code{DWARF_FRAME_REGISTERS} elements when this hook is called. +@var{address} is the address of the table. @end deftypefn @deftypefn {Target Hook} bool TARGET_ASM_TTYPE (rtx @var{sym}) diff --git a/gcc/dwarf2cfi.cc b/gcc/dwarf2cfi.cc index 4d2bd869a4b..1c70bd83f28 100644 --- a/gcc/dwarf2cfi.cc +++ b/gcc/dwarf2cfi.cc @@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see #include "except.h" /* expand_builtin_dwarf_sp_column */ #include "profile-count.h" /* For expr.h */ -#include "expr.h" /* expand_normal, emit_move_insn */ +#include "expr.h" /* init_return_column_size */ #include "output.h" /* asm_out_file */ #include "debug.h" /* dwarf2out_do_frame, dwarf2out_do_cfi_asm */ #include "flags.h" /* dwarf_debuginfo_p */ @@ -241,6 +241,18 @@ expand_builtin_dwarf_sp_column (void) return GEN_INT (DWARF2_FRAME_REG_OUT (dwarf_regnum, 1)); } +/* MEM is a memory reference for the register size table, each element of + which has mode MODE. Initialize column C as a return address column. */ + +static void +init_return_column_size (scalar_int_mode mode, rtx mem, unsigned int c) +{ + HOST_WIDE_INT offset = c * GET_MODE_SIZE (mode); + HOST_WIDE_INT size = GET_MODE_SIZE (Pmode); + emit_move_insn (adjust_address (mem, mode, offset), + gen_int_mode (size, mode)); +} + /* Datastructure used by expand_builtin_init_dwarf_reg_sizes and init_one_dwarf_reg_size to communicate on what has been done by the latter. */ @@ -262,14 +274,17 @@ struct init_one_dwarf_reg_state use for the size entry to initialize, and INIT_STATE is the communication datastructure conveying what we're doing to our caller. */ -static void -init_one_dwarf_reg_size (int regno, machine_mode regmode, - poly_uint16 *table, - init_one_dwarf_reg_state *init_state) +static +void init_one_dwarf_reg_size (int regno, machine_mode regmode, + rtx table, machine_mode slotmode, + init_one_dwarf_reg_state *init_state) { const unsigned int dnum = DWARF_FRAME_REGNUM (regno); const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1); const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum); + + poly_int64 slotoffset = dcol * GET_MODE_SIZE (slotmode); + poly_int64 regsize = GET_MODE_SIZE (regmode); init_state->processed_regno[regno] = true; @@ -283,22 +298,34 @@ init_one_dwarf_reg_size (int regno, machine_mode regmode, init_state->wrote_return_column = true; } - table[dcol] = GET_MODE_SIZE (regmode); + /* ??? When is this true? Should it be a test based on DCOL instead? */ + if (maybe_lt (slotoffset, 0)) + return; + + emit_move_insn (adjust_address (table, slotmode, slotoffset), + gen_int_mode (regsize, slotmode)); } -/* Fill SIZES with size information for each DWARF register. */ +/* Generate code to initialize the dwarf register size table located + at the provided ADDRESS. */ -static void -generate_dwarf_reg_sizes (poly_uint16 *sizes) +void +expand_builtin_init_dwarf_reg_sizes (tree address) { - for (unsigned int i = 0; i < DWARF_FRAME_REGISTERS; i++) - sizes[i] = poly_uint16{}; + unsigned int i; + scalar_int_mode mode = SCALAR_INT_TYPE_MODE (char_type_node); + rtx addr = expand_normal (address); + rtx mem = gen_rtx_MEM (BLKmode, addr); + + init_one_dwarf_reg_state init_state; - init_one_dwarf_reg_state init_state{}; memset ((char *)&init_state, 0, sizeof (init_state)); - for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++) + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { + machine_mode save_mode; + rtx span; + /* No point in processing a register multiple times. This could happen with register spans, e.g. when a reg is first processed as a piece of a span, then as a register on its own later on. */ @@ -306,11 +333,11 @@ generate_dwarf_reg_sizes (poly_uint16 *sizes) if (init_state.processed_regno[i]) continue; - machine_mode save_mode = targetm.dwarf_frame_reg_mode (i); - rtx span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i)); + save_mode = targetm.dwarf_frame_reg_mode (i); + span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i)); if (!span) - init_one_dwarf_reg_size (i, save_mode, sizes, &init_state); + init_one_dwarf_reg_size (i, save_mode, mem, mode, &init_state); else { for (int si = 0; si < XVECLEN (span, 0); si++) @@ -318,45 +345,19 @@ generate_dwarf_reg_sizes (poly_uint16 *sizes) rtx reg = XVECEXP (span, 0, si); init_one_dwarf_reg_size - (REGNO (reg), GET_MODE (reg), sizes, &init_state); + (REGNO (reg), GET_MODE (reg), mem, mode, &init_state); } } } if (!init_state.wrote_return_column) - sizes[DWARF_FRAME_RETURN_COLUMN] = GET_MODE_SIZE (Pmode); + init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN); #ifdef DWARF_ALT_FRAME_RETURN_COLUMN - sizes[DWARF_ALT_FRAME_RETURN_COLUMN] = GET_MODE_SIZE (Pmode); + init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN); #endif - if (targetm.init_dwarf_reg_sizes_extra != nullptr) - targetm.init_dwarf_reg_sizes_extra (sizes); -} - -/* Generate code to initialize the dwarf register size table located - at the provided ADDRESS. */ - -void -expand_builtin_init_dwarf_reg_sizes (tree address) -{ - poly_uint16 *sizes = XALLOCAVEC (poly_uint16, DWARF_FRAME_REGISTERS); - generate_dwarf_reg_sizes (sizes); - - scalar_int_mode mode = SCALAR_INT_TYPE_MODE (char_type_node); - rtx addr = expand_normal (address); - rtx mem = gen_rtx_MEM (BLKmode, addr); - for (unsigned int i = 0; i < DWARF_FRAME_REGISTERS; ++i) - { - unsigned short value; - if (sizes[i].is_constant (&value) && value == 0) - /* No need to set the value to zero again. */ - continue; - - HOST_WIDE_INT offset = i * GET_MODE_SIZE (mode); - emit_move_insn (adjust_address (mem, mode, offset), - gen_int_mode (sizes[i], mode)); - } + targetm.init_dwarf_reg_sizes_extra (address); } diff --git a/gcc/target.def b/gcc/target.def index da5dd31d7a4..db8af0cbe81 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4039,11 +4039,11 @@ DEFHOOK "If some registers are represented in Dwarf-2 unwind information in\n\ multiple pieces, define this hook to fill in information about the\n\ sizes of those pieces in the table used by the unwinder at runtime.\n\ -It will be called by @code{generate_dwarf_reg_sizes} after\n\ +It will be called by @code{expand_builtin_init_dwarf_reg_sizes} after\n\ filling in a single size corresponding to each hard register;\n\ -@var{sizes} is the address of the table. It will contain\n\ -@code{DWARF_FRAME_REGISTERS} elements when this hook is called.", - void, (poly_uint16 *sizes), nullptr) +@var{address} is the address of the table.", + void, (tree address), + hook_void_tree) /* Fetch the fixed register(s) which hold condition codes, for targets where it makes sense to look for duplicate assignments to