Commit Graph

1367 Commits

Author SHA1 Message Date
gysit 51fdd802c7 [mlir][OpDSL] Add type function attributes.
Previously, OpDSL operation used hardcoded type conversion operations (cast or cast_unsigned). Supporting signed and unsigned casts thus meant implementing two different operations. Type function attributes allow us to define a single operation that has a cast type function attribute which at operation instantiation time may be set to cast or cast_unsigned. We may for example, defina a matmul operation with a cast argument:

```
@linalg_structured_op
def matmul(A=TensorDef(T1, S.M, S.K), B=TensorDef(T2, S.K, S.N), C=TensorDef(U, S.M, S.N, output=True),
    cast=TypeFnAttrDef(default=TypeFn.cast)):
  C[D.m, D.n] += cast(U, A[D.m, D.k]) * cast(U, B[D.k, D.n])
```

When instantiating the operation the attribute may be set to the desired cast function:

```
linalg.matmul(lhs, rhs, outs=[out], cast=TypeFn.cast_unsigned)
```

The revsion introduces a enum in the Linalg dialect that maps one-by-one to the type functions defined by OpDSL.

Reviewed By: aartbik

Differential Revision: https://reviews.llvm.org/D119718
2022-02-25 08:25:23 +00:00
Thomas Raoux b1357fe618 [mlir][memref] Add transformation to do loop multi-buffering
This transformation is useful to break dependency between consecutive loop
iterations by increasing the size of a temporary buffer. This is usually
combined with heavy software pipelining.

Differential Revision: https://reviews.llvm.org/D119406
2022-02-24 09:41:21 -08:00
Matthias Springer d2dacde5d8 [mlir][bufferize][NFC] Rename `comprehensive-function-bufferize` to `one-shot-bufferize`
The related functionality is moved over to the bufferization dialect. Test cases are cleaned up a bit.

