diff mbox

Enable DW_OP_VAL_EXPRESSION support in dwarf module

Message ID 6e36fda9-1092-2782-0e03-719b8206febb@foss.arm.com
State New
Headers show

Commit Message

Jiong Wang Nov. 2, 2016, 2:18 p.m. UTC
On 02/11/16 13:42, Jakub Jelinek wrote:
> On Wed, Nov 02, 2016 at 01:26:48PM +0000, Jiong Wang wrote:

>> -/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION note. */

>> +/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION note.  */

>

> Too long line.


Hmm, it shows 80 columns under my editor.  I guess '+' is counted in?

>

>> +    /* RTL sequences inside PARALLEL are raw expression representation.

>> +

>> +       mem_loc_descriptor can be used to build generic DWARF expressions for

>> +       DW_CFA_expression and DW_CFA_val_expression where the expression may can

>> +       not be represented using normal RTL sequences.  In this case, group all

>> +       expression operations (DW_OP_*) inside a PARALLEL.  For those DW_OP which

>> +       doesn't have RTL mapping, wrap it using UNSPEC.  The logic for parsing

>> +       PARALLEL sequences is:

>> +

>> +	foreach elem inside PARALLEL

>> +	  if (elem is UNSPEC)

>> +	    dw_op =  XINT (elem, 1) (DWARF operation is kept as UNSPEC number)

>> +	    oprnd1 = XVECEXP (elem, 0, 0)

>> +	    oprnd2 = XVECEXP (elem, 0, 1)

>> +	  else

>> +	    call mem_loc_descriptor  */

>

> Not sure if it is a good idea to document in weirdly formatted

> pseudo-language what the code actually does a few lines below.  IMHO either

> express it in words, or don't express it at all.


OK, fixed. I replaced these comments as some brief words.

>

>> +		exp_result =

>> +		  new_loc_descr ((enum dwarf_location_atom) dw_op, oprnd1,

>> +				 oprnd2);

>

> Wrong formatting, = should be on the next line.

>

>> +	      }

>> +	    else

>> +	      exp_result =

>> +		mem_loc_descriptor (elem, mode, mem_mode,

>> +				    VAR_INIT_STATUS_INITIALIZED);

>

> Likewise.


Both fixed. Patch updated, please review.

Thanks.

gcc/
2016-11-02  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.

Comments

Jason Merrill Nov. 2, 2016, 3:37 p.m. UTC | #1
OK.

On Wed, Nov 2, 2016 at 10:18 AM, Jiong Wang <jiong.wang@foss.arm.com> wrote:
> On 02/11/16 13:42, Jakub Jelinek wrote:

>>

>> On Wed, Nov 02, 2016 at 01:26:48PM +0000, Jiong Wang wrote:

>>>

>>> -/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION

>>> note. */

>>> +/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION

>>> note.  */

>>

>>

>> Too long line.

>

>

> Hmm, it shows 80 columns under my editor.  I guess '+' is counted in?

>

>>

>>> +    /* RTL sequences inside PARALLEL are raw expression representation.

>>> +

>>> +       mem_loc_descriptor can be used to build generic DWARF expressions

>>> for

>>> +       DW_CFA_expression and DW_CFA_val_expression where the expression

>>> may can

>>> +       not be represented using normal RTL sequences.  In this case,

>>> group all

>>> +       expression operations (DW_OP_*) inside a PARALLEL.  For those

>>> DW_OP which

>>> +       doesn't have RTL mapping, wrap it using UNSPEC.  The logic for

>>> parsing

>>> +       PARALLEL sequences is:

>>> +

>>> +       foreach elem inside PARALLEL

>>> +         if (elem is UNSPEC)

>>> +           dw_op =  XINT (elem, 1) (DWARF operation is kept as UNSPEC

>>> number)

>>> +           oprnd1 = XVECEXP (elem, 0, 0)

>>> +           oprnd2 = XVECEXP (elem, 0, 1)

>>> +         else

>>> +           call mem_loc_descriptor  */

>>

>>

>> Not sure if it is a good idea to document in weirdly formatted

>> pseudo-language what the code actually does a few lines below.  IMHO

>> either

>> express it in words, or don't express it at all.

>

>

> OK, fixed. I replaced these comments as some brief words.

>

>>

>>> +               exp_result =

>>> +                 new_loc_descr ((enum dwarf_location_atom) dw_op,

>>> oprnd1,

>>> +                                oprnd2);

>>

>>

>> Wrong formatting, = should be on the next line.

>>

>>> +             }

>>> +           else

>>> +             exp_result =

>>> +               mem_loc_descriptor (elem, mode, mem_mode,

>>> +                                   VAR_INIT_STATUS_INITIALIZED);

>>

>>

>> Likewise.

>

>

> Both fixed. Patch updated, please review.

>

>

> Thanks.

>

> gcc/

> 2016-11-02  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.

>
diff mbox

Patch

commit 36de0173c17efcc30c56ef10304377e71313e8bc
Author: Jiong Wang <jiong.wang@arm.com>
Date:   Wed Oct 19 15:42:04 2016 +0100

    dwarf val expression

diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 6491d5a..b8c88fb 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -1235,7 +1235,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)
@@ -1267,6 +1267,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
@@ -2033,10 +2056,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;
 
@@ -3015,7 +3044,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);
@@ -3041,7 +3071,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);
@@ -3188,6 +3219,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;
 
@@ -3302,16 +3334,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 4a3df33..4a5c602 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -518,6 +518,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:
@@ -551,6 +552,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:
@@ -14236,6 +14238,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 5374169..962dbb8 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