[Dwarf-discuss] ISSUE: CPU vector types.

Ben Woodard woodard@redhat.com
Fri Mar 24 18:19:52 GMT 2023


I was working on this before the change of administration.

Vector types have been around for a very long time and compilers use 
them but are not handled in the DWARF standard right on DWARF5. I think 
that this was basically something that was overlooked and no one filed 
an issue to get it addressed in the standard.

There are two different proposals about how to handle them and I believe 
that the committee should discuss the two options and then decide a 
course of action.

At the bottom of this email is my proposal. I will admit that in its 
current state it is a work in progress. My original intent was to simply 
codify the existing behavior as implemented by GCC and LLVM (and 
probably other compilers) moving it from a vendor attribute to something 
that was in the standard. However, at the time I was working with Tony 
Tye and the people at AMD on one of their proposals toto better support 
GPUs and this involved a lot of work on the DWARF stack and the 
operations done within them. This led me to realize a problem with my 
initial proposal and that was that it didn't consider the impacts on the 
DWARF stack operations. I reworked my proposal to include changes in 
that area of the standard. Essentially it adds language to all 
operations that were limited to a base type now would also work on a 
vector type of a base type. Tony raised an objection to this and argued 
that handling vector types on the DWARF stack was not necessary. I have 
not put in the time to really come up with a counter example to that 
assertion. He may be correct. I'm personally not sure. No current 
compiler that I am aware of actually generates DWARF that makes use of 
the DWARF stack with vector types. My intuition is that there may be a 
case related to scatter gather where it could be useful to make use 
vector registers on the DWARF stack.

Tony Tye has a different proposal. 
https://github.com/t-tye/dwarf-locations/blob/main/014-vector-base-types.txt 


His proposal basically amounts to make vector types base types. I can't 
say that I disagree with that overall approach. My concerns are:

 1. It breaks with existing behavior.
 2. It would greatly increase the number of base types for a platform. I
    think that it would be the combinatorial expansion of all the
    available encodings and the architecture's available vector lengths.
 3. There is an interaction between the Platform Specific ABI and the
    base types for an architecture. I'm not sure but I think that the PS
    ABI for the various architectures might need revision given this
    change. Given how many architectures there are
 4. It would immediately allow the large vector registers on the DWARF
    stack and I fear that some DWARF stack implementations which are
    currently based on a platform's size of an INT would break. Some
    architecture's vector registers could be as large as 2048b.
 5. I don't know how it will deal with hardware implementation variable
    vector lengths like ARM's SVE or RISC-V RVV. Just for reference for
    people who may not know this is a quick intro to SVE
    https://www.stonybrook.edu/commcms/ookami/support/_docs/3%20-%20Intro%20to%20SVE.pdf

Anyway, my biggest concern is that in the DWARF6 process vector register 
types get standardized. In general I have come to respect Tony as a very 
thoughtful architect, so I would not be upset if his proposal were 
accepted over mine. I would just like to make sure that the concerns 
that I've pointed out above are considered.

----------------------------------

Vector registers

It has been the long standing existing practice to treat hardware
vector registers as arrays of a fundamental base type. To deliniate
these hardware register arrays from arrays in the language source they
have been given the DW_AT_GNU_vector attribute. This proposal simply
standardizes the existing behavior.

In Section 2.2 Attribute Types, DW_AT_vector and
DW_AT_variable_vector_width shall be added to Table 2.2

--------------------------------------------------------------------
     DW_AT_vector                | A hardware vector register
     DW_AT_variable_vector_width | Array bound for hardware
                                 | implementation defined vector register
                                 | width
--------------------------------------------------------------------

The hyperlink in the "Identifies or Specifies" column shall point to
the paragraph added to Section 5.5 below for DW_AT_vector and the
paragraph added to Section 5.13 below for
DW_AT_variable_vector_width.

In Section 2.5.1.2 Register values replace the description of
DW_OP_regval_type with the following:

