Commit Graph

409 Commits

Author SHA1 Message Date
Sergei Grechanik 27df7158fe [mlir] Fix dumping invalid ops
This patch fixes the crash when printing some ops (like affine.for and
scf.for) when they are dumped in invalid state, e.g. during pattern
application. Now the AsmState constructor verifies the operation
first and switches to generic operation printing when the verification
fails. Also operations are now printed in generic form when emitting
diagnostics and the severity level is Error.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D117834
2022-03-07 08:32:31 -08:00
Sergei Grechanik 988a3ba0d8 [mlir] Expose printer flags in AsmState
This change exposes printer flags in AsmState and AsmStateImpl. All functions
receiving AsmState as a parameter now use the flags from the AsmState instead of
taking an additional OpPrintingFlags parameter.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D119870
2022-02-15 17:27:45 -08:00
Mehdi Amini b055e6d313 Add a new interface method `getAsmBlockName()` on OpAsmOpInterface to control block names
This allows operations to control the block ids used by the printer in nested regions.

Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D115849
2022-02-11 08:46:08 +00:00
Sanjoy Das c080456d64 Delete dead code
Differential Revision: https://reviews.llvm.org/D118501
2022-01-28 20:01:35 -08:00
Uday Bondhugula 8676e10f74 [MLIR] Improve doc for -mlir-print-local-scope and unhide
This is a pretty important debugging option to stay hidden. Also,
improve its cmd-line description; the current description gives no hint
that this is the one to use to have locations printed inline.
Out-of-line locations are also unproductive to work with in many cases
where the locations are actually compact, which is also why this option
should be more visible.  This revision doesn't change the default on it
though.

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D117186
2022-01-25 11:13:48 +05:30
Mehdi Amini 9006bf4248 Remove obsolete `getAsmResultNames` from OpAsmDialectInterface
This is superseded by the same method on OpAsmOpInterface, which is
available on the Dialect through the Fallback mechanism,

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D117750
2022-01-21 05:58:32 +00:00
River Riddle d75c3e8396 [mlir] Don't print `// no predecessors` on entry blocks
Entry blocks can never have predecessors, so this is unnecessary.

Fixes #53287

Differential Revision: https://reviews.llvm.org/D117713
2022-01-19 15:57:58 -08:00
Mehdi Amini e7ab36f191 Change elided large constant syntax to make it more explicit
When the printer is requested to elide large constant, we emit an opaque
attribute instead. This patch fills the dialect name with
"elided_large_const" instead of "_" to remove some user confusion when
they later try to consume it.

Differential Revision: https://reviews.llvm.org/D117711
2022-01-19 20:41:42 +00:00
Mogball 5c36ee8d57 [mlir] Drop the leading space when printing regions
The leading space that is always printed at the beginning of regions is not consistent with other parts of the printing API. Moreover, this leading space can lead to undesirable assembly formats:

```
attr-dict-with-keyword $region
```

Prints as:

```
// Two spaces between `}` and `{`
attributes {foo}  { ... }
```

Moreover, the leading space results in the odd generic op format:

```
"test.op"() ( {...}) : () -> ()
```

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D117411
2022-01-18 16:52:34 +00:00
Stanislav Funiak 7de8488c3d [MLIR] Printing a null Value.
This diff adds support to printing a Value when it is null. We encounter this situation when debugging the PDL bytcode execution (where a null Value is perfectly valid). Currently, the AsmPrinter crashes (with an assert in a cast) when it encounters such Value.

We follow the same format used in other printed entities (e.g., null attribute).

Reviewed By: mehdi_amini, bondhugula

Differential Revision: https://reviews.llvm.org/D116084
2022-01-04 08:13:03 +05:30
Mehdi Amini e5639b3fa4 Fix more clang-tidy cleanups in mlir/ (NFC) 2021-12-22 20:53:11 +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
Mehdi Amini 7f9e9c7fc3 Move getAsmBlockArgumentNames from OpAsmDialectInterface to OpAsmOpInterface
This method is more suitable as an opinterface: it seems intrinsic to
individual instances of the operation instead of the dialect.
Also remove the restriction on the interface being applicable to the entry block only.

Differential Revision: https://reviews.llvm.org/D116018
2021-12-20 07:18:01 +00:00
Javier Setoain a4830d14ed [mlir][RFC] Add scalable dimensions to VectorType
With VectorType supporting scalable dimensions, we don't need many of
the operations currently present in ArmSVE, like mask generation and
basic arithmetic instructions. Therefore, this patch also gets
rid of those.

Having built-in scalable vector support also simplifies the lowering of
scalable vector dialects down to LLVMIR.

Scalable dimensions are indicated with the scalable dimensions
between square brackets:

        vector<[4]xf32>

Is a scalable vector of 4 single precission floating point elements.

More generally, a VectorType can have a set of fixed-length dimensions
followed by a set of scalable dimensions:

        vector<2x[4x4]xf32>

Is a vector with 2 scalable 4x4 vectors of single precission floating
point elements.

The scale of the scalable dimensions can be obtained with the Vector
operation:

        %vs = vector.vscale

This change is being discussed in the discourse RFC:

https://llvm.discourse.group/t/rfc-add-built-in-support-for-scalable-vector-types/4484

Differential Revision: https://reviews.llvm.org/D111819
2021-12-15 09:31:37 +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
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 120591e126 [mlir] Replace usages of Identifier with StringAttr
Identifier and StringAttr essentially serve the same purpose, i.e. to hold a string value. Keeping these seemingly identical pieces of functionality separate has caused problems in certain situations:

* Identifier has nice accessors that StringAttr doesn't
* Identifier can't be used as an Attribute, meaning strings are often duplicated between Identifier/StringAttr (e.g. in PDL)

The only thing that Identifier has that StringAttr doesn't is support for caching a dialect that is referenced by the string (e.g. dialect.foo). This functionality is added to StringAttr, as this is useful for StringAttr in generally the same ways it was useful for Identifier.

Differential Revision: https://reviews.llvm.org/D113536
2021-11-11 02:02:24 +00:00
Mehdi Amini 19ced834cc Check if an attribute is in the builtin dialect before going through all the possible combinations (NFC)
This is just a "micro-optimization" noticed through code review.

Differential Revision: https://reviews.llvm.org/D112984
2021-11-02 05:57:40 +00:00
Vladislav Vinogradov e41ebbecf9 [mlir][RFC] Refactor layout representation in MemRefType
The change is based on the proposal from the following discussion:
https://llvm.discourse.group/t/rfc-memreftype-affine-maps-list-vs-single-item/3968

* Introduce `MemRefLayoutAttr` interface to get `AffineMap` from an `Attribute`
  (`AffineMapAttr` implements this interface).
* Store layout as a single generic `MemRefLayoutAttr`.

This change removes the affine map composition feature and related API.
Actually, while the `MemRefType` itself supported it, almost none of the upstream
can work with more than 1 affine map in `MemRefType`.

The introduced `MemRefLayoutAttr` allows to re-implement this feature
in a more stable way - via separate attribute class.

Also the interface allows to use different layout representations rather than affine maps.
For example, the described "stride + offset" form, which is currently supported in ASM parser only,
can now be expressed as separate attribute.

Reviewed By: ftynse, bondhugula

Differential Revision: https://reviews.llvm.org/D111553
2021-10-19 12:31:15 +03:00
Andrew Young 844706701e
[MLIR] Add `KeywordOrString` handling to AsmParser
This adds a new parser and printer for text which may be a keyword or a
string. When printing, it will attempt to print the text as a keyword,
but if it has any special or non-printable characters, it will be
printed as an escaped string.  When parsing, it will parse either a
valid keyword or a potentially escaped string. The printer allows for an
empty string, in which case it prints `""`.

This new function is used for printing the name in NamedAttributes, and
for printing the symbol name after the `@`. In CIRCT we are using this
to print module port names, which are conceptually similar to named
function arguments.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D111683
2021-10-15 00:08:34 -07:00
Vladislav Vinogradov c6390f19f2 [mlir] Fix AsmPrinter for types with sub elements
Call `printType(subElemType)` instead of `os << subElemType` for them.
It allows to handle type aliases inside complex types.

As a side effect, fixed `test.int` parsing.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D111536
2021-10-12 12:08:16 +03:00
Chris Lattner 33f4315324 [AsmParser] move AsmParser::getContext to IR library.
This is (perhaps unintuitively) where the other AsmParser method
implementations are, which means that dialects don't generally need
to depend on MLIRParser directly.  This should fix a build failure
building .so files on the mlir-nvidia builder.
2021-09-29 22:07:00 -07:00
River Riddle 531206310a [mlir:OpAsm] Factor out the common bits of (Op/Dialect)Asm(Parser/Printer)
This has a few benefits:
* It allows for defining parsers/printer code blocks that
  can be shared between operations and attribute/types.
* It removes the weird duplication of generic parser/printer hooks,
  which means that newly added hooks only require touching one class.

Differential Revision: https://reviews.llvm.org/D110375
2021-09-24 20:12:19 +00:00
Chris Lattner da93829b44 [DialectAsmPrinter] Add missing 'printAttributeWithoutType' member.
DialectAsmParser has a `parseAttribute` member that takes a
contextual type, but DialectAsmPrinter doesn't have the corresponding
member to take advantage of it.  As such, custom attribute
implementations can't really use it.  This adds the obvious missing
method which fills this hole.

Differential Revision: https://reviews.llvm.org/D110211
2021-09-21 18:45:24 -07: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
Mehdi Amini 387f95541b Add a new interface allowing to set a default dialect to be used for printing/parsing regions
Currently the builtin dialect is the default namespace used for parsing
and printing. As such module and func don't need to be prefixed.
In the case of some dialects that defines new regions for their own
purpose (like SpirV modules for example), it can be beneficial to
change the default dialect in order to improve readability.

Differential Revision: https://reviews.llvm.org/D107236
2021-08-31 17:52:40 +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
Mehdi Amini fd87963eee Change dialect `printOperation()` hook to `getOperationPrinter()`
This makes the hook return a printer if available, instead of using LogicalResult  to
indicate if a printer was available (and invoked). This allows the caller to detect that
the dialect has a printer for a given operation without actually invoking the printer.
It'll be leveraged in a future revision to move printing the op name itself under control
of the ASMPrinter.

Differential Revision: https://reviews.llvm.org/D108803
2021-08-31 17:52:39 +00:00
Chris Lattner 41d4aa7de6 [SymbolRefAttr] Revise SymbolRefAttr to hold a StringAttr.
SymbolRefAttr is fundamentally a base string plus a sequence
of nested references.  Instead of storing the string data as
a copies StringRef, store it as an already-uniqued StringAttr.

This makes a lot of things simpler and more efficient because:
1) references to the symbol are already stored as StringAttr's:
   there is no need to copy the string data into MLIRContext
   multiple times.
