Commit ac5b3eff by Jiong Wang Committed by Jiong Wang

[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
parent 122e3608
2016-11-03 Jiong Wang <jiong.wang@arm.com>
* 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 <segher@kernel.crashing.org> 2016-11-03 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/78186 PR rtl-optimization/78186
...@@ -1236,7 +1236,7 @@ dwarf2out_frame_debug_cfa_register (rtx set) ...@@ -1236,7 +1236,7 @@ dwarf2out_frame_debug_cfa_register (rtx set)
reg_save (sregno, dregno, 0); 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 static void
dwarf2out_frame_debug_cfa_expression (rtx set) dwarf2out_frame_debug_cfa_expression (rtx set)
...@@ -1268,6 +1268,29 @@ 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); 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. */ /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */
static void static void
...@@ -2034,10 +2057,16 @@ dwarf2out_frame_debug (rtx_insn *insn) ...@@ -2034,10 +2057,16 @@ dwarf2out_frame_debug (rtx_insn *insn)
break; break;
case REG_CFA_EXPRESSION: case REG_CFA_EXPRESSION:
case REG_CFA_VAL_EXPRESSION:
n = XEXP (note, 0); n = XEXP (note, 0);
if (n == NULL) if (n == NULL)
n = single_set (insn); 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; handled_one = true;
break; break;
...@@ -3016,7 +3045,8 @@ output_cfa_loc (dw_cfi_ref cfi, int for_eh) ...@@ -3016,7 +3045,8 @@ output_cfa_loc (dw_cfi_ref cfi, int for_eh)
dw_loc_descr_ref loc; dw_loc_descr_ref loc;
unsigned long size; 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 = unsigned r =
DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); 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) ...@@ -3042,7 +3072,8 @@ output_cfa_loc_raw (dw_cfi_ref cfi)
dw_loc_descr_ref loc; dw_loc_descr_ref loc;
unsigned long size; 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 = unsigned r =
DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1); 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) ...@@ -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_def_cfa_expression:
case DW_CFA_expression: case DW_CFA_expression:
case DW_CFA_val_expression:
output_cfa_loc (cfi, for_eh); output_cfa_loc (cfi, for_eh);
break; break;
...@@ -3303,16 +3335,13 @@ output_cfi_directive (FILE *f, dw_cfi_ref cfi) ...@@ -3303,16 +3335,13 @@ output_cfi_directive (FILE *f, dw_cfi_ref cfi)
break; break;
case DW_CFA_def_cfa_expression: 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_expression:
case DW_CFA_val_expression:
if (f != asm_out_file) 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; break;
} }
fprintf (f, "\t.cfi_escape %#x,", cfi->dw_cfi_opc); fprintf (f, "\t.cfi_escape %#x,", cfi->dw_cfi_opc);
......
...@@ -525,6 +525,7 @@ dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi) ...@@ -525,6 +525,7 @@ dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
case DW_CFA_def_cfa_register: case DW_CFA_def_cfa_register:
case DW_CFA_register: case DW_CFA_register:
case DW_CFA_expression: case DW_CFA_expression:
case DW_CFA_val_expression:
return dw_cfi_oprnd_reg_num; return dw_cfi_oprnd_reg_num;
case DW_CFA_def_cfa_offset: case DW_CFA_def_cfa_offset:
...@@ -558,6 +559,7 @@ dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi) ...@@ -558,6 +559,7 @@ dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
return dw_cfi_oprnd_reg_num; return dw_cfi_oprnd_reg_num;
case DW_CFA_expression: case DW_CFA_expression:
case DW_CFA_val_expression:
return dw_cfi_oprnd_loc; return dw_cfi_oprnd_loc;
default: default:
...@@ -15365,6 +15367,46 @@ mem_loc_descriptor (rtx rtl, machine_mode mode, ...@@ -15365,6 +15367,46 @@ mem_loc_descriptor (rtx rtl, machine_mode mode,
resolve_one_addr (&rtl); resolve_one_addr (&rtl);
goto symref; 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: default:
if (flag_checking) if (flag_checking)
{ {
......
...@@ -149,6 +149,11 @@ REG_NOTE (CFA_REGISTER) ...@@ -149,6 +149,11 @@ REG_NOTE (CFA_REGISTER)
store of a register to an arbitrary (non-validated) memory address. */ store of a register to an arbitrary (non-validated) memory address. */
REG_NOTE (CFA_EXPRESSION) 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 /* 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 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 or the like. Either the attached rtx, or the destination of the insn's
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment