[mlir][tblgen] Generate generic adaptors for Ops
authorMarkus Böck <markus.boeck02@gmail.com>
Sun, 25 Dec 2022 14:07:49 +0000 (15:07 +0100)
committerMarkus Böck <markus.boeck02@gmail.com>
Wed, 11 Jan 2023 13:32:21 +0000 (14:32 +0100)
commitcf6f21751622fcae326d1fe13bc5afd74c4e720f
tree8d2de87a746444a35962708c6a6def7e1ce0d563
parentcce49337aa9fea54e6070c6d179ecfbfe74076bb
[mlir][tblgen] Generate generic adaptors for Ops

This is part of the RFC for a better fold API: https://discourse.llvm.org/t/rfc-a-better-fold-api-using-more-generic-adaptors/67374

This patch implements the generation of generic adaptors through TableGen. These are essentially a generalization of Adaptors, as implemented previously, but instead of indexing into a `mlir::ValueRange`, they may index into any container, regardless of the element type. This allows the use of the convenient getter methods of Adaptors to be reused on ranges that are the result of some kind of mapping functions of an ops operands.
In the case of the fold API in the RFC, this would be `ArrayRef<Attribute>`, which is a mapping of the operands to their possibly-constant values.

Implementation wise, some special care was taken to not cause a compile time regression, nor to break any kind of source compatibility.
For that purpose, the current adaptor class was split into three:
* A generic adaptor base class, within the detail namespace as it is an implementation detail, which implements all APIs independent of the range type used for the operands. This is all the attribute and region related code. Since it is not templated, its implementation does not have to be inline and can be put into the cpp source file
* The actual generic adaptor, which has a template parameter for the range that should be indexed into for retrieving operands. It implements all the getters for operands, as they are dependent on the range type. It publicly inherits from the generic adaptor base class
* A class named as adaptors have been named so far, inheriting from the generic adaptor class with `mlir::ValueRange` as range to index into. It implements the rest of the API, specific to `mlir::ValueRange` adaptors, which have previously been part of the adaptor. This boils down to a constructor from the Op type as well as the verify function.

The last class having the exact same API surface and name as Adaptors did previously leads to full source compatibility.

Differential Revision: https://reviews.llvm.org/D140660
mlir/include/mlir/TableGen/Class.h
mlir/include/mlir/TableGen/Operator.h
mlir/lib/TableGen/Class.cpp
mlir/lib/TableGen/Operator.cpp
mlir/test/mlir-tblgen/op-decl-and-defs.td
mlir/test/mlir-tblgen/op-operand.td
mlir/tools/mlir-tblgen/OpClass.cpp
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
mlir/unittests/IR/AdaptorTest.cpp [new file with mode: 0644]
mlir/unittests/IR/CMakeLists.txt