On Mon, Apr 3, 2023 at 12:42 PM Pedro Alves via Dwarf-discuss < dwarf-discuss@lists.dwarfstd.org> wrote:
> Hi Ben, > > On 2023-03-24 6:19 p.m., Ben Woodard via Dwarf-discuss wrote: > > > 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. > > In light of the recent discussion, I was thinking how it would help if the > proposal was laid out in terms of vector types instead of hardware > registers. > I think the proposed language here is a bit too C/C++ centric. > Please see comments inline below. > > > 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. > > I'd suggest replacing the above with something like this: > > ~~~~~~~~~~~~ > Vector types > > As an extension to C and C++, GCC supports defining vector data types. > DW_AT_GNU_vector is used for languages beyond C/C++ today. > On some targets, operations on these vector types make use of SIMD > vector registers and instructions. > > Vector types are similar to arrays, and you can index and initialize > them similarly, but they have some important differences. For > example: > These statements are not true in general for non C/C++ languages, and DW_TAG_array_type represents a variety of array types across many languages. > - Arrays automatically decay to pointers. Vector types do not. > Array decay is only a C/C++ "feature" as far as I know. - You can pass vector types by value to functions, and likewise > functions can return vector types by value. You can not do either > with C arrays. > Arrays in other languages can be passed and returned by value at the language level (e.g. Ada) and sometimes even at the machine level (e.g. Rust). > - Vector types can be used with a subset of normal C operations: +, -, > *, /, unary minus, ^, |, &, ~, %. For example, addition is defined as > the addition of the corresponding elements of the operands. > The implicit statement here that non-vector arrays cannot be used with any normal operations is also not true in general (e.g. in Fortran 90 A = B + C works). > A debugger that supports expression evaluation will want to be able to > support these vector operations on vector objects too. > Supporting expression evaluation requires very deep knowledge of the semantics of the program's language, to the point where I think saying much beyond "vector types may have different semantics than standard array types" in the DWARF spec isn't worth the effort. > Vector types may appear on function prototypes, so they affect calling > convention. > > To distinguish vector types from regular C arrays, GCC's DWARF > describes the vector types as array with the DW_AT_GNU_vector > attribute, a GNU extension. Clang also supports the GCC vector > language extension, and supports the same DWARF attribute as well. > Vector types have supported by GDB for well over a decade, using said > DWARF extension. This proposal 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 > > Here, I think it would be better to say "A vector type". An object of > vector > type could well have a memory location, for instance. > > > DW_AT_variable_vector_width | Array bound for hardware > > | implementation defined vector register > > | width > > Does GCC have a corresponding GNU extension for this? I don't recall ever > seeing it, and my grepping isn't finding it. > > > -------------------------------------------------------------------- > > > > 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 > > "a hardware vector register" -> "a vector type" > > > denoted with DW_AT_vector. The the width of the register shall be > > Double "The the". > > "width of the register" -> "width of the vector" > > > specified as an array dimension and the type contained within the > > register must be a DW_TAG_base_type entry. > > "register" -> "vector". > > > -------------------------------------------------------------------- > > > > 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 > > "attriburte" -> "attribute" > > > that the width of a vector is defined by the hardware > > implementation of the target. > > I think that saying: > > that the width of a vector may be deduced based on knowledge of the > ABI. > > is more in line what is typically said in the spec. > > Pedro Alves > > -- > Dwarf-discuss mailing list > Dwarf-discuss@lists.dwarfstd.org > https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss - Kyle
-- Dwarf-discuss mailing list Dwarf-discuss@lists.dwarfstd.org https://lists.dwarfstd.org/mailman/listinfo/dwarf-discuss