Hi Indu, Cupertino,

On 3/4/24 10:00, Indu Bhagat wrote:
> From: Cupertino Miranda <cupertino.mira...@oracle.com>
> 
> [Changes from V1]
>   - Refactor the code a bit.
> [End of changes from V1]
> 
> PR debug/114186
> 
> DWARF DIEs of type DW_TAG_subrange_type are linked together to represent
> the information about the subsequent dimensions.  The CTF processing was
> so far working through them in the opposite (incorrect) order.
> 
> While fixing the issue, refactor the code a bit for readability.
> 
> co-authored-By: Indu Bhagat <indu.bha...@oracle.com>

Thanks for the patch and refactor. I do find v2 easier to follow.
Two very minor typos in comments, noted inline below.

Otherwise, LGTM and OK.
Thanks!

> 
> gcc/
>       PR debug/114186
>       * dwarf2ctf.cc (gen_ctf_array_type): Invoke the ctf_add_array ()
>       in the correct order of the dimensions.
>         (gen_ctf_subrange_type): Refactor out handling of
>       DW_TAG_subrange_type DIE to here.
> 
> gcc/testsuite/
>       PR debug/114186
>       * gcc.dg/debug/ctf/ctf-array-6.c: Add test.
> ---
> 
> Testing notes:
> 
> Regression tested on x86_64-linux-gnu default target.
> Regression tested for target bpf-unknown-none (btf.exp, ctf.exp, bpf.exp).
> 
> ---
>  gcc/dwarf2ctf.cc                             | 153 +++++++++----------
>  gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c |  14 ++
>  2 files changed, 84 insertions(+), 83 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c
> 
> diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
> index dca86edfffa9..3985de115a79 100644
> --- a/gcc/dwarf2ctf.cc
> +++ b/gcc/dwarf2ctf.cc
> @@ -349,105 +349,92 @@ gen_ctf_pointer_type (ctf_container_ref ctfc, 
> dw_die_ref ptr_type)
>    return ptr_type_id;
>  }
>  
> -/* Generate CTF for an array type.  */
> +/* Recursively generate CTF for array dimensions starting at DIE C (of type
> +   DW_TAG_subrange_type) until DIE LAST (of type DW_TAG_subrange_type) is
> +   reached.  ARRAY_ELEMS_TYPE_ID is base type for the array.  */
>  
>  static ctf_id_t
> -gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type)
> +gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_id_t array_elems_type_id,
> +                    dw_die_ref c, dw_die_ref last)
>  {
> -  dw_die_ref c;
> -  ctf_id_t array_elems_type_id = CTF_NULL_TYPEID;
> +  ctf_arinfo_t arinfo;
> +  ctf_id_t array_node_type_id = CTF_NULL_TYPEID;
> +
> +  dw_attr_node *upper_bound_at;
> +  dw_die_ref array_index_type;
> +  uint32_t array_num_elements;
> +
> +  /* When DW_AT_upper_bound is used to specify the size of an
> +     array in DWARF, it is usually an unsigned constant
> +     specifying the upper bound index of the array.  However,
> +     for unsized arrays, such as foo[] or bar[0],
> +     DW_AT_upper_bound is a signed integer constant
> +     instead.  */
> +
> +  upper_bound_at = get_AT (c, DW_AT_upper_bound);
> +  if (upper_bound_at
> +      && AT_class (upper_bound_at) == dw_val_class_unsigned_const)
> +    /* This is the ound index.  */

typo, I guess this is meant to be "bound" ? 

> +    array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1;
> +  else if (get_AT (c, DW_AT_count))
> +    array_num_elements = get_AT_unsigned (c, DW_AT_count);
> +  else
> +    {
> +      /* This is a VLA of some kind.  */
> +      array_num_elements = 0;
> +    }
>  
> -  int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector);
> -  if (vector_type_p)
> -    return array_elems_type_id;
> +  /* Ok, mount and register the array type.  Note how the array
> +     type we register here is the type of the elements in
> +     subsequent "dimensions", if there are any.  */
> +  arinfo.ctr_nelems = array_num_elements;
>  
> -  dw_die_ref array_elems_type = ctf_get_AT_type (array_type);
> +  array_index_type = ctf_get_AT_type (c);
> +  arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type);
>  
> -  /* First, register the type of the array elements if needed.  */
> -  array_elems_type_id = gen_ctf_type (ctfc, array_elems_type);
> +  if (c == last)
> +    arinfo.ctr_contents = array_elems_type_id;
> +  else
> +    arinfo.ctr_contents = gen_ctf_subrange_type (ctfc, array_elems_type_id,
> +                                              dw_get_die_sib (c), last);
>  
> -  /* DWARF array types pretend C supports multi-dimensional arrays.
> -     So for the type int[N][M], the array type DIE contains two
> -     subrange_type children, the first with upper bound N-1 and the
> -     second with upper bound M-1.
> +  if (!ctf_type_exists (ctfc, c, &array_node_type_id))
> +    array_node_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, c);
>  
> -     CTF, on the other hand, just encodes each array type in its own
> -     array type CTF struct.  Therefore we have to iterate on the
> -     children and create all the needed types.  */
> +  return array_node_type_id;
> +}
>  
> -  c = dw_get_die_child (array_type);
> -  gcc_assert (c);
> -  do
> -    {
> -      ctf_arinfo_t arinfo;
> -      dw_die_ref array_index_type;
> -      uint32_t array_num_elements;
> +/* Generate CTF for an ARRAY_TYPE.  */
>  
> -      c = dw_get_die_sib (c);
> +static ctf_id_t
> +gen_ctf_array_type (ctf_container_ref ctfc,
> +                 dw_die_ref array_type)
> +{
> +  dw_die_ref first, last, array_elems_type;
> +  ctf_id_t array_elems_type_id = CTF_NULL_TYPEID;
> +  ctf_id_t array_type_id = CTF_NULL_TYPEID;
>  
> -      if (dw_get_die_tag (c) == DW_TAG_subrange_type)
> -     {
> -       dw_attr_node *upper_bound_at;
> -
> -       array_index_type = ctf_get_AT_type (c);
> -
> -       /* When DW_AT_upper_bound is used to specify the size of an
> -          array in DWARF, it is usually an unsigned constant
> -          specifying the upper bound index of the array.  However,
> -          for unsized arrays, such as foo[] or bar[0],
> -          DW_AT_upper_bound is a signed integer constant
> -          instead.  */
> -
> -       upper_bound_at = get_AT (c, DW_AT_upper_bound);
> -       if (upper_bound_at
> -           && AT_class (upper_bound_at) == dw_val_class_unsigned_const)
> -         /* This is the upper bound index.  */
> -         array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1;
> -       else if (get_AT (c, DW_AT_count))
> -         array_num_elements = get_AT_unsigned (c, DW_AT_count);
> -       else
> -         {
> -           /* This is a VLA of some kind.  */
> -           array_num_elements = 0;
> -         }
> -     }
> -      else if (dw_get_die_tag (c) == DW_TAG_enumeration_type)
> -     {
> -       array_index_type = 0;
> -       array_num_elements = 0;
> -       /* XXX writeme. */
> -       gcc_assert (1);
> -     }
> -      else
> -     gcc_unreachable ();
> +  int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector);
> +  if (vector_type_p)
> +    return array_elems_type_id;
>  
> -      /* Ok, mount and register the array type.  Note how the array
> -      type we register here is the type of the elements in
> -      subsequent "dimensions", if there are any.  */
> +  /* Find the first and last array dimension DIEs.  */
> +  last = dw_get_die_child (array_type);
> +  first = dw_get_die_sib (last);
>  
> -      arinfo.ctr_nelems = array_num_elements;
> -      if (array_index_type)
> -     arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type);
> -      else
> -     arinfo.ctr_index = gen_ctf_type (ctfc, ctf_array_index_die);
> +  /* Type de-duplication.
> +     Consult the ctfc_types before adding CTF type for the first dimension.  
> */
> +  if (!ctf_type_exists (ctfc, first, &array_type_id))
> +    {
> +      array_elems_type = ctf_get_AT_type (array_type);
> +      /* First, register the type of the array elements if needed.  */
> +      array_elems_type_id = gen_ctf_type (ctfc, array_elems_type);
>  
> -      arinfo.ctr_contents = array_elems_type_id;
> -      if (!ctf_type_exists (ctfc, c, &array_elems_type_id))
> -     array_elems_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo,
> -                                          c);
> +      array_type_id = gen_ctf_subrange_type (ctfc, array_elems_type_id, 
> first,
> +                                          last);
>      }
> -  while (c != dw_get_die_child (array_type));
>  
> -#if 0
> -  /* Type de-duplication.
> -     Consult the ctfc_types hash again before adding the CTF array type 
> because
> -     there can be cases where an array_type type may have been added by the
> -     gen_ctf_type call above.  */
> -  if (!ctf_type_exists (ctfc, array_type, &type_id))
> -    type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, array_type);
> -#endif
> -
> -  return array_elems_type_id;
> +  return array_type_id;
>  }
>  
>  /* Generate CTF for a typedef.  */
> diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c 
> b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c
> new file mode 100644
> index 000000000000..5ecbb049535d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c
> @@ -0,0 +1,14 @@
> +/* CTF generation for multidimentional array.  */