Differential Revision: https://reviews.llvm.org/D120191
2022-02-22 17:19:20 +09:00
Shraiysh Vaishay 5bec1ea7a7 [mlir] Added oilist primitive
This patch attempts to add the `oilist` primitive proposed in the [[ https://llvm.discourse.group/t/rfc-extending-declarative-assembly-format-to-support-order-independent-variadic-segments/4388 | RFC: Extending Declarative Assembly Format to support order-independent variadic segments ]].

This element supports optional order-independent variadic segments for operations. This will allow OpenACC and OpenMP Dialects to have similar and relaxed requirements while encouraging the use of Declarative Assembly Format and avoiding code duplication.

An oilist element parses grammar of the form:
```
clause-list := clause clause-list | empty
clause := `keyword` clause1 | `otherKeyword` clause2
clause1 := <assembly-format element>
clause2 := <assembly-format element>
```

AssemblyFormat specification:
```
let assemblyFormat = [{
  oilist( `keyword` clause1
        | `otherkeyword` clause2
        ...
        )
}];
```

Example:
```
oilist( `private` `(` $arg0 `:` type($arg0) `)`
      | `nowait`
      | `reduction` custom<ReductionClause>($arg1, type($arg1)))

oilist( `private` `=` $arg0 `:` type($arg0)
      | `reduction` `=` $arg1 `:` type($arg1)
      | `firstprivate` `=` $arg3 `:` type($arg2))
```

Reviewed By: Mogball, rriddle

Differential Revision: https://reviews.llvm.org/D115215
2022-02-17 11:10:24 +05:30
Lei Zhang e027c00821 [mlir][tensor] Add a pattern to split tensor.pad ops
This commit adds a pattern to wrap a tensor.pad op with
an scf.if op to separate the cases where we don't need padding
(all pad sizes are actually zeros) and where we indeed need
padding.

This pattern is meant to handle padding inside tiled loops.
Under such cases the padding sizes typically depend on the
loop induction variables. Splitting them would allow treating
perfect tiles and edge tiles separately.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D117018
2022-02-16 13:43:57 -05:00
Mogball 26a61db93f [mlir][ods] NFC fix compilation error on clang-8 2022-02-15 19:41:16 +00:00
Mogball 761bc83af4 [mlir][ods] Default-valued parameters in attribute or type defs
Optional parameters with `defaultValue` set will be populated with that value if they aren't encountered during parsing. Moreover, parameters equal to their default values are elided when printing.

Depends on D118210

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D118544
2022-02-15 19:02:11 +00:00
gysit 348bfc8e50 [mlir][linalg] Add attributes to region builder (NFC).
Adapt the region builder signature to hand in the attributes of the created ops. The revision is a preparation step the support named ops that need access to the operation attributes during op creation.

Depends On D119692

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D119693
2022-02-14 13:14:14 +00:00
gysit d50571ab07 [mlir][OpDSL] Add default value to index attributes.
Index attributes had no default value, which means the attribute values had to be set on the operation. This revision adds a default parameter to `IndexAttrDef`. After the change, every index attribute has to define a default value. For example, we may define the following strides attribute:
```

```
When using the operation the default stride is used if the strides attribute is not set. The mechanism is implemented using `DefaultValuedAttr`.

Additionally, the revision uses the naming index attribute instead of attribute more consistently, which is a preparation for follow up revisions that will introduce function attributes.

Depends On D119125

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D119126
2022-02-14 12:14:12 +00:00
gysit a3655de2c8 [mlir][OpDSL] Add support for basic rank polymorphism.
Previously, OpDSL did not support rank polymorphism, which required a separate implementation of linalg.fill. This revision extends OpDSL to support rank polymorphism for a limited class of operations that access only scalars and tensors of rank zero. At operation instantiation time, it scales these scalar computations to multi-dimensional pointwise computations by replacing the empty indexing maps with identity index maps. The revision does not change the DSL itself, instead it adapts the Python emitter and the YAML generator to generate different indexing maps and and iterators depending on the rank of the first output.

Additionally, the revision introduces a `linalg.fill_tensor` operation that in a future revision shall replace the current handwritten `linalg.fill` operation. `linalg.fill_tensor` is thus only temporarily available and will be renamed to `linalg.fill`.

Reviewed By: nicolasvasilache, stellaraccident

Differential Revision: https://reviews.llvm.org/D119003
2022-02-11 08:27:49 +00:00
Mogball 740e832644 [mlir][ods] Attribute and type formats: support whitespaces
Supports whitespace elements: ` ` and `\\n` as well as the "empty" whitespace `` that removes an otherwise printed space.

Depends on D118208

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D118210
2022-02-08 23:27:36 +00:00
Mogball 72619d101f [mlir][ods] NFC fix tblgen crash with empty assembly format 2022-02-08 21:13:58 +00:00
Mogball 07486395d2 [mlir][ods] Optional Attribute or Type Parameters
Implements optional attribute or type parameters, including support for such parameters in the assembly format `struct` directive. Also implements optional groups.

Depends on D117971

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D118208
2022-02-08 20:09:44 +00:00
Mahesh Ravishankar 2abd7f13bc [mlir][Linalg] NFC: Combine elementwise fusion test passes.
There are a few different test passes that check elementwise fusion in
Linalg. Consolidate them to a single pass controlled by different pass
options (in keeping with how `TestLinalgTransforms` exists).
2022-02-08 18:08:37 +00:00
Alex Zinenko 3df6cadec4 [mlir] ODS: require DefaultValuedAttr to be const-buildable
ODS provides a mechanism for defalut-valued attributes based on a wrapper
TableGen class that is recognized by mlir-tblgen. Such attributes, if not set
on the operaiton, can be construted on-the-fly in their getter given a constant
value. In order for this construction to work, the attribute specificaiton in
ODS must set the constBuilderCall field correctly. This has not been verified,
which could lead to invalid C++ code being generated by mlir-tblgen.

Closes #53588.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D119113
2022-02-08 09:31:09 +01:00
River Riddle 2418cd92c0 [mlir] Update uses of `parser`/`printer` ODS op field to `hasCustomAssemblyFormat`
The parser/printer fields are deprecated and in the process of being removed.
2022-02-07 19:03:58 -08:00
River Riddle d7f0083dca [mlir:ODS] Deprecate Op parser/printer fields in favor of a new hasCustomAssemblyFormat field
Currently if an operation wants a C++ implemented parser/printer, it specifies inline
code blocks. This is quite problematic for various reasons, e.g. it requires defining
C++ inside of Tablegen which is discouraged when possible, but mainly because
nearly all usages simply forward to static functions (e.g. `static void parseSomeOp(...)`)
with users devising their own standards for how these are defined.

This commit adds support for a `hasCustomAssemblyFormat` bit field that specifies if
a C++ parser/printer is needed, and when set to 1 declares the parse/print methods for
operations to override. For migration purposes, the existing behavior is untouched. Upstream
usages will be replaced in a followup to keep this patch focused on the new implementation.

Differential Revision: https://reviews.llvm.org/D119054
2022-02-07 19:03:57 -08:00
Mahesh Ravishankar 7568f7101f Revert "[mlir][Linalg] NFC: Combine elementwise fusion test passes."
This reverts commit d730336411.
2022-02-07 22:51:29 +00:00
Mahesh Ravishankar d730336411 [mlir][Linalg] NFC: Combine elementwise fusion test passes.
There are a few different test passes that check elementwise fusion in
Linalg. Consolidate them to a single pass controlled by different pass
options (in keeping with how `TestLinalgTransforms` exists).
2022-02-07 22:46:57 +00:00
Markus Böck 296e03fc64 [mlir][NFC] Fully qualify call to `mlir::success` in auto generated C++ 2022-02-05 00:40:04 +01:00
Markus Böck 7b196f1b09 [mlir][Rewrite] Add support for using an operation with no results as location
Prior to this patch, using an operation without any results as the location would result in the generation of invalid C++ code. It'd try to format using the result values, which would would end up being an empty string for an operation without any.
This patch fixes that issue by instead using getValueAndRangeUse which handles both ranges as well as the case for an op without any results.

Differential Revision: https://reviews.llvm.org/D118885
2022-02-03 15:08:09 +01:00
Markus Böck 7a9e3ef77a [mlir] Fix crash in RewriterGen when a `TypeConstraint` is not given an argument
The code assumes that a TypeConstraint in the additional constraints list specifies precisely one argument.
If the user were to not specify any, it'd result in a crash. If given more than one, the additional ones were ignored.

This patch fixes the crash and disallows user errors by adding a check that a single argument is supplied to the TypeConstraint

Differential Revision: https://reviews.llvm.org/D118763
2022-02-03 09:08:27 +01:00
River Riddle 42e5f1d97b [mlir] Refactor how additional verification is specified in ODS
Currently if an operation requires additional verification, it specifies an inline
code block (`let verifier = "blah"`). This is quite problematic for various reasons, e.g.
it requires defining C++ inside of Tablegen which is discouraged when possible, but mainly because
nearly all usages simply forward to a static function `static LogicalResult verify(SomeOp op)`.
This commit adds support for a `hasVerifier` bit field that specifies if an additional verifier
is needed, and when set to `1` declares a `LogicalResult verify()` method for operations to
override. For migration purposes, the existing behavior is untouched. Upstream usages will
be replaced in a followup to keep this patch focused on the hasVerifier implementation.

One main user facing change is that what was one `MyOp::verify` is now `MyOp::verifyInvariants`.
This better matches the name this method is called everywhere else, and also frees up `verify` for
the user defined additional verification. The `verify` function when generated now (for additional
verification) is private to the operation class, which should also help avoid accidental usages after
this switch.

Differential Revision: https://reviews.llvm.org/D118742
2022-02-02 13:34:28 -08:00
Markus Böck 513ba61ca1 [mlir] Fully qualify generated C++ code in RewriterGen.cpp
By fully qualifying the use of any types and functions from the mlir namespace, users are not required to add using namespace mlir; into the C++ file including the Tablegen output.

Differential Revision: https://reviews.llvm.org/D118767
2022-02-02 11:57:57 +01:00
Mogball 42f87a0354 [mlir][ods] NFC Fix ASAN error in FormatParser
Some FormatElement subclasses contain `std::vector`. Since these use
BumpPtrAllocator, they need to be converted to trailing objects.
However, this is not a trivial fix so I will leave it as a FIXME and use
a workaround.
2022-02-02 04:29:57 +00:00
Benjamin Kramer a0ea73394f [mlir] Attempt working around a GCC 5 bug
It doesn't like implicit `this` in generic lambdas.
2022-02-01 11:58:27 +01:00
Mogball 0bc0ad86e2 [mlir][ods] Unify Attr/TypeDef and Operation Format Parsing
Part 2 of 3 of unifying the assembly formats of attributes/types and operations.The last patch that introduced attribute/type formats (D111594) factored out the format lexer entirely. This patch factors out most of the format parsers such that the attribute/type and op parsers only need to implement handling for specific elements.

Certain things could be factored better (element verification, 'seen' variables) but the primary goal of factoring is so that features can be used across both assembly formats.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D117971
2022-02-01 07:28:37 +00:00
Mehdi Amini 446425f898 Apply clang-tidy fixes for llvm-include-order in AttrOrTypeFormatGen.cpp (NFC) 2022-01-30 19:49:23 +00:00
Stella Stamenova c0861fcbb9 [mlir] Only build mlir-cpu-runner when the native arch is targeted
mlir-cpu-runner has a dependency on ExecutionEngine which is only built for the native arch. So currently mlir-cpu-runner does not link correctly when the native arch is not targeted.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D118422
2022-01-28 10:09:09 -08:00
River Riddle 7d0426dd95 [mlir] Move ComposeSubView+ExpandOps from Standard to MemRef
These transformations already operate on memref operations (as part of
splitting up the standard dialect). Now that the operations have moved,
it's time for these transformations to move as well.

Differential Revision: https://reviews.llvm.org/D118285
2022-01-26 23:11:02 -08:00
River Riddle 6842ec42f6 [mlir][NFC] Add a using for llvm::SMLoc/llvm::SMRange to LLVM.h
These are used pervasively during parsing.

Differential Revision: https://reviews.llvm.org/D118291
2022-01-26 21:37:23 -08:00
River Riddle d10d49dce4 [mlir][NFC] Add a using for llvm::BitVector to LLVM.h
BitVector is becoming widespread enough that we should add a proper using.

Differential Revision: https://reviews.llvm.org/D118290
2022-01-26 21:37:23 -08:00
Jeremy Furtek 33185e66f2 [mlir] Add ODS support for enum attributes with grouped bit cases
This diff modifies the tablegen specification and code generation for
BitEnumAttr attributes in MLIR Operation Definition Specification (ODS) files.
Specifically:

- there is a new tablegen class for "none" values (i.e. no bits set)
- single-bit enum cases are specified via bit index (i.e. [0, 31]) instead of
  the resulting enum integer value
- there is a new tablegen class to represent a "grouped" bitwise OR of other
  enum values

This diff is intended as an initial step towards improving "fastmath"
optimization support in MLIR, to allow more precise control of whether certain
floating point optimizations are applied in MLIR passes. "Fast" math options
for floating point MLIR operations would (following subsequent RFC and
discussion) be specified by using the improved enum bit support in this diff.
For example, a "fast" enum value would act as an alias for a group of other
cases (e.g. finite-math-only, no-signed-zeros, etc.), in a way that is similar
to support in C/C++ compilers (clang, gcc).

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D117029
2022-01-26 21:01:01 +00:00
serge-sans-paille 75e164f61d [llvm] Cleanup header dependencies in ADT and Support
The cleanup was manual, but assisted by "include-what-you-use". It consists in

1. Removing unused forward declaration. No impact expected.
2. Removing unused headers in .cpp files. No impact expected.
3. Removing unused headers in .h files. This removes implicit dependencies and
   is generally considered a good thing, but this may break downstream builds.
   I've updated llvm, clang, lld, lldb and mlir deps, and included a list of the
   modification in the second part of the commit.
4. Replacing header inclusion by forward declaration. This has the same impact
   as 3.

Notable changes:

- llvm/Support/TargetParser.h no longer includes llvm/Support/AArch64TargetParser.h nor llvm/Support/ARMTargetParser.h
- llvm/Support/TypeSize.h no longer includes llvm/Support/WithColor.h
- llvm/Support/YAMLTraits.h no longer includes llvm/Support/Regex.h
- llvm/ADT/SmallVector.h no longer includes llvm/Support/MemAlloc.h nor llvm/Support/ErrorHandling.h

You may need to add some of these headers in your compilation units, if needs be.

As an hint to the impact of the cleanup, running

clang++ -E  -Iinclude -I../llvm/include ../llvm/lib/Support/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l

before: 8000919 lines
after:  7917500 lines

Reduced dependencies also helps incremental rebuilds and is more ccache
friendly, something not shown by the above metric :-)

Discourse thread on the topic: https://llvm.discourse.group/t/include-what-you-use-include-cleanup/5831
2022-01-21 13:54:49 +01:00
River Riddle 755dc07d69 [mlir:Analysis] Move the LoopAnalysis library to Dialect/Affine/Analysis
The current state of the top level Analysis/ directory is that it contains two libraries;
a generic Analysis library (free from dialect dependencies), and a LoopAnalysis library
that contains various analysis utilities that originated from Affine loop transformations.
This commit moves the LoopAnalysis to the more appropriate home of `Dialect/Affine/Analysis/`,
given the use and intention of the majority of the code within it. After the move, if there
are generic utilities that would fit better in the top-level Analysis/ directory, we can move
them.

Differential Revision: https://reviews.llvm.org/D117351
2022-01-18 10:28:22 -08:00
Mogball aae5125550 [mlir] Replace StrEnumAttr -> EnumAttr in core dialects
Removes uses of `StrEnumAttr` in core dialects

Reviewed By: mehdi_amini, rriddle

Differential Revision: https://reviews.llvm.org/D117514
2022-01-18 17:15:00 +00:00
Nicolas Vasilache cc0d208805 [mlir][Linalg] Drop deprecated convolution vectorization patterns
Differential revision: https://reviews.llvm.org/D117326
2022-01-18 09:26:50 +00:00
Mehdi Amini 78fdbdbf26 Use reference for large object passed by value at the moment in MLIR TableGen (NFC)
Also make the ODS Operator class have const iterator, and use const
references for existing API taking Operator by reference.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D117516
2022-01-18 06:48:33 +00:00
Mehdi Amini c8e047f5e1 Enable useDefault{Type/Attribute}PrinterParser by default in ODS Dialect definition
The majority of dialects reimplement the same boilerplate over and over,
switching the default makes it for better discoverability and make it simpler
to implement new dialects.

Differential Revision: https://reviews.llvm.org/D117524
2022-01-18 06:36:34 +00:00
Nicolas Vasilache f40a579bea Revert "[mlir][Linalg] NFC - Drop vectorization reliance on ConvolutionOpInterface"
This reverts commit c8f5735301.

The integration tests are broken.
2022-01-17 19:38:07 +00:00
Nicolas Vasilache c8f5735301 [mlir][Linalg] NFC - Drop vectorization reliance on ConvolutionOpInterface
Differential Revision: https://reviews.llvm.org/D117323
2022-01-17 17:01:36 +00:00
Eugene Zhulenev 69bc334be5 [mlir] Remove getNumberOfExecutions from RegionBranchOpInterface
`getNumRegionInvocations` was originally added for the async reference counting, but turned out to be not useful, and currently is not used anywhere (couldn't find any uses in public github repos). Removing dead code.

Reviewed By: Mogball, mehdi_amini

Differential Revision: https://reviews.llvm.org/D117347
2022-01-14 13:15:27 -08:00
Rahul Joshi 8067ced144 [MLIR] Introduce generic visitors.
- Generic visitors invoke operation callbacks before/in-between/after visiting the regions
  attached to an operation and use a `WalkStage` to indicate which regions have been
  visited.
- This can be useful for cases where we need to visit the operation in between visiting
  regions attached to the operation.

Differential Revision: https://reviews.llvm.org/D116230
2022-01-14 09:15:27 -08:00
Adrian Kuegel cc79d603c9 [mlir] Use .empty() instead of checking size() == 0.
Based on a finding by ClangTidy readability-container-size-empty check.
2022-01-14 11:58:52 +01:00
Markus Böck 52b8fe9b6e [mlir] Fix attaching side effects on `FlatSymbolRefAttr`
The names of the generated attribute getters for ops changed some time ago. The method created from the attribute name returns the return type and an additional method of the same name with Attr as suffix is generated which returns the actual attribute as its storage type.

The code generating effects however was using the methods without the Attr suffix, which is a problem in the case of FlatSymbolRefAttr as it has a return type of llvm::StringRef. This would lead to compilation errors as the constructor of SideEffects::EffectInstance expects a SymbolRefAttr in this case.

This patch simply fixes the generated effects code to use the Attr suffixed getter to get the actual storage type of the attribute.

Differential Revision: https://reviews.llvm.org/D117194
2022-01-13 19:57:01 +01:00
River Riddle a60e83fe7c [mlir][Interfaces] Add a extraSharedClassDeclaration field
This field allows for defining a code block that is placed in both the interface
and trait declarations. This is very useful when defining a set of utilities to
expose on both the Interface class and the derived attribute/operation/type.

In non-static methods, `$_attr`/`$_op`/`$_type` (depending on the type of
interface) may be used to refer to an instance of the IR entity. In the interface
declaration, this is an instance of the interface class. In the trait declaration,
this is an instance of the concrete entity class (e.g. `IntegerAttr`, `FuncOp`, etc.).

Differential Revision: https://reviews.llvm.org/D116961
2022-01-12 14:12:08 -08:00
MaheshRavishankar e7cb716ef9 [mlir][Linalg] Pattern to fuse pad operation with elementwise operations.
Most convolution operations need explicit padding of the input to
ensure all accesses are inbounds. In such cases, having a pad
operation can be a significant overhead. One way to reduce that
overhead is to try to fuse the pad operation with the producer of its
source.

A sequence

```
linalg.generic -> linalg.pad_tensor
```

can be replaced with

```
linalg.fill -> tensor.extract_slice -> linalg.generic ->
tensor.insert_slice.
```

if the `linalg.generic` has all parallel iterator types.

Differential Revision: https://reviews.llvm.org/D116418
2022-01-11 13:37:25 -08:00
Mehdi Amini 63f0c00d38 Add a `qualified` directive to the Op, Attribute, and Type declarative assembly format
This patch introduces a new directive that allow to parse/print attributes and types fully
qualified.
This is a follow-up to ee0908703d which introduces the eliding of the `!dialect.mnemonic` by default and allows to force to fully qualify each type/attribute
individually.

Differential Revision: https://reviews.llvm.org/D116905
2022-01-11 01:30:19 +00:00
gysit cf05668c17 [mlir][OpDSL] Rename `PrimFn` to `ArithFn`.
The revision renames `PrimFn` to `ArithFn`. The name resembles the newly introduced arith dialect that implements most of the arithmetic functions. An exception are log/exp that are part of the math dialect.

Depends On D115239

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D115240
2022-01-07 12:38:03 +00:00
gysit 15757ea80a [mlir][OpDSL] Add `TypeFn` class.
This revision introduces a the `TypeFn` class that similar to the `PrimFn` class contains an extensible set of type conversion functions. Having the same mechanism for both type conversion functions and arithmetic functions improves code consistency. Additionally, having an explicit function class and function name is a prerequisite to specify a conversion or arithmetic function via attribute. In a follow up commits, we will introduce function attributes to make OpDSL operations more generic. In particular, the goal is to handle signed and unsigned computation in one operations. Today, there is a linalg.matmul and a linalg.matmul_unsigned.

The commit implements the following changes:
- Introduce the class of type conversion functions `TypeFn`
- Replace the hardwired cast and cast_unsigned ops by the `TypeFn` counterparts
- Adapt the python and C++ code generation paths to support the new cast operations

Example:
```
cast(U, A[D.m, D.k])
```
changes to
```
TypeFn.cast(U, A[D.m, D.k])
```

Depends On D115237

Reviewed By: stellaraccident

Differential Revision: https://reviews.llvm.org/D115239
2022-01-07 12:26:47 +00:00
Mogball b0774e5f50 [mlir][ods] ODS ops get an `extraClassDefinition`
Extra definitions are placed in the generated source file for each op class. The substitution `$cppClass` is replaced by the op's C++ class name.

This is useful when declaring but not defining methods in TableGen base classes:

```
class BaseOp<string mnemonic>
    : Op<MyDialect, mnemonic, [DeclareOpInterfaceMethods<SomeInterface>] {
  let extraClassDeclaration = [{
    // ZOp is declared at at the bottom of the file and is incomplete here
    ZOp getParent();
  }];
  let extraClassDefinition = [{
    int $cppClass::someInterfaceMethod() {
      return someUtilityFunction(*this);
    }
    ZOp $cppClass::getParent() {
      return dyn_cast<ZOp>(this->getParentOp());
    }
  }];
}
```

Certain things may prevent defining these functions inline, in the declaration. In this example, `ZOp` in the same dialect is incomplete at the function declaration because ops classes are declared in alphabetical order. Alternatively, functions may be too big to be desired as inlined, or they may require dependencies that create cyclic includes, or they may be calling a templated utility function that one may not want to expose in a header. If the functions are not inlined, then inheriting from the base class N times means that each function will need to be defined N times. With `extraClassDefinitions`, they only need to be defined once.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D115783
2022-01-06 01:43:26 +00:00
Mehdi Amini 564bcf9d02 Align adaptor's generator accessors for attribute on the Op class
Each attribute has two accessor: one suffixed with `Attr` which returns the attribute itself
and one without the suffix which unwrap the attribute.
For example for a StringAttr attribute with a field named `kind`, we'll generate:

StringAttr getKindAttr();
StringRef getKind();

Differential Revision: https://reviews.llvm.org/D116466
2022-01-05 05:42:15 +00:00
Jacques Pienaar 05594de2d7 [mlir][ods] Handle DeclareOpInterfaceMethods in formatgen
Previously it would not consider ops with
DeclareOpInterfaceMethods<InferTypeOpInterface> as having the
InferTypeOpInterface interfaces added. The OpInterface nested inside
DeclareOpInterfaceMethods is not retained so that one could query it, so
check for the the C++ class directly (a bit raw/low level - will be
addressed in follow up).

Differential Revision: https://reviews.llvm.org/D116572
2022-01-04 08:28:59 -08:00
Mehdi Amini 1461bd13c9 Revert "Define a `cppAccessorType` to const-ref in APFloatParameter and update ODS emitter to use it for verifier signatures"
This reverts commit 89af17c0c7.

This broke the gcc5 build.
2022-01-03 06:32:50 +00:00
Mehdi Amini 564619b786 Use cast<> instead of dyn_cast<> when we don't check the result (NFC) 2022-01-03 06:06:36 +00:00
Mehdi Amini 89af17c0c7 Define a `cppAccessorType` to const-ref in APFloatParameter and update ODS emitter to use it for verifier signatures
This reduce an unnecessary amount of copy of non-trivial objects, like
APFloat.

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D116505
2022-01-03 04:57:11 +00:00
Mehdi Amini 5a1f6077ec Apply clang-tidy fixes for readability-container-size-empty for MLIR (NFC)
Reviewed By: rriddle, Mogball

Differential Revision: https://reviews.llvm.org/D116252
2022-01-02 01:56:38 +00:00
Mehdi Amini 1fc096af1e Apply clang-tidy fixes for performance-unnecessary-value-param to MLIR (NFC)
Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D116250
2022-01-02 01:45:18 +00:00
Mehdi Amini 89de9cc8a7 Apply clang-tidy fixes for performance-for-range-copy to MLIR (NFC)
Differential Revision: https://reviews.llvm.org/D116248
2022-01-02 01:13:42 +00:00
Kazu Hirata 63846a634d [mlir] Remove unused "using" (NFC)
Identified by misc-unused-using-decls.
2022-01-01 09:14:19 -08:00
Markus Böck eb6b2efe4e [mlir][NFC] Fully qualify use of SmallVector in generated C++ code of mlir-tblgen 2022-01-01 14:52:32 +01:00
Mehdi Amini a9f13f8065 Fix a few unitialized class members in MLIR (NFC)
Flagged by Coverity.
2022-01-01 01:40:36 +00:00
Markus Böck a9e8b1ee7f [mlir] Fully qualify default types used in parser code 2021-12-24 22:25:50 +01:00
Mehdi Amini 94a47dfde2 Revert "Fix warning: "unused variable 'attrClass'" (NFC)"
This reverts commit 724e6861b3.
This broke the build.
2021-12-23 03:59:25 +00:00
Mehdi Amini 724e6861b3 Fix warning: "unused variable 'attrClass'" (NFC) 2021-12-23 03:55:47 +00:00
Mehdi Amini e5639b3fa4 Fix more clang-tidy cleanups in mlir/ (NFC) 2021-12-22 20:53:11 +00:00
Mogball 00e4354558 [mlir][ods] FIx incorrect comments in PassGen (NFC)
And incorrect command option description for `-gen-pass-decls`.
2021-12-20 21:14:20 +00:00
Mehdi Amini 02b6fb218e Fix clang-tidy issues in mlir/ (NFC)
Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D115956
2021-12-20 20:25:01 +00:00
Mogball 1aa0b84fa4 [mlir][ods] Fix OpFormatGen calling inferReturnTypes before region/segment resolution
The generated parser for ops with type inference calls `inferReturnTypes` before region resolution and segment attribute resolution, i.e. regions and the segment attributes are not passed to the `inferReturnTypes` even though it may need that information.

In particular, an op that has sized operand segments which queries those operands in its `inferReturnTypes` function will crash because the segment attributes hadn't been added yet.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D115782
2021-12-16 19:04:50 +00:00
River Riddle 11d26bd143 [mlir][PDLL] Add an initial frontend for PDLL
This is a new pattern rewrite frontend designed from the ground
up to support MLIR constructs, and to target PDL. This frontend
language was proposed in https://llvm.discourse.group/t/rfc-pdll-a-new-declarative-rewrite-frontend-for-mlir/4798

This commit starts sketching out the base structure of the
frontend, and is intended to be a minimal starting point for
building up the language. It essentially contains support for
defining a pattern, variables, and erasing an operation. The
features mentioned in the proposal RFC (including IDE support)
will be added incrementally in followup commits.

I intend to upstream the documentation for the language in a
followup when a bit more of the pieces have been landed.

Differential Revision: https://reviews.llvm.org/D115093
2021-12-16 02:08:12 +00:00
Mogball 843534db3c [mlir][ods] Fix OpDefinitionsGen infer return types builder with regions
Despite handling regions and inferred return types, the builder was never generated for ops with both InferReturnTypeOpInterface and regions.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D115525
2021-12-13 15:11:35 +00:00
Mogball e40624ae60 [mlir][ods] Fix OpFormatGen sometimes not calling inferReturnTypes
Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D115522
2021-12-10 19:35:56 +00:00
Mehdi Amini be0a7e9f27 Adjust "end namespace" comment in MLIR to match new agree'd coding style
See D115115 and this mailing list discussion:
https://lists.llvm.org/pipermail/llvm-dev/2021-December/154199.html

Differential Revision: https://reviews.llvm.org/D115309
2021-12-08 06:05:26 +00:00
Mehdi Amini ee0908703d Change the printing/parsing behavior for Attributes used in declarative assembly format
The new form of printing attribute in the declarative assembly is eliding the `#dialect.mnemonic` prefix to only keep the `<....>` part.

Differential Revision: https://reviews.llvm.org/D113873
2021-12-08 02:02:37 +00:00
Matthias Springer 8a232632c5 [mlir][linalg][bufferize] Add FuncOp bufferization pass
This passes bufferizes FuncOp bodies, but not FuncOp boundaries.

Differential Revision: https://reviews.llvm.org/D114671
2021-12-07 21:44:26 +09:00
Mehdi Amini 48fb79effb Improve error message when declarativeAssembly contains invalid literals
Differential Revision: https://reviews.llvm.org/D115085
2021-12-04 00:27:32 +00:00
Mogball 75dfeef9ad [mlir][ods] fix defgen on empty files 2021-12-02 21:25:59 +00:00
Jacques Pienaar 86eb57b728 [mlir][drr] Simple heuristic to reduce chance of accidental nullptr dereference
When an attribute is optional & is given an additional constraint in
rewrite pattern that could lead to dereferencing null Attribute. Avoid
cases where the constraints checks attribute but has no check if null.

This should be improved to be more uniformly guarded.
2021-12-01 20:45:08 -08:00
Mogball ecaad4a876 [mlir][ods][nfc] fix gcc-5 build 2021-12-01 18:34:59 +00:00
Mogball ca6bd9cd43 [mlir][ods] AttrOrTypeGen uses Class
AttrOrType def generator uses `Class` code gen helper,
instead of naked raw_ostream.

Depends on D113714 and D114807

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D113715
2021-12-01 16:53:23 +00:00
Jacques Pienaar 62fea88bc5 [mlir] Update accessors prefixed form (NFC) 2021-11-30 19:42:37 -08:00
Lei Zhang cb395f66ac [mlir][spirv] Change the return type for {Min|Max}VersionBase
For synthesizing an op's implementation of the generated interface
from {Min|Max}Version, we need to define an `initializer` and
`mergeAction`. The `initializer` specifies the initial version,
and `mergeAction` specifies how version specifications from
different parts of the op should be merged to generate a final
version requirements.

Previously we use the specified version enum as the type for both
the initializer and thus the final return type. This means we need
to perform `static_cast` over some hopefully not used number (`~0u`)
as the initializer. This is quite opaque and sort of not guaranteed
to work. Also, there are ops that have an enum attribute where some
values declare version requirements (e.g., enumerant `B` requires
v1.1+) but some not (e.g., enumerant `A` requires nothing). Then a
concrete op instance with `A` will still declare it implements the
version interface (because interface implementation is static for
an op) but actually theirs no requirements for version.

So this commit changes to use an more explicit `llvm::Optional`
to wrap around the returned version enum.  This should make it
more clear.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D108312
2021-11-24 17:33:01 -05:00
Markus Böck 0a8a5902a6 [mlir] Fully qualify default generated type/attribute printer and parser
This patch makes it possible to use the newly added useDefaultAttributePrinterParser and useDefaultTypePrinterParser dialect options without any using namespace declarations. Two things had to be done to make this possible:

* Fully qualify any type usages or functions from the mlir namespace in the generated C++ code
* Makes sure to emit the printers and parsers inside the same namespace as the Dialect

Differential Revision: https://reviews.llvm.org/D114168
2021-11-18 20:24:00 +01:00
Michal Terepeta 54c9984207 [mlir][Python] Fix generation of accessors for Optional
Previously, in case there was only one `Optional` operand/result within
the list, we would always return `None` from the accessor, e.g., for a
single optional result we would generate:

```
return self.operation.results[0] if len(self.operation.results) > 1 else None
```

But what we really want is to return `None` only if the length of
`results` is smaller than the total number of element groups (i.e.,
the optional operand/result is in fact missing).

This commit also renames a few local variables in the generator to make
the distinction between `isVariadic()` and `isVariableLength()` a bit
more clear.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D113855
2021-11-18 09:42:57 +01:00
River Riddle 0c7890c844 [mlir] Convert NamedAttribute to be a class
NamedAttribute is currently represented as an std::pair, but this
creates an extremely clunky .first/.second API. This commit
converts it to a class, with better accessors (getName/getValue)
and also opens the door for more convenient API in the future.

Differential Revision: https://reviews.llvm.org/D113956
2021-11-18 05:39:29 +00:00
River Riddle edc6c0ecb9 [mlir] Refactor AbstractOperation and OperationName
The current implementation is quite clunky; OperationName stores either an Identifier
or an AbstractOperation that corresponds to an operation. This has several problems:

* OperationNames created before and after an operation are registered are different
* Accessing the identifier name/dialect/etc. from an OperationName are overly branchy
  - they need to dyn_cast a PointerUnion to check the state

This commit refactors this such that we create a single information struct for every
operation name, even operations that aren't registered yet. When an OperationName is
created for an unregistered operation, we only populate the name field. When the
operation is registered, we populate the remaining fields. With this we now have two
new classes: OperationName and RegisteredOperationName. These both point to the
same underlying operation information struct, but only RegisteredOperationName can
assume that the operation is actually registered. This leads to a much cleaner API, and
we can also move some AbstractOperation functionality directly to OperationName.

Differential Revision: https://reviews.llvm.org/D114049
2021-11-17 22:29:57 +00:00
River Riddle 195730a650 [mlir][NFC] Replace references to Identifier with StringAttr
This is part of the replacement of Identifier with StringAttr.

Differential Revision: https://reviews.llvm.org/D113953
2021-11-16 17:36:26 +00:00
Mogball 0b158c6c7d [mlir][ods] Fix unused uniqued attr constraint
Derived attributes' constraints are no longer uniqued - derived
attributes' verifiers are not automatically generated.
2021-11-14 23:23:14 +00:00
Mogball da4d716ef9 [mlir][ods] Fix incorrect name in comment (NFC) 2021-11-13 20:06:48 +00:00
Mogball 2696a9529e [mlir][ods] Cleanup of Class Codegen helper
Depends on D113331

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D113714
2021-11-12 21:22:01 +00:00
Mogball 0ecd72ea00 [mlir][ods] Fix DenseSet ambiguous reference 2021-11-12 03:12:36 +00:00
Mogball e1d6f29a1e [mlir][ods] Escape attribute summaries 2021-11-12 01:39:15 +00:00
Mogball b8186b313c [mlir][ods] Unique attribute, successor, region constraints
With `-Os` turned on, results in 2-5% binary size reduction
(depends on the original binary). Without it, the binary size
is essentially unchanged.

Depends on D113128

Differential Revision: https://reviews.llvm.org/D113331
2021-11-12 01:04:08 +00:00
Nicolas Vasilache 34ff857350 [mlir][X86Vector] Add specialized vector.transpose lowering patterns for AVX2
This revision adds an implementation of 2-D vector.transpose for 4x8 and 8x8 for
AVX2 and surfaces it to the Linalg level of control.

Reviewed By: dcaballe

Differential Revision: https://reviews.llvm.org/D113347
2021-11-11 07:33:31 +00:00
Mehdi Amini f97e72aaca Use base class AsmParser/AsmPrinter in Types and Attribute print/parse method (NFC)
This decouples the printing/parsing from the "context" in which the parsing occurs.
This will allow to invoke these methods directly using an OpAsmParser/OpAsmPrinter.

Differential Revision: https://reviews.llvm.org/D113637
2021-11-11 06:26:33 +00:00
Jacques Pienaar 468581f16b [mlir] Fix unused variable waraning in OpDocGen 2021-11-10 18:19:09 -08:00
Jacques Pienaar ec0b53d4e4 [mlir] Add traits, interfaces, effects to generated docs
Simply emit traits, interfaces & effects (with some minimal formatting) to the
generated docs to make this information easier to find in the docs.

Differential Revision: https://reviews.llvm.org/D113539
2021-11-10 16:09:43 -08:00
thomasraoux 5aa6038a40 [mlir] Make topologicalSort iterative and consider op regions
When doing topological sort we need to make sure an op is scheduled before any
of the ops within its regions.
Also change the algorithm to not be recursive in order to prevent potential
stack overflow.

Differential Revision: https://reviews.llvm.org/D113423
2021-11-10 10:05:01 -08:00
Mehdi Amini 1370f52bb7 Fix ODS Attribute/Type declarative assembly generator after API change for Attribute/Type print
The change in f30a8a6f67 conflicted with the recently landed feature on
ODS assembly format for Attribute/Type.
2021-11-10 01:08:35 +00:00
Mehdi Amini f30a8a6f67 Change the contract with the type/attribute parsing to let the dispatch handle the mnemonic
This breaking change requires to remove printing the mnemonic in the print()
method on Type/Attribute classes.
This makes it consistent with the parsing code which alread handles the
mnemonic outside of the parsing method.

This likely won't break the build for anyone, but tests will start
failing for dialects downstream. The fix is trivial and look like
going from:

void emitc::OpaqueType::print(DialectAsmPrinter &printer) const {
  printer << "opaque<\"";

to:

void emitc::OpaqueAttr::print(DialectAsmPrinter &printer) const {
  printer << "<\"";

Reviewed By: rriddle, aartbik

Differential Revision: https://reviews.llvm.org/D113334
2021-11-10 00:47:15 +00:00
Mehdi Amini c27d85a9c9 Emit the boilerplate for Type printer/parser dialect dispatching from ODS
Add a new `useDefaultTypePrinterParser` boolean settings on the dialect
(default to false for now) that emits the boilerplate to dispatch type
parsing/printing to the auto-generated method.
We will likely turn this on by default in the future.

Differential Revision: https://reviews.llvm.org/D113332
2021-11-10 00:41:36 +00:00
Mehdi Amini fd6b404183 Emit the boilerplate for Attribute printer/parser dialect dispatching from ODS
Add a new `useDefaultAttributePrinterParser` boolean settings on the dialect
(default to false for now) that emits the boilerplate to dispatch attribute
parsing/printing to the auto-generated method.
We will likely turn this on by default in the future.

Differential Revision: https://reviews.llvm.org/D113329
2021-11-10 00:38:19 +00:00
Mogball 2dd00c17e0 [mlir][ods] Cleanup of handling Op vs OpAdaptor
In preparation for implementation subrange lookup on attributes.

Depends on D113039

Reviewed By: jpienaar, Chia-hungDuan

Differential Revision: https://reviews.llvm.org/D113128
2021-11-09 20:09:21 +00:00
River Riddle ae40d62541 [mlir] Refactor ElementsAttr's value access API
There are several aspects of the API that either aren't easy to use, or are
deceptively easy to do the wrong thing. The main change of this commit
is to remove all of the `getValue<T>`/`getFlatValue<T>` from ElementsAttr
and instead provide operator[] methods on the ranges returned by
`getValues<T>`. This provides a much more convenient API for the value
ranges. It also removes the easy-to-be-inefficient nature of
getValue/getFlatValue, which under the hood would construct a new range for
the type `T`. Constructing a range is not necessarily cheap in all cases, and
could lead to very poor performance if used within a loop; i.e. if you were to
naively write something like:

```
DenseElementsAttr attr = ...;
for (int i = 0; i < size; ++i) {
  // We are internally rebuilding the APFloat value range on each iteration!!
  APFloat it = attr.getFlatValue<APFloat>(i);
}
```

Differential Revision: https://reviews.llvm.org/D113229
2021-11-09 00:15:08 +00:00
Chia-hung Duan 2d99c815d7 [mlir-tblgen] Support `either` in Tablegen DRR.
Add a new directive `either` to specify the operands can be matched in either order

Reviewed By: jpienaar, Mogball

Differential Revision: https://reviews.llvm.org/D110666
2021-11-08 23:16:03 +00:00
Chia-hung Duan f3798ad5fa Static verifier for type/attribute in DRR
Generate static function for matching the type/attribute to reduce the
memory footprint.

Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D110199
2021-11-08 21:34:17 +00:00
Mogball 254ecfbc40 [mlir][ods] fix c++11 build 2021-11-08 20:40:13 +00:00
Jeff Niu 9a2fdc369d [MLIR] Attribute and type formats in ODS
Declarative attribute and type formats with assembly formats. Define an
`assemblyFormat` field in attribute and type defs with a `mnemonic` to
generate a parser and printer.

```tablegen
def MyAttr : AttrDef<MyDialect, "MyAttr"> {
  let parameters = (ins "int64_t":$count, "AffineMap":$map);
  let mnemonic = "my_attr";
  let assemblyFormat = "`<` $count `,` $map `>`";
}
```

Use `struct` to define a comma-separated list of key-value pairs:

```tablegen
def MyType : TypeDef<MyDialect, "MyType"> {
  let parameters = (ins "int":$one, "int":$two, "int":$three);
  let mnemonic = "my_attr";
  let assemblyFormat = "`<` $three `:` struct($one, $two) `>`";
}
```

Use `struct(*)` to capture all parameters.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D111594
2021-11-08 17:38:28 +00:00
Alex Zinenko 6981e5ec91 [mlir][python] fix constructor generation for optional operands in presence of segment attribute
The ODS-based Python op bindings generator has been generating incorrect
specification of the operand segment in presence if both optional and variadic
operand groups: optional groups were treated as variadic whereas they require
separate treatement. Make sure it is the case. Also harden the tests around
generated op constructors as they could hitherto accept the code for both
optional and variadic arguments.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D113259
2021-11-05 12:40:27 +01:00
Mogball 8129b04b8a [mlir][ods] Op::verify should not call OpAdaptor::verify
OpAdaptor::verify performs string lookups on an attribute dictionary. By
calling OpAdaptor::verify, Op::verify is not able to use cached attribute
identifiers for faster lookups.

Reviewed By: jpienaar, rriddle

Differential Revision: https://reviews.llvm.org/D113039
2021-11-04 19:12:55 +00:00
Jacques Pienaar a7fc39f213 [mlir] Use _odsPrinter for printer name in generated code
The generated name should not be load bearing, so this should be a NFC change.

Differential Revision: https://reviews.llvm.org/D113149
2021-11-03 15:34:13 -07:00
Jacques Pienaar 2fa76d4769 [mlir][ods] Fix incorrectly generated attribute name.
In prefixed accessor on OpAdaptor.
2021-10-29 14:06:33 -07:00
Jacques Pienaar 0ef217d8e1 [mlir] Fix missing prefix for region accessor on OpAdaptor
Also flip op-decl-and-defs test to _Prefixed to test more.
2021-10-26 17:35:16 -07:00
Jacques Pienaar 332ce23f3c [mlir][ods] Fix incorrect accessing of segment_sizes
The previous change resulted in prefixing a query that uses the raw
attribute as if function invocation. Fixing quickly, with updated test
to follow.
2021-10-26 16:04:15 -07:00
Matthias Kramm 16e530d43b When generating C++ code, use C++ string escaping.
Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D112468
2021-10-25 22:53:44 +00:00
Alex Zinenko 2995d29bb4 [mlir][python] Infer result types in generated constructors whenever possible
In several cases, operation result types can be unambiguously inferred from
operands and attributes at operation construction time. Stop requiring the user
to provide these types as arguments in the ODS-generated constructors in Python
bindings. In particular, handle the SameOperandAndResultTypes and
FirstAttrDerivedResultType traits as well as InferTypeOpInterface using the
recently added interface support. This is a significant usability improvement
for IR construction, similar to what C++ ODS provides.

Depends On D111656

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D111811
2021-10-25 12:50:44 +02:00
Matthias Kramm 95935e8285 Make genAttributeVerifier escape the summary.
The summary can contain references to e.g. attribute defaults, which
can contain special characters. So these strings need to be C++
escaped.

Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D112249
2021-10-21 21:41:31 +00:00
Matthias Kramm 5c0369eceb Fix escaping in RewriterGen.cpp.
When we escape strings for C++, make sure we use C++ escape
sequences. (In particular, \x22 instead of \22)

Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D112269
2021-10-21 21:33:19 +00:00
Alex Zinenko 310736e098 [mlir] fix region property generation in python bindings 2021-10-20 19:00:59 +02:00
Jacques Pienaar 6a99423390 [mlir] Expand prefixing to OpFormatGen
Follow up to also use the prefixed emitters in OpFormatGen (moved
getGetterName(s) and getSetterName(s) to Operator as that is most
convenient usage wise even though it just depends on Dialect). Prefix
accessors in Test dialect and follow up on missed changes in
OpDefinitionsGen.

Differential Revision: https://reviews.llvm.org/D112118
2021-10-20 07:08:37 -07:00
Mogball 44610c01ae [MLIR][ODS] default-valued strings should be in quotes
`DefaultValuedAttr<StrAttr, "">` and `ConstantAttr<StrAttr, "">`
result in bugs in which TableGen will not recognize that the attribute
has a default value, because `""` is an empty TableGen string.

Strings no longer have special treatment. Instead, string values must be
wrapped in quotes: "\"foo\"". Two helpers, `DefaultValuedStrAttr` and
`ConstantStrAttr` have been added to keep code clean.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D111855
2021-10-15 03:00:41 +00:00
Jacques Pienaar 65c9907c80 [mlir][ods] Enable emitting getter/setter prefix
Allow emitting get & set prefix for accessors generated for ops. If
enabled, then the argument/return/region name gets converted from
snake_case to UpperCamel and prefix added. The attribute also allows
generating both the current "raw" method along with the prefix'd one to
make it easier to stage changes.

The option is added on the dialect and currently defaults to existing
raw behavior. The expectation is that the staging where both are
generated would be short lived and so optimized to keeping the changes
local/less invasive (it just generates two functions for each accessor
with the same body - most of these internally again call a helper
function). But generation can be optimized if needed.

I'm unsure about OpAdaptor classes as there it is all get methods (it is
a named view into raw data structures), so prefix doesn't add much.

This starts with emitting raw-only form (as current behavior) as
default, then one can opt-in to raw & prefixed, then just prefixed. The
default in OpBase will switch to prefixed-only to be consistent with
MLIR style guide. And the option potentially removed later (considered
enabling specifying prefix but current discussion more pro keeping it
limited and stuck with that).

Also add more explicit checking for pruned functions to avoid emitting
where no function was added (and so avoiding dereferencing nullptr)
during op def/decl generation.

See https://bugs.llvm.org/show_bug.cgi?id=51916 for further discussion.

Differential Revision: https://reviews.llvm.org/D111033
2021-10-14 15:58:44 -07:00
Alex Zinenko 18fbd5fe34 [mlir][python] Better support for variadic regions in Python bindings
Improve support for variadic regions in ODS-generated operation view classes.
In particular, make generated constructors take an extra argument that
specifies the number of variadic regions if the operation has them. Previously,
there was no mechanism to specify a non-zero number of variadic regions. Also
generate named accessors to regions.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D111783
2021-10-14 13:15:13 +02:00
Tobias Gysi eaa52750ce [mlir][linalg] Verify every LinalgOp has a body.
After removing the last LinalgOps that have no region attached we can verify there is a region. The patch performs the following changes:
- Move the SingleBlockImplicitTerminator trait further up the the structured op base class.
- Adapt the LinalgOp verification since the trait only check if there is 0 or 1 block.
- Introduce a getBlock method on the LinalgOp interface.
- Access the LinalgOp body using either getBlock() or getBody() if the concrete operation type is known.

This patch is a follow up to https://reviews.llvm.org/D111233.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D111393
2021-10-14 09:08:39 +00:00
Mogball a54f4eae0e [MLIR] Replace std ops with arith dialect ops
Precursor: https://reviews.llvm.org/D110200

Removed redundant ops from the standard dialect that were moved to the
`arith` or `math` dialects.

Renamed all instances of operations in the codebase and in tests.

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D110797
2021-10-13 03:07:03 +00:00
Daniel Resnick 1760d8b36b [mlir][ODS] Support result type inference in custom assembly format
Operations that have the InferTypeOpInterface trait can now omit the return
types in their custom assembly formats.

Differential Revision: https://reviews.llvm.org/D111326
2021-10-11 14:07:56 -06:00
Alex Zinenko b164f23c29 [mlir][python] support taking ops instead of values in op constructors
Introduce support for accepting ops instead of values when constructing ops. A
single-result op can be used instead of a value, including in lists of values,
and any op can be used instead of a list of values. This is similar to, but
more powerful, than the C++ API that allows for implicitly casting an OpType to
Value if it is statically known to have a single result - the cast in Python is
based on the op dynamically having a single result, and also handles the
multi-result case. This allows to build IR in a more concise way:

    op = dialect.produce_multiple_results()
    other = dialect.produce_single_result()
    dialect.consume_multiple_results(other, op)

instead of having to access the results manually

    op = dialect.produce.multiple_results()
    other = dialect.produce_single_result()
    dialect.consume_multiple_results(other.result, op.operation.results)

The dispatch is implemented directly in Python and is triggered automatically
for autogenerated OpView subclasses. Extension OpView classes should use the
functions provided in ods_common.py if they want to implement this behavior.
An alternative could be to implement the dispatch in the C++ bindings code, but
it would require to forward opaque types through all Python functions down to a
binding call, which makes it hard to inspect them in Python, e.g., to obtain
the types of values.

Reviewed By: gysit

Differential Revision: https://reviews.llvm.org/D111306
2021-10-08 09:49:48 +02:00
Tobias Gysi 3fe7fe4424 [mlir][linalg] Add unsigned min/max/cast function to OpDSL.
Update OpDSL to support unsigned integers by adding unsigned min/max/cast signatures. Add tests in OpDSL and on the C++ side to verify the proper signed and unsigned operations are emitted.

The patch addresses an issue brought up in https://reviews.llvm.org/D111170.

Reviewed By: rsuderman

Differential Revision: https://reviews.llvm.org/D111230
2021-10-07 06:27:20 +00:00
Lei Zhang 83e074a0c6 [mlir] Add an 'cppNamespace' field to availability
This allows us to generate interfaces in a namespace,
following other TableGen'erated code.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D108311
2021-10-05 09:38:09 -04:00
Stella Laurenzo 267bb194f3 [mlir] Remove old "tc" linalg ods generator.
* This could have been removed some time ago as it only had one op left in it, which is redundant with the new approach.
* `matmul_i8_i8_i32` (the remaining op) can be trivially replaced by `matmul`, which natively supports mixed precision.

Differential Revision: https://reviews.llvm.org/D110792
2021-09-30 16:30:06 +00:00
Chris Lattner fb093c8314 [ODS/AsmParser] Don't pass MLIRContext with DialectAsmParser.
The former is redundant because the later carries it as part of
its builder.  Add a getContext() helper method to DialectAsmParser
to make this more convenient, and stop passing the context around
explicitly.  This simplifies ODS generated parser hooks for attrs
and types.

This resolves PR51985

Recommit 4b32f8bac4 after fixing a dependency.

Differential Revision: https://reviews.llvm.org/D110796
2021-09-30 05:10:28 +00:00
Mehdi Amini 3310e0020c Revert "[ODS/AsmParser] Don't pass MLIRContext with DialectAsmParser."
This reverts commit 4b32f8bac4.

Seems like the build is broken with -DDBUILD_SHARED_LIBS=ON
2021-09-30 05:01:17 +00:00
Chris Lattner 4b32f8bac4 [ODS/AsmParser] Don't pass MLIRContext with DialectAsmParser.
The former is redundant because the later carries it as part of
its builder.  Add a getContext() helper method to DialectAsmParser
to make this more convenient, and stop passing the context around
explicitly.  This simplifies ODS generated parser hooks for attrs
and types.

This resolves PR51985

Differential Revision: https://reviews.llvm.org/D110796
2021-09-29 21:36:05 -07:00
Mehdi Amini 9c2cd6e7c8 Fix clang-tidy warning "modernize-use-nullptr" in MLIR VulkanRuntime (NFC) 2021-09-26 22:06:00 +00:00
Diego Caballero 2a876a711d [mlir] Create a generic reduction detection utility
This patch introduces a generic reduction detection utility that works
across different dialecs. It is mostly a generalization of the reduction
detection algorithm in Affine. The reduction detection logic in Affine,
Linalg and SCFToOpenMP have been replaced with this new generic utility.

The utility takes some basic components of the potential reduction and
returns: 1) the reduced value, and 2) a list with the combiner operations.
The logic to match reductions involving multiple combiner operations disabled
until we can properly test it.

Reviewed By: ftynse, bondhugula, nicolasvasilache, pifon2a

Differential Revision: https://reviews.llvm.org/D110303
2021-09-24 20:45:59 +00:00
Diana Picus b7050c791d [mlir] Fix build on Windows on Arm
clang-cl errors out while handling the templated version of tgfmt. This
patch works around the issue by explicitly choosing the non-templated
version of tgfmt, which takes an ArrayRef<std::string>.

More details in this thread:
https://lists.llvm.org/pipermail/cfe-dev/2021-September/068936.html

Thanks @Mehdi Amini for suggesting the fix :)