--------------------------------------------------------------------
     The DW_OP_regval_type operation provides the contents of a given
     register interpreted as a value of a given type. The first operand
     is an unsigned LEB128 number, which identifies a register whose
     contents is to be pushed onto the stack. The second operand is an
     unsigned LEB128 number that represents the offset of a debugging
     information entry in the current compilation unit, which must be a
     DW_TAG_base_type entry that provides the type of the value
     contained in the specified register or it must be an
     DW_TAG_array_type with a DW_AT_vector attribute.

     [non-normative] A DW_TAG_array_type with a DW_AT_vector attribute
     is the way that a vector register is specified and can be
     considered a base type for the architecture.
--------------------------------------------------------------------

In Section 2.5.1.3 Stack Operations replace the description of
DW_OP_deref_type with the following:

--------------------------------------------------------------------
     The DW_OP_deref_type operation behaves like the DW_OP_deref_size
     operation: it pops the top stack entry and treats it as an
     address. The popped value must have an integral type. The value
     retrieved from that address is pushed together with a type
     identifier. In the DW_OP_deref_type operation, the size in bytes
     of the data retrieved from the dereferenced address is specified
     by the first operand. This operand is a 1-byte unsigned integral
     constant whose value which is the same as the size of the type
     referenced by the second operand. The second operand is an
     unsigned LEB128 integer that represents the offset of a debugging
     information entry in the current compilation unit that provides
     the type of the data pushed. This entry must be either a
     DW_TAG_base_type entry or a DW_TAG_array_type entry with a
     DW_AT_vector attribute.
--------------------------------------------------------------------

Replace the description of DW_OP_xderef_type with the following:

--------------------------------------------------------------------
     The DW_OP_xderef_type operation behaves like the DW_OP_xderef_size
     operation: it pops the top two stack entries, treats them as an
     address and an address space identifier, and pushes the value
     retrieved. In the DW_OP_xderef_type operation, the size in bytes
     of the data retrieved from the dereferenced address is specified
     by the first operand. This operand is a 1-byte unsigned integral
     constant whose value value is the same as the size of the type
     referenced by the second operand. The second operand is an
     unsigned LEB128 integer that represents the offset of a debugging
     information entry in the current compilation unit that provides
     the type of the data pushed. This entry must be a DW_TAG_base_type
     entry or a DW_TAG_array_type entry with a DW_AT_vector attribute.
--------------------------------------------------------------------

In Section 5.5 Array Type Entries, replace first paragraph of
non-normative text with:

--------------------------------------------------------------------
     [non-normative] Many languages share the concept of an “array,”
     which is a table of components of identical type. Furthermore,
     many architectures contain vector registers which mirror the
     language concept of an array.
--------------------------------------------------------------------

Insert the following paragraph between the first paragraph of
normative text describing DW_TAG_array_type and the second paragraph
dealing with multidimensional ordering.

--------------------------------------------------------------------
     An array type that refers to a hardware vector register, shall be
     denoted with DW_AT_vector. The the width of the register shall be
     specified as an array dimension and the type contained within the
     register must be a DW_TAG_base_type entry.
--------------------------------------------------------------------

In Section 5.13 Subrange Type Entries insert the following paragraph
between the paragraph defining DW_AT_threads_scaled and the one
defining DW_AT_lower_bound and DW_AT_upper_bound.

--------------------------------------------------------------------
     The subrange entry may have a DW_AT_variable_vector_width
     attribute, which is a flag. If present, this attriburte indicates
     that the width of a vector is defined by the hardware
     implementation of the target. The actual width of the vector
     registers can be determined at runtime but is unknown at compile
     time.
--------------------------------------------------------------------

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.dwarfstd.org/pipermail/dwarf-discuss/attachments/20230324/c0ec7c0a/attachment.htm>


More information about the Dwarf-discuss mailing list