nit: multidimensional (note 's' rather than 't')

> +
> +/* { dg-do compile )  */
> +/* { dg-options "-O0 -gctf -dA" } */
> +
> +/* { dg-final { scan-assembler-times "\[\t \]+0x2\[\t \]+\[^\n\]*cta_nelems" 
> 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]+0x3\[\t \]+\[^\n\]*cta_nelems" 
> 1 } } */
> +/* { dg-final { scan-assembler-times "\[\t \]+0x4\[\t \]+\[^\n\]*cta_nelems" 
> 1 } } */
> +
> +/* { dg-final { scan-assembler-times "\t.\[^\t \]+\t0x1\[\t \]+# 
> cta_contents\[\\r\\n\]+\t.\[^\t \]+\t0x2\[\t \]+# 
> cta_index\[\\r\\n\]+\t.\[^\t \]+\t0x4\[\t \]+# cta_nelems" 1 } } */
> +/* { dg-final { scan-assembler-times "\t.\[^\t \]+\t0x3\[\t \]+# 
> cta_contents\[\\r\\n\]+\t.\[^\t \]+\t0x2\[\t \]+# 
> cta_index\[\\r\\n\]+\t.\[^\t \]+\t0x3\[\t \]+# cta_nelems" 1 } } */
> +/* { dg-final { scan-assembler-times "\t.\[^\t \]+\t0x4\[\t \]+# 
> cta_contents\[\\r\\n\]+\t.\[^\t \]+\t0x2\[\t \]+# 
> cta_index\[\\r\\n\]+\t.\[^\t \]+\t0x2\[\t \]+# cta_nelems" 1 } } */
> +
> +int a[2][3][4];

Reply via email to