Differential Revision: https://reviews.llvm.org/D110223
2021-09-23 09:04:28 +02:00
Tyler Augustine cd36bab4ca Fix bug for Ops with default valued attributes and successors/variadic regions.
When both a DefaultValuedAttr and a successor or variadic region was specified, this would generate invalid C++ declaration. There would be the parameter with a default value, followed by the successors/regions, which don't have a default, which is invalid.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D110205
2021-09-22 21:22:31 +00:00
River Riddle d80d3a358f [mlir] Refactor ElementsAttr into an AttrInterface
This revision refactors ElementsAttr into an Attribute Interface.
This enables a common interface with which to interact with
element attributes, without needing to modify the builtin
dialect. It also removes a majority (if not all?) of the need for
the current OpaqueElementsAttr, which was originally intended as
a way to opaquely represent data that was not representable by
the other builtin constructs.

The new ElementsAttr interface not only allows for users to
natively represent their data in the way that best suits them,
it also allows for efficient opaque access and iteration of the
underlying data. Attributes using the ElementsAttr interface
can directly expose support for interacting with the held
elements using any C++ data type they claim to support. For
example, DenseIntOrFpElementsAttr supports iteration using
various native C++ integer/float data types, as well as
APInt/APFloat, and more. ElementsAttr instances that refer to
DenseIntOrFpElementsAttr can use all of these data types for
iteration:

```c++
DenseIntOrFpElementsAttr intElementsAttr = ...;

ElementsAttr attr = intElementsAttr;
for (uint64_t value : attr.getValues<uint64_t>())
  ...;
for (APInt value : attr.getValues<APInt>())
  ...;
for (IntegerAttr value : attr.getValues<IntegerAttr>())
  ...;
```

ElementsAttr also supports failable range/iterator access,
allowing for selective code paths depending on data type
support:

```c++
ElementsAttr attr = ...;
if (auto range = attr.tryGetValues<uint64_t>()) {
  for (uint64_t value : *range)
    ...;
}
```

Differential Revision: https://reviews.llvm.org/D109190
2021-09-21 01:57:43 +00:00
River Riddle 0cb5d7fc7f [mlir] Add value_begin/value_end methods to DenseElementsAttr
Currently DenseElementsAttr only exposes the ability to get the full range of values for a given type T, but there are many situations where we just want the beginning/end iterator. This revision adds proper value_begin/value_end methods for all of the supported T types, and also cleans up a bit of the interface.

Differential Revision: https://reviews.llvm.org/D104173
2021-09-21 01:57:43 +00:00
Chia-hung Duan bb2506061b [mlir-tblgen] Add DagNode StaticMatcher.
Some patterns may share the common DAG structures. Generate a static
function to do the match logic to reduce the binary size.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D105797
2021-09-20 23:37:42 +00:00
Mogball cb8c30d35d [DRR] Explicit Return Types in Rewrites
Adds a new rewrite directive returnType that can be added at the end of an op's
argument list to explicitly specify return types.