2) This allows pointer comparisons instead of string
   comparisons (or redundant uniquing) within SymbolTable.cpp.
3) This allows SymbolTable to hold a DenseMap instead of a
   StringMap (which again copies the string data and slows
   lookup).

This is a moderately invasive patch, so I kept a lot of
compatibility APIs around.  It would be nice to explore changing
getName() to return a StringAttr for example (right now you have
to use getNameAttr()), and eliminate things like the StringRef
version of getSymbol.

Differential Revision: https://reviews.llvm.org/D108899
2021-08-29 21:54:47 -07:00
Vladislav Vinogradov 59f59d1c62 [mlir] Allow to override type/attr aliases from various hooks
Use new return type for `OpAsmDialectInterface::getAlias`:

* `AliasResult::NoAlias` if an alias was not provided.
* `AliasResult::OverridableAlias` if an alias was provided, but it might be overriden by other hook.
* `AliasResult::FinalAlias` if an alias was provided and it should be used (no other hooks will be checked).

In that case `AsmPrinter` will use either the first alias with `FinalAlias` result or
the last alias with `OverridableAlias` result (it depends on dialect array order).

Used `OverridableAlias` result for `BuiltinOpAsmDialectInterface`.

Use case: provide more informative alias for built-in attributes like `AffineMapAttr`
instead of generic "map<N>".

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D107437
2021-08-06 12:05:31 +03:00
Itai Zukerman ebbe149a6f [mlir] Gated calls to getAsm{Result,BlockArgument}Names on whether printing ops in generic form.
Depends On D105300

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D105301
2021-07-10 17:19:37 +00:00
Itai Zukerman 2c0f17982f [mlir] Added OpPrintingFlags to AsmState and SSANameState.
This enables checking the printing flags when formatting names
in SSANameState.

Depends On D105299

Reviewed By: mehdi_amini, bondhugula

