[mlir][IR] Generalize `DenseElementsAttr` to custom element types (#179122)

`DenseElementsAttr` supports only a hard-coded list of element types:
`int`, `index`, `float`, `complex`. This commit generalizes the
`DenseElementsAttr` infrastructure: it now supports arbitrary element
types, as long as they implement the new `DenseElementTypeInterface`.

The `DenseElementTypeInterface` has the following helper functions:
- `getDenseElementBitSize`: Query the size of an element in bits. (When
storing an element in memory, each element is padded to a full byte.
This is an existing limitation of the `DenseElementsAttr`; with an
exception for `i1`.)
- `convertToAttribute`: Attribute factory / deserializer. Converts bytes
into an MLIR attribute. The attribute provides the assembly format /
printer for a single element.
- `convertFromAttribute`: Serializer. Converts an MLIR attribute into
bytes.

Note: `convertToAttribute` / `convertFromAttribute` are mainly for
writing test cases. For performance reasons, `DenseElementsAttr` users
should work with raw bytes / elements and avoid any API that
materializes MLIR attributes. However, MLIR attributes typically have
human-readable parsers/printers, making them suitable for lit tests and
debugging.

This PR introduces an additional assembly format for
`DenseElementsAttrs`. There are now two formats. (The existing one is
kept for compatibility reasons.)
- Literal-first (existing): `dense<[1, 2, 3]> : tensor<3xi32>`
- Type-first (new): `dense<tensor<3xi32> : [1 : i32, 2 : i32, 3 : i32]>`

The new syntax is needed to disambiguate between "literal" (e.g., `1`)
and attribute (e.g., `1 : i32`) when parsing the first token. In the
literal-first syntax, we only parse literals. In the type-first syntax,
we only parse attributes.

The existing `int`, `index`, `float`, `complex` types also implement the
`DenseElementTypeInterface`. This allows us to implement
`DenseElementsAttr::get` and `AttributeElementIterator::operator*` in a
generic way.

RFC:
https://discourse.llvm.org/t/rfc-allow-custom-element-types-in-denseelementattr/89656
14 files changed
tree: 723387a26431ec780f268d13d5bf6ec950675ec6
  1. .ci/
  2. .github/
  3. bolt/
  4. clang/
  5. clang-tools-extra/
  6. cmake/
  7. compiler-rt/
  8. cross-project-tests/
  9. flang/
  10. flang-rt/
  11. libc/
  12. libclc/
  13. libcxx/
  14. libcxxabi/
  15. libsycl/
  16. libunwind/
  17. lld/
  18. lldb/
  19. llvm/
  20. llvm-libgcc/
  21. mlir/
  22. offload/
  23. openmp/
  24. orc-rt/
  25. polly/
  26. runtimes/
  27. third-party/
  28. utils/
  29. .clang-format
  30. .clang-format-ignore
  31. .clang-tidy
  32. .git-blame-ignore-revs
  33. .gitattributes
  34. .gitignore
  35. .mailmap
  36. CODE_OF_CONDUCT.md
  37. CONTRIBUTING.md
  38. LICENSE.TXT
  39. pyproject.toml
  40. README.md
  41. SECURITY.md
README.md

The LLVM Compiler Infrastructure

OpenSSF Scorecard OpenSSF Best Practices libc++

Welcome to the LLVM project!

This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.

The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.

C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.

Other components include: the libc++ C++ standard library, the LLD linker, and more.

Getting the Source Code and Building LLVM

Consult the Getting Started with LLVM page for information on building and running LLVM.

For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.

Getting in touch

Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.

The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.