```
(OpX $v0, $v1, (returnType "$_builder.getI32Type()"))
```

Pass in a bound value to copy its return type, or pass a native code call to
dynamically create new types.

```
(OpX $v0, $v1, (returnType $v0, (NativeCodeCall<"..."> $v1)))
```

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D109472
2021-09-15 14:25:29 -07:00
Mehdi Amini 7fb2394a4f Add sanity check in MLIR ODS to catch case where an arguments/results/regions/successors names overlap
This is making a tablegen crash with a more friendly error.

Differential Revision: https://reviews.llvm.org/D109474
2021-09-13 06:21:25 +00:00
Alex Zinenko 8b58ab8ccd [mlir] Factor type reconciliation out of Standard-to-LLVM conversion
Conversion to the LLVM dialect is being refactored to be more progressive and
is now performed as a series of independent passes converting different
dialects. These passes may produce `unrealized_conversion_cast` operations that
represent pending conversions between built-in and LLVM dialect types.
Historically, a more monolithic Standard-to-LLVM conversion pass did not need
these casts as all operations were converted in one shot. Previous refactorings
have led to the requirement of running the Standard-to-LLVM conversion pass to
clean up `unrealized_conversion_cast`s even though the IR had no standard
operations in it. The pass must have been also run the last among all to-LLVM
passes, in contradiction with the partial conversion logic. Additionally, the
way it was set up could produce invalid operations by removing casts between
LLVM and built-in types even when the consumer did not accept the uncasted
type, or could lead to cryptic conversion errors (recursive application of the
rewrite pattern on `unrealized_conversion_cast` as a means to indicate failure
to eliminate casts).