Differential Revision: https://reviews.llvm.org/D105300
2021-07-10 16:40:00 +00:00
Itai Zukerman f4f11ee4a7 [mlir][NFC] Switched `interfaces` to a private member of SSANameState.
`interfaces` is passed through to the `numberValuesIn*` functions with exactly
the same value as when SSANameState is constructed.  This just seems cleaner.

Also, a dependent PR adds `printerFlags` which follows similar code paths.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D105299
2021-07-10 16:40:00 +00:00
David Blaikie 1def2579e1 PR51018: Remove explicit conversions from SmallString to StringRef to future-proof against C++23
C++23 will make these conversions ambiguous - so fix them to make the
codebase forward-compatible with C++23 (& a follow-up change I've made
will make this ambiguous/invalid even in <C++23 so we don't regress
this & it generally improves the code anyway)
2021-07-08 13:37:57 -07:00
Markus Böck a96911c49b [mlir] Escape strings of opaque attributes
Opaque attributes that currently contain string literals can't currently be properly roundtripped as they are not printed as escaped strings. This leads to incorrect tokens being generated and the parser to almost certainly fail. This patch simply uses llvm::printEscapedString from LLVM. It escapes all non printable characters and quotes to \xx hex literals, and backslashes to two backslashes. This syntax is supported by MLIRs Lexer as well. The same function is also currently in use for the same purpose in printSymbolReference, printAttribute for StringAttr and many more in AsmPrinter.cpp.

Differential Revision: https://reviews.llvm.org/D105405
2021-07-05 12:13:36 +02:00
Robert David 7cfb7a67c5 [mlir] Make Type::print and Type::dump const 2021-06-16 15:31:20 -07:00
Nicolas Vasilache a1678987d9 [mlir] NFC - Drop newline form BlockArgument printing.
Differential Revision: https://reviews.llvm.org/D104368
2021-06-16 13:28:43 +00:00
River Riddle c42dd5dbb0 [mlir] Add new SubElementAttr/SubElementType Interfaces
These interfaces allow for a composite attribute or type to opaquely provide access to any held attributes or types. There are several intended use cases for this interface. The first of which is to allow the printer to create aliases for non-builtin dialect attributes and types. In the future, this interface will also be extended to allow for SymbolRefAttr to be placed on other entities aside from just DictionaryAttr and ArrayAttr.

To limit potential test breakages, this revision only adds the new interfaces to the builtin attributes/types that are currently hardcoded during AsmPrinter alias generation. In a followup the remaining builtin attributes/types, and non-builtin attributes/types can be extended to support it.

Differential Revision: https://reviews.llvm.org/D102945
2021-06-10 17:23:07 -07:00
Lei Zhang 4694097dab [mlir] Don't elide the last op if there is no terminator
Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D103264
2021-05-28 07:25:49 -04:00
Chris Lattner 81467f500f [IR] Add a Location to BlockArgument
This adds the ability to specify a location when creating BlockArguments.
Notably Value::getLoc() will return this correctly, which makes diagnostics
more precise (e.g. the example in test-legalize-type-conversion.mlir).

This is currently optional to avoid breaking any existing code - if
absent, the BlockArgument defaults to using the location of its enclosing
operation (preserving existing behavior).

The bulk of this change is plumbing location tracking through the parser
and printer to make sure it can round trip (in -mlir-print-debuginfo
mode).  This is complete for generic operations, but requires manual
adoption for custom ops.

I added support for function-like ops to round trip their argument
locations - they print correctly, but when parsing the locations are
dropped on the floor.  I intend to fix this, but it will require more
invasive plumbing through "function_like_impl" stuff so I think it
best to split it out to its own patch.

This is a reapply of the patch here: https://reviews.llvm.org/D102567
with an additional change: we now never defer block argument locations,
guaranteeing that we can round trip correctly.

This isn't required in all cases, but allows us to hill climb here and
works around unrelated bugs like https://bugs.llvm.org/show_bug.cgi?id=50451

Differential Revision: https://reviews.llvm.org/D102991
2021-05-23 14:10:00 -07:00
Richard Smith 80d981eda6 Revert "[IR] Add a Location to BlockArgument." and follow-on commit
"[mlir] Speed up Lexer::getEncodedSourceLocation"

