From ac5b3efff29c2b0bf056adbb1e075927692653da Mon Sep 17 00:00:00 2001 From: Jiong Wang Date: Thu, 3 Nov 2016 17:32:03 +0000 Subject: [PATCH] [DWARF] Enable DW_CFA_VAL_EXPRESSION support gcc/ * reg-notes.def (CFA_VAL_EXPRESSION): New entry. * dwarf2cfi.c (dwarf2out_frame_debug_cfa_val_expression): New function. (dwarf2out_frame_debug): Support REG_CFA_VAL_EXPRESSION. (output_cfa_loc): Support DW_CFA_val_expression. (output_cfa_loc_raw): Likewise. (output_cfi): Likewise. (output_cfi_directive): Likewise. * dwarf2out.c (dw_cfi_oprnd1_desc): Support DW_CFA_val_expression. (dw_cfi_oprnd2_desc): Likewise. (mem_loc_descriptor): Recognize new pattern generated for value expression. From-SVN: r241826 --- gcc/ChangeLog | 14 +++++++++++++ gcc/dwarf2cfi.c | 51 +++++++++++++++++++++++++++++++++++++---------- gcc/dwarf2out.c | 42 ++++++++++++++++++++++++++++++++++++++ gcc/reg-notes.def | 5 +++++ 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 680b54947c2..aa47e5db814 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-11-03 Jiong Wang + + * reg-notes.def (CFA_VAL_EXPRESSION): New entry. + * dwarf2cfi.c (dwarf2out_frame_debug_cfa_val_expression): New function. + (dwarf2out_frame_debug): Support REG_CFA_VAL_EXPRESSION. + (output_cfa_loc): Support DW_CFA_val_expression. + (output_cfa_loc_raw): Likewise. + (output_cfi): Likewise. + (output_cfi_directive): Likewise. + * dwarf2out.c (dw_cfi_oprnd1_desc): Support DW_CFA_val_expression. + (dw_cfi_oprnd2_desc): Likewise. + (mem_loc_descriptor): Recognize new pattern generated for value + expression. + 2016-11-03 Segher Boessenkool PR rtl-optimization/78186 diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index da9da52353e..b6e8b4b6c61 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -1236,7 +1236,7 @@ dwarf2out_frame_debug_cfa_register (rtx set) reg_save (sregno, dregno, 0); } -/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION note. */ +/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION note. */ static void dwarf2out_frame_debug_cfa_expression (rtx set) @@ -1268,6 +1268,29 @@ dwarf2out_frame_debug_cfa_expression (rtx set) update_row_reg_save (cur_row, regno, cfi); } +/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_VAL_EXPRESSION + note. */ + +static void +dwarf2out_frame_debug_cfa_val_expression (rtx set) +{ + rtx dest = SET_DEST (set); + gcc_assert (REG_P (dest)); + + rtx span = targetm.dwarf_register_span (dest); + gcc_assert (!span); + + rtx src = SET_SRC (set); + dw_cfi_ref cfi = new_cfi (); + cfi->dw_cfi_opc = DW_CFA_val_expression; + cfi->dw_cfi_oprnd1.dw_cfi_reg_num = dwf_regno (dest); + cfi->dw_cfi_oprnd2.dw_cfi_loc + = mem_loc_descriptor (src, GET_MODE (src), + GET_MODE (dest), VAR_INIT_STATUS_INITIALIZED); + add_cfi (cfi); + update_row_reg_save (cur_row, dwf_regno (dest), cfi); +} + /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */ static void @@ -2034,10 +2057,16 @@ dwarf2out_frame_debug (rtx_insn *insn) break; case REG_CFA_EXPRESSION: + case REG_CFA_VAL_EXPRESSION: n = XEXP (note, 0); if (n == NULL) n = single_set (insn); - dwarf2out_frame_debug_cfa_expression (n); + + if (REG_NOTE_KIND (note) == REG_CFA_EXPRESSION) + dwarf2out_frame_debug_cfa_expression (n); + else + dwarf2out_frame_debug_cfa_val_expression (n); + handled_one = true; break; @@ -3016,7 +3045,8 @@ output_cfa_loc (dw_cfi_ref cfi, int for_eh) dw_loc_descr_ref loc; unsigned long size; - if (cfi->dw_cfi_opc == DW_CFA_expression) + if (cfi->dw_cfi_opc == DW_CFA_expression + || cfi->dw_cfi_opc == DW_CFA_val_expression) { unsigned r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); @@ -3042,7 +3072,8 @@ output_cfa_loc_raw (dw_cfi_ref cfi) dw_loc_descr_ref loc; unsigned long size; - if (cfi->dw_cfi_opc == DW_CFA_expression) + if (cfi->dw_cfi_opc == DW_CFA_expression + || cfi->dw_cfi_opc == DW_CFA_val_expression) { unsigned r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1); @@ -3189,6 +3220,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh) case DW_CFA_def_cfa_expression: case DW_CFA_expression: + case DW_CFA_val_expression: output_cfa_loc (cfi, for_eh); break; @@ -3303,16 +3335,13 @@ output_cfi_directive (FILE *f, dw_cfi_ref cfi) break; case DW_CFA_def_cfa_expression: - if (f != asm_out_file) - { - fprintf (f, "\t.cfi_def_cfa_expression ...\n"); - break; - } - /* FALLTHRU */ case DW_CFA_expression: + case DW_CFA_val_expression: if (f != asm_out_file) { - fprintf (f, "\t.cfi_cfa_expression ...\n"); + fprintf (f, "\t.cfi_%scfa_%sexpression ...\n", + cfi->dw_cfi_opc == DW_CFA_def_cfa_expression ? "def_" : "", + cfi->dw_cfi_opc == DW_CFA_val_expression ? "val_" : ""); break; } fprintf (f, "\t.cfi_escape %#x,", cfi->dw_cfi_opc); diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 24b85c15676..b6161e519ee 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -525,6 +525,7 @@ dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi) case DW_CFA_def_cfa_register: case DW_CFA_register: case DW_CFA_expression: + case DW_CFA_val_expression: return dw_cfi_oprnd_reg_num; case DW_CFA_def_cfa_offset: @@ -558,6 +559,7 @@ dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi) return dw_cfi_oprnd_reg_num; case DW_CFA_expression: + case DW_CFA_val_expression: return dw_cfi_oprnd_loc; default: @@ -15365,6 +15367,46 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, resolve_one_addr (&rtl); goto symref; + /* RTL sequences inside PARALLEL record a series of DWARF operations for + the expression. An UNSPEC rtx represents a raw DWARF operation, + new_loc_descr is called for it to build the operation directly. + Otherwise mem_loc_descriptor is called recursively. */ + case PARALLEL: + { + int index = 0; + dw_loc_descr_ref exp_result = NULL; + + for (; index < XVECLEN (rtl, 0); index++) + { + rtx elem = XVECEXP (rtl, 0, index); + if (GET_CODE (elem) == UNSPEC) + { + /* Each DWARF operation UNSPEC contain two operands, if + one operand is not used for the operation, const0_rtx is + passed. */ + gcc_assert (XVECLEN (elem, 0) == 2); + + HOST_WIDE_INT dw_op = XINT (elem, 1); + HOST_WIDE_INT oprnd1 = INTVAL (XVECEXP (elem, 0, 0)); + HOST_WIDE_INT oprnd2 = INTVAL (XVECEXP (elem, 0, 1)); + exp_result + = new_loc_descr ((enum dwarf_location_atom) dw_op, oprnd1, + oprnd2); + } + else + exp_result + = mem_loc_descriptor (elem, mode, mem_mode, + VAR_INIT_STATUS_INITIALIZED); + + if (!mem_loc_result) + mem_loc_result = exp_result; + else + add_loc_descr (&mem_loc_result, exp_result); + } + + break; + } + default: if (flag_checking) { diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def index 5374169b9a4..962dbb8007e 100644 --- a/gcc/reg-notes.def +++ b/gcc/reg-notes.def @@ -149,6 +149,11 @@ REG_NOTE (CFA_REGISTER) store of a register to an arbitrary (non-validated) memory address. */ REG_NOTE (CFA_EXPRESSION) +/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex + for FRAME_RELATED_EXPR intuition. The DWARF expression computes the value of + the given register. */ +REG_NOTE (CFA_VAL_EXPRESSION) + /* Attached to insns that are RTX_FRAME_RELATED_P, with the information that this is a restore operation, i.e. will result in DW_CFA_restore or the like. Either the attached rtx, or the destination of the insn's -- 2.30.2