[DWARF] Enable DW_CFA_VAL_EXPRESSION support
authorJiong Wang <jiong.wang@arm.com>
Thu, 3 Nov 2016 17:32:03 +0000 (17:32 +0000)
committerJiong Wang <jiwang@gcc.gnu.org>
Thu, 3 Nov 2016 17:32:03 +0000 (17:32 +0000)
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
gcc/dwarf2cfi.c
gcc/dwarf2out.c
gcc/reg-notes.def

index 680b54947c2ced6a328a1b1dc842e71c493ff695..aa47e5db81407a0cb78414e0ad39a0b9be783bc8 100644 (file)
@@ -1,3 +1,17 @@
+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>
 
        PR rtl-optimization/78186
index da9da52353ea3a1a42e3e25cb5cb11e5f0358858..b6e8b4b6c61c251fc3d4be5abd86e151cee27abb 100644 (file)
@@ -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);
index 24b85c15676b8ba31704814f46eb0e23dd107fce..b6161e519ee271899adb55ace7e490c48a8cb7af 100644 (file)
@@ -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)
        {
index 5374169b9a417d3695b685bfce2b44ff5d8c89e1..962dbb8007e5150d733344dd5a75495d9adf6a79 100644 (file)
@@ -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