In fact, the need to eliminate A->B->A `unrealized_conversion_cast`s is not
specific to to-LLVM conversions and can be factored out into a separate type
reconciliation pass, which is achieved in this commit. While the cast operation
itself has a folder pattern, it is insufficient in most conversion passes as
the folder only applies to the second cast. Without complex legality setup in
the conversion target, the conversion infra will either consider the cast
operations valid and not fold them (a separate canonicalization would be
necessary to trigger the folding), or consider the first cast invalid upon
generation and stop with error. The pattern provided by the reconciliation pass
applies to the first cast operation instead. Furthermore, having a separate
pass makes it clear when `unrealized_conversion_cast`s could not have been
eliminated since it is the only reason why this pass can fail.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D109507
2021-09-09 16:51:24 +02:00
Mehdi Amini 4eaaf05394 Add sanity check in MLIR ODS to catch case where two results have the same name
This is making a tablegen crash with a more friendly error.

Differential Revision: https://reviews.llvm.org/D109456
2021-09-08 23:38:50 +00:00
Mehdi Amini 6f1f30a957 Add sanity check in MLIR ODS to catch case where two operands have the same name
This is making a tablegen crash into a more friendly error.

Differential Revision: https://reviews.llvm.org/D109449
2021-09-08 16:58:57 +00:00
Tyler Augustine 7105512a34 Support alias.scope and noalias metadata lowering on intrinsics.
Builds on https://reviews.llvm.org/D107870 to support annotating intrinsics with alias.scope and noalias metadata.