This reverts commit 3043be9d2d and commit
861d69a525.

This change resulted in printing textual MLIR that can't be parsed; see
review thread https://reviews.llvm.org/D102567 for details.
2021-05-18 19:26:00 -07:00
Chris Lattner 3043be9d2d [IR] Add a Location to BlockArgument.
This adds the ability to specify a location when creating BlockArguments.
Notably Value::getLoc() will return this correctly, which makes diagnostics
more precise (e.g. the example in test-legalize-type-conversion.mlir).

This is currently optional to avoid breaking any existing code - if
absent, the BlockArgument defaults to using the location of its enclosing
operation (preserving existing behavior).

The bulk of this change is plumbing location tracking through the parser
and printer to make sure it can round trip (in -mlir-print-debuginfo
mode).  This is complete for generic operations, but requires manual
adoption for custom ops.

I added support for function-like ops to round trip their argument
locations - they print correctly, but when parsing the locations are
dropped on the floor.  I intend to fix this, but it will require more
invasive plumbing through "function_like_impl" stuff so I think it
best to split it out to its own patch.

Differential Revision: https://reviews.llvm.org/D102567
2021-05-18 10:18:04 -07:00
Eugene Zhulenev fb3a00c327 [mlir] Fix ssa values naming bug
Address comments in https://reviews.llvm.org/D102226 to fix the bug + style violations

Differential Revision: https://reviews.llvm.org/D102368
2021-05-12 14:30:29 -07:00
Chia-hung Duan f653313d4a [mlir][AsmPrinter] Remove recursion while SSA naming
Address the TODO of removing recursion while SSA naming.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D102226
2021-05-12 11:23:01 +08:00
Alex Zinenko 6841e6afba [mlir] support max/min lower/upper bounds in affine.parallel
This enables to express more complex parallel loops in the affine framework,
for example, in cases of tiling by sizes not dividing loop trip counts perfectly
or inner wavefront parallelism, among others. One can't use affine.max/min
and supply values to the nested loop bounds since the results of such
affine.max/min operations aren't valid symbols. Making them valid symbols
isn't an option since they would introduce selection trees into memref
subscript arithmetic as an unintended and undesired consequence. Also
add support for converting such loops to SCF. Drop some API that isn't used in
the core repo from AffineParallelOp since its semantics becomes ambiguous in
presence of max/min bounds. Loop normalization is currently unavailable for
such loops.

Depends On D101171

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D101172
2021-04-29 13:16:25 +02:00
Nico Weber fce0ef277d [mlir] some iwyu fixes after ba7a92c01e 2021-04-21 10:48:54 -04:00
River Riddle b1260109fb [mlir][AsmPrinter] Fix multi-threaded segfault by using explicit null stream per thread
We were using llvm::nulls, but that isn't thread safe so we switch to giving each thread it's own null stream.

Differential Revision: https://reviews.llvm.org/D100578
2021-04-15 12:26:59 -07:00
Aart Bik 7714b405a0 [mlir] introduce "encoding" attribute to tensor type
This CL introduces a generic attribute (called "encoding") on tensors.
The attribute currently does not carry any concrete information, but the type
system already correctly determines that tensor<8xi1,123> != tensor<8xi1,321>.
The attribute will be given meaning through an interface in subsequent CLs.

See ongoing discussion on discourse:

[RFC] Introduce a sparse tensor type to core MLIR
https://llvm.discourse.group/t/rfc-introduce-a-sparse-tensor-type-to-core-mlir/2944

A sparse tensor will look something like this:

```
// named alias with all properties we hold dear:
#CSR = {
  // individual named attributes
}

// actual sparse tensor type:
tensor<?x?xf64, #CSR>
```

I see the following rough 5 step plan going forward:

(1) introduce this format attribute in this CL, currently still empty
(2) introduce attribute interface that gives it "meaning", focused on sparse in first phase
(3) rewrite sparse compiler to use new type, remove linalg interface and "glue"
(4) teach passes to deal with new attribute, by rejecting/asserting on non-empty attribute as simplest solution, or doing meaningful rewrite in the longer run
(5) add FE support, document, test, publicize new features, extend "format" meaning to other domains if useful

Reviewed By: stellaraccident, bondhugula

Differential Revision: https://reviews.llvm.org/D99548
2021-04-12 10:37:15 -07:00