Reviewed By: arpith-jacob, ftynse

Differential Revision: https://reviews.llvm.org/D109025
2021-09-01 16:54:20 +00:00
Mehdi Amini c41b16c26b Change ASM Op printer to print the operation name in the framework instead of leaving it up to each individual operation
This aligns the printer with the parser contract: the operation isn't part of the user-controllable part of the syntax.

Differential Revision: https://reviews.llvm.org/D108804
2021-08-31 17:52:40 +00:00
Stella Laurenzo 8e6c55c92c [mlir][python] Extend C/Python API to be usable for CFG construction.
* It is pretty clear that no one has tried this yet since it was both incomplete and broken.
* Fixes a symbol hiding issues keeping even the generic builder from constructing an operation with successors.
* Adds ODS support for successors.
* Adds CAPI `mlirBlockGetParentRegion`, `mlirRegionEqual` + tests (and missing test for `mlirBlockGetParentOperation`).
* Adds Python property: `Block.region`.
* Adds Python methods: `Block.create_before` and `Block.create_after`.
* Adds Python property: `InsertionPoint.block`.
* Adds new blocks.py test to verify a plausible CFG construction case.

Differential Revision: https://reviews.llvm.org/D108898
2021-08-30 08:28:00 -07:00
River Riddle c8d9e1ce43 [mlir][AttrTypeGen] Add support for specifying a "accessor" type of a parameter
This allows for using a different type when accessing a parameter than the
one used for storage. This allows for returning parameters by reference,
enables using more optimized/convient reference results, and more.

Differential Revision: https://reviews.llvm.org/D108593
2021-08-25 09:27:36 +00:00
MaheshRavishankar b546f4347b [mlir]Linalg] Allow controlling fusion of linalg.generic -> linalg.tensor_expand_shape.
Differential Revision: https://reviews.llvm.org/D108565
2021-08-23 16:28:10 -07:00