Commit Graph

1341 Commits

Author SHA1 Message Date
Tobias Gysi b9715156ff [mlir][linalg] lower index operations during linalg to vector lowering.
The patch extends the vectorization pass to lower linalg index operations to vector code. It allocates constant 1d vectors that enumerate the indexes along the iteration dimensions and broadcasts/transposes these 1d vectors to the iteration space.

Differential Revision: https://reviews.llvm.org/D100373
2021-04-20 11:55:44 +00:00
Frederik Gossen c2c65585c5 [MLIR] Fix `isValidIndex`
Differential Revision: https://reviews.llvm.org/D100635
2021-04-16 14:58:54 +02:00
River Riddle 706c9c5ce0 [mlir] Add support for walking locations similarly to Operations
This allows for walking all nested locations of a given location, and is generally useful when processing locations.

Differential Revision: https://reviews.llvm.org/D100437
2021-04-15 16:09:34 -07:00
River Riddle 4efb7754e0 [mlir][NFC] Add a using directive for llvm::SetVector
Differential Revision: https://reviews.llvm.org/D100436
2021-04-15 16:09:34 -07: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
Tobias Gysi b614ada0e8 [mlir] add support for index type in vectors.
The patch enables the use of index type in vectors. It is a prerequisite to support vectorization for indexed Linalg operations. This refactoring became possible due to the newly introduced data layout infrastructure. The data layout of a module defines the bitwidth of the index type needed to verify bitcasts and similar vector operations.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D99948
2021-04-08 08:17:13 +00:00
Christian Sigg fcc5755878 [mlir] Remove no-op array assignment in dictionaryAttrSort().
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D99954
2021-04-06 21:30:37 +02:00
David Blaikie 499571ea83 Add workaround for false positive in -Wfree-nonheap-object 2021-04-03 14:03:43 -07:00
River Riddle 109305e104 [mlir] Emit errors when creating unregistered attributes/types when not allowed
This was missed when verification for creating unregistered operations was added.

Differential Revision: https://reviews.llvm.org/D99684
2021-04-02 12:45:35 -07:00
Nicolas Vasilache 335d2df533 [mlir][Python][Linalg] Add missing attributes to linalg ops
This revision tightens up the handling of attributes for both named
and generic linalg ops.
To demonstrate the IR validity, a working e2e Linalg example is added.

Differential Revision: https://reviews.llvm.org/D99430
2021-04-01 08:16:50 +00:00
Mehdi Amini a360a9786f Fix deletion of operations through the rewriter in a pattern matching a consumer operation
This allows for the conversion to match `A(B()) -> C()` with a pattern matching
`A` and marking `B` for deletion.

Also add better assertions when an operation is erased while still having uses.

Differential Revision: https://reviews.llvm.org/D99442
2021-03-30 22:02:14 +00:00
thomasraoux 5288c25c70 [mlir][vector] Add lowering of Transfer_read with broadcast and permutation map
Convert transfer_read ops with permutation maps into simpler
transfer_read with minority map + vector.braodcast and vector.transpose.
And transfer_read with leading dimensions broacast into transfer_read of
lower rank.

Differential Revision: https://reviews.llvm.org/D99019
2021-03-29 08:38:43 -07:00
Mehdi Amini fcdf142ed5 Remove unused function, fix warning (NFC)
The `mayNotHaveTerminator` was initially on Block but moved to the
verifier before landing and wasn't removed from its original place
where it is unused.
2021-03-25 18:37:57 +00:00
Vladislav Vinogradov 70b6f16e07 [mlir] Support MemRefType with multiple AffineMaps in getStridesAndOffset
Compose multiple AffineMaps into single map before strides extraction.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D99166
2021-03-25 12:18:49 +03:00
Mehdi Amini 973ddb7d6e Define a `NoTerminator` traits that allows operations with a single block region to not provide a terminator
In particular for Graph Regions, the terminator needs is just a
historical artifact of the generalization of MLIR from CFG region.
Operations like Module don't need a terminator, and before Module
migrated to be an operation with region there wasn't any needed.

To validate the feature, the ModuleOp is migrated to use this trait and
the ModuleTerminator operation is deleted.

This patch is likely to break clients, if you're in this case:

- you may iterate on a ModuleOp with `getBody()->without_terminator()`,
  the solution is simple: just remove the ->without_terminator!
- you created a builder with `Builder::atBlockTerminator(module_body)`,
  just use `Builder::atBlockEnd(module_body)` instead.
- you were handling ModuleTerminator: it isn't needed anymore.
- for generic code, a `Block::mayNotHaveTerminator()` may be used.

Differential Revision: https://reviews.llvm.org/D98468
2021-03-25 03:59:03 +00:00
Jacques Pienaar 5d6b4aa80d [mlir] Compare elements directly rather than creating pair first
This avoided some conversion overhead on a model in TypeUniquer when
converting from ArrayRef -> TypeRange.

Differential Revision: https://reviews.llvm.org/D99300
2021-03-24 14:39:11 -07:00
Alex Zinenko 1916b0e098 [mlir] support data layout specs on ModuleOp
ModuleOp is a natural place to provide scoped data layout information. However,
it is undesirable for ModuleOp to implement the entirety of
DataLayoutOpInterface because that would require either pushing the interface
inside the IR library instead of a separate library, or putting the default
implementation of the interface as inline functions in headers leading to
binary bloat. Instead, ModuleOp accepts an arbitrary data layout spec attribute
and has a dedicated hook to extract it, and DataLayout is modified to know
about ModuleOp particularities.

Reviewed By: herhut, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D98500
2021-03-24 15:13:38 +01:00
River Riddle 76f3c2f3f3 [mlir][Pattern] Add better support for using interfaces/traits to match root operations in rewrite patterns
To match an interface or trait, users currently have to use the `MatchAny` tag. This tag can be quite problematic for compile time for things like the canonicalizer, as the `MatchAny` patterns may get applied to  *every* operation. This revision adds better support by bucketing interface/trait patterns based on which registered operations have them registered. This means that moving forward we will only attempt to match these patterns to operations that have this interface registered. Two simplify defining patterns that match traits and interfaces, two new utility classes have been added: OpTraitRewritePattern and OpInterfaceRewritePattern.

Differential Revision: https://reviews.llvm.org/D98986
2021-03-23 14:05:33 -07:00
Alex Zinenko 5fac87d1bc [mlir] verify that operand/result_segment_sizes attributes have i32 element
This is an assumption that is made in numerous places in the code. In
particular, in the code generated by mlir-tblgen for operand/result accessors
in ops with attr-sized operand or result lists. Make sure to verify this
assumption.

Note that the operation traits are verified before running the custom op
verifier, which can expect the trait verifier to have passed, but some traits
may be verified before the AttrSizedOperand/ResultTrait and should not make
such assumptions.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D99183
2021-03-23 18:26:31 +01:00
Mehdi Amini a0c776fc94 Add a mechanism for Dialects to customize printing/parsing operations when they are unregistered
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D99007
2021-03-23 00:40:03 +00:00
thomasraoux 16947650d5 [mlir][linalg] Extend linalg vectorization to support non-identity input maps
This propagates the affine map to transfer_read op in case it is not a
minor identity map.

Differential Revision: https://reviews.llvm.org/D98523
2021-03-18 12:32:35 -07:00
River Riddle caa7038a89 [mlir][IR] Move the remaining builtin attributes to ODS.
With this revision, all builtin attributes and types will have been moved to the ODS generator.

Differential Revision: https://reviews.llvm.org/D98474
2021-03-16 16:31:53 -07:00
River Riddle 85ab413b53 [mlir][PDL] Add support for variadic operands and results in the PDL byte code
Supporting ranges in the byte code requires additional complexity, given that a range can't be easily representable as an opaque void *, as is possible with the existing bytecode value types (Attribute, Type, Value, etc.). To enable representing a range with void *, an auxillary storage is used for the actual range itself, with the pointer being passed around in the normal byte code memory. For type ranges, a TypeRange is stored. For value ranges, a ValueRange is stored. The above problem represents a majority of the complexity involved in this revision, the rest is adapting/adding byte code operations to support the changes made to the PDL interpreter in the parent revision.

After this revision, PDL will have initial end-to-end support for variadic operands/results.

Differential Revision: https://reviews.llvm.org/D95723
2021-03-16 13:20:19 -07:00
River Riddle 02c4c0d5b2 [mlir][pdl] Remove CreateNativeOp in favor of a more general ApplyNativeRewriteOp.
This has a numerous amount of benefits, given the overly clunky nature of CreateNativeOp:
* Users can now call into arbitrary rewrite functions from inside of PDL, allowing for more natural interleaving of PDL/C++ and enabling for more of the pattern to be in PDL.
* Removes the need for an additional set of C++ functions/registry/etc. The new ApplyNativeRewriteOp will use the same PDLRewriteFunction as the existing RewriteOp. This reduces the API surface area exposed to users.

This revision also introduces a new PDLResultList class. This class is used to provide results of native rewrite functions back to PDL. We introduce a new class instead of using a SmallVector to simplify the work necessary for variadics, given that ranges will require some changes to the structure of PDLValue.

Differential Revision: https://reviews.llvm.org/D95720
2021-03-16 13:20:18 -07:00
Alex Zinenko 0fb4a201c0 [mlir] fix shared-lib build fallout of e2310704d8
The patch in question broke the build with shared libraries due to
missing dependencies, one of which would have been circular between
MLIRStandard and MLIRMemRef if added. Fix this by moving more code
around and swapping the dependency direction. MLIRMemRef now depends on
MLIRStandard, but MLIRStandard does _not_ depend on MLIRMemRef.
Arguably, this is the right direction anyway since numerous libraries
depend on MLIRStandard and don't necessarily need to depend on
MLIRMemref.

Other otable changes include:
- some EDSC code is moved inline to MemRef/EDSC/Intrinsics.h because it
  creates MemRef dialect operations;
- a utility function related to shape moved to BuiltinTypes.h/cpp
  because it only realtes to shaped types and not any particular dialect
  (standard dialect is erroneously believed to contain MemRefType);
- a Python test for the standard dialect is disabled completely because
  the ops it tests moved to the new MemRef dialect, but it is not
  exposed to Python bindings, and the change for that is non-trivial.
2021-03-15 13:41:38 +01:00
Frederik Gossen 2a71f95767 [MLIR] Allow compatible shapes in `Elementwise` operations
Differential Revision: https://reviews.llvm.org/D98186
2021-03-15 09:56:20 +01:00
Sergei Grechanik fd2b08969b [mlir][Vector] Lowering of transfer_read/write to vector.load/store
This patch introduces progressive lowering patterns for rewriting
vector.transfer_read/write to vector.load/store and vector.broadcast
in certain supported cases.

Reviewed By: dcaballe, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D97822
2021-03-11 18:17:51 -08:00
River Riddle 31bb8efd69 [mlir][StorageUniquer] Properly call the destructor on non-trivially destructible storage instances
This allows for storage instances to store data that isn't uniqued in the context, or contain otherwise non-trivial logic, in the rare situations that they occur. Storage instances with trivial destructors will still have their destructor skipped. A consequence of this is that the storage instance definition must be visible from the place that registers the type.

Differential Revision: https://reviews.llvm.org/D98311
2021-03-11 11:35:32 -08:00
Tres Popp 25a20b8aa6 [mlir] Correct verifyCompatibleShapes
verifyCompatibleShapes is not transitive. Create an n-ary version and
update SameOperandShapes and SameOperandAndResultShapes traits to use
it.

Differential Revision: https://reviews.llvm.org/D98331
2021-03-11 13:04:10 +01:00
River Riddle 4e02eb8014 [mlir] Optimize the implementation of RegionDCE
The current implementation has some inefficiencies that become noticeable when running on large modules. This revision optimizes the code, and updates some out-dated idioms with newer utilities. The main components of this optimization include:

* Add an overload of Block::eraseArguments that allows for O(N) erasure of disjoint arguments.
* Don't process entry block arguments given that we don't erase them at this point.
* Don't track individual operation results, given that we don't erase them. We can just track the parent operation.

Differential Revision: https://reviews.llvm.org/D98309
2021-03-10 16:39:50 -08:00
Vladislav Vinogradov f3bf5c053b [mlir] Model MemRef memory space as Attribute
Based on the following discussion:
https://llvm.discourse.group/t/rfc-memref-memory-shape-as-attribute/2229

The goal of the change is to make memory space property to have more
expressive representation, rather then "magic" integer values.

It will allow to have more clean ASM form:

```
gpu.func @test(%arg0: memref<100xf32, "workgroup">)

// instead of

gpu.func @test(%arg0: memref<100xf32, 3>)
```

Explanation for `Attribute` choice instead of plain `string`:

* `Attribute` classes allow to use more type safe API based on RTTI.
* `Attribute` classes provides faster comparison operator based on
  pointer comparison in contrast to generic string comparison.
* `Attribute` allows to store more complex things, like structs or dictionaries.
  It will allows to have more complex memory space hierarchy.

This commit preserve old integer-based API and implements it on top
of the new one.

Depends on D97476

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D96145
2021-03-10 12:57:27 +03:00
River Riddle a776ecb6c2 [mlir][IR] Add an Operation::eraseOperands that supports batch erasure
This method allows for removing multiple disjoint operands at once, reducing the need to erase operands individually (which results in shifting the operand list).

Differential Revision: https://reviews.llvm.org/D98290
2021-03-09 15:07:53 -08:00
River Riddle 4a7aed4ee7 [mlir][IR] Add a new SymbolUserMap class
This class provides efficient implementations of symbol queries related to uses, such as collecting the users of a symbol, replacing all uses, etc. This provides similar benefits to use related queries, as SymbolTableCollection did for lookup queries.

Differential Revision: https://reviews.llvm.org/D98071
2021-03-09 15:07:52 -08:00
River Riddle 0d01dfbc37 [mlir][IR][NFC] Move the remaining builtin types to ODS
This will allow for removing the duplicated type documentation from LangRef and instead link to the builtin dialect documentation.

Differential Revision: https://reviews.llvm.org/D98093
2021-03-08 14:32:40 -08:00
River Riddle a4bb667d83 [mlir][IR][NFC] Define the Location classes in ODS instead of C++
This also removes the need for LocationDetail.h.

Differential Revision: https://reviews.llvm.org/D98092
2021-03-08 14:32:40 -08:00
Diego Caballero 2de6dbda66 [mlir] Add 'Skip' result to Operation visitor
This patch is a follow-up on D97217. It adds a new 'Skip' result to the Operation visitor
so that a callback can stop the ongoing visit of an operation/block/region and
continue visiting the next one without fully interrupting the walk. Skipping is
needed to be able to erase an operation/block in pre-order and do not continue
visiting the internals of that operation/block.

Related to the skipping mechanism, the patch also introduces the following changes:
 * Added new TestIRVisitors pass with basic testing for the IR visitors.
 * Fixed missing early increment ranges in visitor implementation.
 * Updated documentation of walk methods to include erasure information and walk
   order information.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D97820
2021-03-06 00:02:20 +02:00
Diego Caballero 71a86245ca [mlir] Extend Operation visitor with pre-order traversal
This patch extends the Region, Block and Operation visitors to also support pre-order walks.
We introduce a new template argument that dictates the walk order (only pre-order and
post-order are supported for now). The default order for Regions, Blocks and Operations is
post-order. Mixed orders (e.g., Region/Block pre-order + Operation post-order) could easily
be implemented, as shown in NumberOfExecutions.cpp.

Reviewed By: rriddle, frgossen, bondhugula

Differential Revision: https://reviews.llvm.org/D97217
2021-03-06 00:02:20 +02:00
River Riddle f175ba4a54 [mlir][AsmPrinter] Don't use string comparison when filtering list attributes
In .mlir modules with larges amounts of attributes, e.g. a function with a larger number of argument attributes, the string comparison filtering greatly affects compile time. This revision switches to using a SmallDenseSet in these situations, resulting in over a 10x speed up in some situations.

Differential Revision: https://reviews.llvm.org/D97980
2021-03-05 12:47:05 -08:00
River Riddle 2f37cdd569 [mlir][IR][NFC] Move a majority of the builtin attributes to ODS
Now that attributes can be generated using ODS, we can move the builtin attributes as well. This revision removes a majority of the builtin attributes with a few left for followup revisions. The attributes moved to ODS in this revision are: AffineMapAttr, ArrayAttr, DictionaryAttr, IntegerSetAttr, StringAttr, SymbolRefAttr, TypeAttr, and UnitAttr.

Differential Revision: https://reviews.llvm.org/D97591
2021-03-04 13:04:06 -08:00
River Riddle 3dfa86149e [mlir][IR] Refactor the internal implementation of Value
The current implementation of Value involves a pointer int pair with several different kinds of owners, i.e. BlockArgumentImpl*, Operation *, TrailingOpResult*. This design arose from the desire to save memory overhead for operations that have a very small number of results (generally 0-2). There are, unfortunately, many problematic aspects of the current implementation that make Values difficult to work with or just inefficient.

Operation result types are stored as a separate array on the Operation. This is very inefficient for many reasons: we use TupleType for multiple results, which can lead to huge amounts of memory usage if multi-result operations change types frequently(they do). It also means that simple methods like Value::getType/Value::setType now require complex logic to get to the desired type.

Value only has one pointer bit free, severely limiting the ability to use it in things like PointerUnion/PointerIntPair. Given that we store the kind of a Value along with the "owner" pointer, we only leave one bit free for users of Value. This creates situations where we end up nesting PointerUnions to be able to use Value in one.

As noted above, most of the methods in Value need to branch on at least 3 different cases which is both inefficient, possibly error prone, and verbose. The current storage of results also creates problems for utilities like ValueRange/TypeRange, which want to efficiently store base pointers to ranges (of which Operation* isn't really useful as one).

This revision greatly simplifies the implementation of Value by the introduction of a new ValueImpl class. This class contains all of the state shared between all of the various derived value classes; i.e. the use list, the type, and the kind. This shared implementation class provides several large benefits:

* Most of the methods on value are now branchless, and often one-liners.

* The "kind" of the value is now stored in ValueImpl instead of Value
This frees up all of Value's pointer bits, allowing for users to take full advantage of PointerUnion/PointerIntPair/etc. It also allows for storing more operation results as "inline", 6 now instead of 2, freeing up 1 word per new inline result.

* Operation result types are now stored in the result, instead of a side array
This drops the size of zero-result operations by 1 word. It also removes the memory crushing use of TupleType for operations results (which could lead up to hundreds of megabytes of "dead" TupleTypes in the context). This also allowed restructured ValueRange, making it simpler and one word smaller.

This revision does come with two conceptual downsides:
* Operation::getResultTypes no longer returns an ArrayRef<Type>
This conceptually makes some usages slower, as the iterator increment is slightly more complex.
* OpResult::getOwner is slightly more expensive, as it now requires a little bit of arithmetic

From profiling, neither of the conceptual downsides have resulted in any perceivable hit to performance. Given the advantages of the new design, most compiles are slightly faster.

Differential Revision: https://reviews.llvm.org/D97804
2021-03-03 14:33:37 -08:00
Frederik Gossen bcc9b371e4 Split `ElementwiseMappable` trait into four more precise traits.
Some elementwise operations are not scalarizable, vectorizable, or tensorizable.
Split `ElementwiseMappable` trait into the following, more precise traits.
  - `Elementwise`
  - `Scalarizable`
  - `Vectorizable`
  - `Tensorizable`
This allows for reuse of `Elementwise` in dialects like HLO.

Differential Revision: https://reviews.llvm.org/D97674
2021-03-02 15:31:19 +01:00
Vladislav Vinogradov 37eca08e5b [mlir][NFC] Rename `MemRefType::getMemorySpace` to `getMemorySpaceAsInt`
Just a pure method renaming.

It is a preparation step for replacing "memory space as raw integer"
with more generic "memory space as attribute", which will be done in
separate commit.

The `MemRefType::getMemorySpace` method will return `Attribute` and
become the main API, while `getMemorySpaceAsInt` will be declared as
deprecated and will be replaced in all in-tree dialects (also in separate
commits).

Reviewed By: mehdi_amini, rriddle

Differential Revision: https://reviews.llvm.org/D97476
2021-03-02 11:08:54 +03:00
Jacques Pienaar 87e05eb03b Revert "Remove use of tuple for multiresult type storage"
This reverts commit 08f0764ff5.
2021-03-01 10:39:41 -08:00
Jacques Pienaar 08f0764ff5 Remove use of tuple for multiresult type storage
Move the results in line with the op instead. This results in each
operation having its own types recorded vs single tuple type, but comes
at benefit that every mutation doesn't incurs uniquing. Ran into cases
where updating result type of operation led to very large memory usage.

Differential Revision: https://reviews.llvm.org/D97652
2021-03-01 09:30:24 -08:00
Mehdi Amini 014575932f Fix Block::eraseArguments: keep track the first removed element while removing
Not only this is likely more efficient than BitVector::find_first(), but
also if the BitVector is empty find_first() returns -1, which
llvm::drop_begin isn't robust against.
2021-02-27 19:18:09 +00:00
Mehdi Amini 7b06786de2 Fix Block::eraseArguments to properly update the cached positions
This is fixing correctness and ASAN failure post-ee90bb3486948.
2021-02-27 19:04:12 +00:00
Mehdi Amini ee90bb3486 Store (cache) the Argument number (index in the argument list) inside the BlockArgumentImpl
This avoids linear search in BlockArgument::getArgNumber().

Differential Revision: https://reviews.llvm.org/D97596
2021-02-27 17:21:08 +00:00
River Riddle e6260ad043 [mlir] Simplify various pieces of code now that Identifier has access to the Context/Dialect
This also exposed a bug in Dialect loading where it was not correctly identifying identifiers that had the dialect namespace as a prefix.

Differential Revision: https://reviews.llvm.org/D97431
2021-02-26 18:00:05 -08:00
Christian Sigg 0b05908feb [mlir] Remove some rarely used OpState members and use Operation members instead.
Skipping the deprecation dance here.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D97494
2021-02-26 08:37:11 +01:00
Christian Sigg 8c074cb0b7 [mlir] Mark OpState::getAttrs() deprecated.
Fix call sites.

The method will be removed 2 weeks later.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D97464
2021-02-25 20:54:42 +01:00
River Riddle 65a3197a8f [mlir] Refactor InterfaceMap to use a sorted vector of interfaces, as opposed to a DenseMap
A majority of operations have a very small number of interfaces, which means that the cost of using a hash map is generally larger for interface lookups than just a binary search. In the future when there are a number of operations with large amounts of interfaces, we can switch to a hybrid approach that optimizes lookups based on the number of interfaces. For now, however, a binary search is the best approach.

This dropped compile time on a largish TF MLIR module by 20%(half a second).

Differential Revision: https://reviews.llvm.org/D96085
2021-02-23 14:36:45 -08:00
River Riddle 72d5afa4ac [mlir] Add a new debug action framework.
This revision adds the infrastructure for `Debug Actions`. This is a DEBUG only
API that allows for external entities to control various aspects of compiler
execution. This is conceptually similar to something like DebugCounters in LLVM, but at a lower level. This framework doesn't make any assumptions about how the higher level driver is controlling the execution, it merely provides a framework for connecting the two together. This means that on top of DebugCounter functionality, we could also provide more interesting drivers such as interactive execution. A high level overview of the workflow surrounding debug actions is
shown below:

*   Compiler developer defines an `action` that is taken by the a pass,
    transformation, utility that they are developing.
*   Depending on the needs, the developer dispatches various queries, pertaining
    to this action, to an `action manager` that will provide an answer as to
    what behavior the action should do.
*   An external entity registers an `action handler` with the action manager,
    and provides the logic to resolve queries on actions.

The exact definition of an `external entity` is left opaque, to allow for more
interesting handlers.

This framework was proposed here: https://llvm.discourse.group/t/rfc-debug-actions-in-mlir-debug-counters-for-the-modern-world

Differential Revision: https://reviews.llvm.org/D84986
2021-02-23 00:52:17 -08:00
River Riddle 06e25d5645 [mlir][IR] Refactor the `getChecked` and `verifyConstructionInvariants` methods on Attributes/Types
`verifyConstructionInvariants` is intended to allow for verifying the invariants of an attribute/type on construction, and `getChecked` is intended to enable more graceful error handling aside from an assert. There are a few problems with the current implementation of these methods:
* `verifyConstructionInvariants` requires an mlir::Location for emitting errors, which is prohibitively costly in the situations that would most likely use them, e.g. the parser.
This creates an unfortunate code duplication between the verifier code and the parser code, given that the parser operates on llvm::SMLoc and it is an undesirable overhead to pre-emptively convert from that to an mlir::Location.
* `getChecked` effectively requires duplicating the definition of the `get` method, creating a quite clunky workflow due to the subtle different in its signature.

This revision aims to talk the above problems by refactoring the implementation to use a callback for error emission. Using a callback allows for deferring the costly part of error emission until it is actually necessary.

Due to the necessary signature change in each instance of these methods, this revision also takes this opportunity to cleanup the definition of these methods by:
* restructuring the signature of `getChecked` such that it can be generated from the same code block as the `get` method.
* renaming `verifyConstructionInvariants` to `verify` to match the naming scheme of the rest of the compiler.

Differential Revision: https://reviews.llvm.org/D97100
2021-02-22 17:37:49 -08:00
Jacques Pienaar 381a65fa06 [mlir] Add clone method to ShapedType
Allow clients to create a new ShapedType of the same "container" type
but with different element or shape. First use case is when refining
shape during shape inference without needing to consider which
ShapedType is being refined.

Differential Revision: https://reviews.llvm.org/D96682
2021-02-15 11:04:16 -08:00
Alex Zinenko 34ea608a47 [mlir] Support repeated delayed registration of dialect interfaces
Dialects themselves do not support repeated addition of interfaces with the
same TypeID. However, in case of delayed registration, the registry may contain
such an interface, or have the same interface registered several times due to,
e.g., dependencies. Make sure we delayed registration does not attempt to add
an interface with the same TypeID more than once.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D96606
2021-02-15 10:46:26 +01:00
Aart Bik 5f022ad6ed [mlir] detect integer overflow in debug mode
Rationale:
This computation failed ASAN for the following input
(integer overflow during 4032000000000000000 * 100):

  tensor<100x200x300x400x500x600x700x800xf32>

This change adds a simple overflow detection during
debug mode (which we run more regularly than ASAN).
Arguably this is an unrealistic tensor input, but
in the context of sparse tensors, we may start to
see cases like this.

Bug:
https://bugs.llvm.org/show_bug.cgi?id=49136

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D96530
2021-02-11 18:20:40 -08:00
Nicolas Vasilache 5bc4f8846c s[mlir] Tighten computation of inferred SubView result type.
The AffineMap in the MemRef inferred by SubViewOp may have uncompressed symbols which result in type mismatch on otherwise unused symbols. Make the computation of the AffineMap compress those unused symbols which results in better canonical types.
Additionally, improve the error message to report which inferred type was expected.

Differential Revision: https://reviews.llvm.org/D96551
2021-02-11 22:38:16 +00:00
Alex Zinenko 2996a8d675 [mlir] avoid exposing mutable DialectRegistry from MLIRContext
MLIRContext allows its users to access directly to the DialectRegistry it
contains. While sometimes useful for registering additional dialects on an
already existing context, this breaks the encapsulation by essentially giving
raw accesses to a part of the context's internal state. Remove this mutable
access and instead provide a method to append a given DialectRegistry to the
one already contained in the context. Also provide a shortcut mechanism to
construct a context from an already existing registry, which seems to be a
common use case in the wild. Keep read-only access to the registry contained in
the context in case it needs to be copied or used for constructing another
context.

With this change, DialectRegistry is no longer concerned with loading the
dialects and deciding whether to invoke delayed interface registration. Loading
is concentrated in the MLIRContext, and the functionality of the registry
better reflects its name.

Depends On D96137

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D96331
2021-02-10 12:07:34 +01:00
Alex Zinenko 3da51522fb [mlir] enable delayed registration of dialect interfaces
This introduces a mechanism to register interfaces for a dialect without making
the dialect itself depend on the interface. The registration request happens on
DialectRegistry and, if the dialect has not been loaded yet, the actual
registration is delayed until the dialect is loaded. It requires
DialectRegistry to become aware of the context that contains it and the context
to expose methods for querying if a dialect is loaded.

This mechanism will enable a simple extension mechanism for dialects that can
have interfaces defined outside of the dialect code. It is particularly helpful
for, e.g., translation to LLVM IR where we don't want the dialect itself to
depend on LLVM IR libraries.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D96137
2021-02-10 12:07:32 +01:00
River Riddle fe7c0d90b2 [mlir][IR] Remove the concept of `OperationProperties`
These properties were useful for a few things before traits had a better integration story, but don't really carry their weight well these days. Most of these properties are already checked via traits in most of the code. It is better to align the system around traits, and improve the performance/cost of traits in general.

Differential Revision: https://reviews.llvm.org/D96088
2021-02-09 12:00:15 -08:00
Tres Popp c2c83e97c3 Revert "Revert "Reorder MLIRContext location in BuiltinAttributes.h""
This reverts commit 511dd4f438 along with
a couple fixes.

Original message:
Now the context is the first, rather than the last input.

This better matches the rest of the infrastructure and makes
it easier to move these types to being declaratively specified.

Phabricator: https://reviews.llvm.org/D96111
2021-02-08 10:39:58 +01:00
Tres Popp 511dd4f438 Revert "Reorder MLIRContext location in BuiltinAttributes.h"
This reverts commit 7827753f98.
2021-02-08 09:32:42 +01:00
Tres Popp 7827753f98 Reorder MLIRContext location in BuiltinAttributes.h
Now the context is the first, rather than the last input.

This better matches the rest of the infrastructure and makes
it easier to move these types to being declaratively specified.

Differential Revision: https://reviews.llvm.org/D96111
2021-02-08 09:28:09 +01:00
Vladislav Vinogradov f349abc265 [mlir] Add `const` qualifiers to `AffineMap` methods
The `AffineMap` class follows the same semantic as Type and Attribute.
It is immutable object, so it make sence to mark its methods as const.
Also part of its API is already marked as const, this change just make the API consistent.

Reviewed By: ftynse, bondhugula

Differential Revision: https://reviews.llvm.org/D96026
2021-02-05 15:22:16 +03:00
River Riddle e21adfa32d [mlir] Mark LogicalResult as LLVM_NODISCARD
This makes ignoring a result explicit by the user, and helps to prevent accidental errors with dropped results. Marking LogicalResult as no discard was always the intention from the beginning, but got lost along the way.

Differential Revision: https://reviews.llvm.org/D95841
2021-02-04 15:10:10 -08:00
Nicolas Vasilache f4ac9f0334 [mlir][Linalg] Drop SliceOp
This op is subsumed by rank-reducing SubViewOp and has become useless.

Differential revision: https://reviews.llvm.org/D95317
2021-02-04 11:22:01 +00:00
River Riddle ec10f06609 [mlir][Pattern] Create a new IRRewriter class to enable sharing code with pattern rewrites
This revision adds two new classes, RewriterBase and IRRewriter. RewriterBase is a new shared base class between IRRewriter and PatternRewriter. PatternRewriter will continue to be the base class used to perform rewrites within a rewrite pattern. IRRewriter on the other hand, is a new class that allows for tracking IR rewrites from outside of a rewrite pattern. In this revision all of the old API from PatternRewriter is moved to RewriterBase, but the distinction between IRRewriter and PatternRewriter is kept on the chance that a necessary API divergence happens in the future.

Currently if you want to have some utility that transforms a piece of IR and share it between pattern and non-pattern code, you have to duplicate it. This revision enables the creation of utilities that can be invoked from rewrite patterns and normal transformation code:

```c++
void someSharedUtility(RewriterBase &rewriter, ...) {
  // Some interesting IR mutation here.
}

// Some RewritePattern
LogicalResult MyPattern::matchAndRewrite(Operation *op, PatternRewriter &rewriter) {
  ...
  someSharedUtility(rewriter, ...);
  ...
}

// Some Pass
void MyPass::runOnOperation() {
  ...
  IRRewriter rewriter(...);
  someSharedUtility(rewriter, ...);
}
```

Differential Revision: https://reviews.llvm.org/D94638
2021-02-02 12:04:51 -08:00
Mehdi Amini 32ef6d89f4 Avoid string comparisons on the fast path of MLIR Identifier lookup (NFC)
Differential Revision: https://reviews.llvm.org/D95770
2021-02-01 21:05:07 +00:00
Jacques Pienaar 2eb5f34542 Fix omitted kw in type alias printer
* Fixing missing `type` keyword in alias print
* Add test for large tuple type alias & rerun output to verify printed
form can be parsed (which caught the above).
2021-01-31 14:06:58 -08:00
Jacques Pienaar 4d9336923e Use type alias for large tuples
Tuples can occupy quite a lot of space, instead of printing out tuple type
everywhere, just use the type alias if larger (arbitrarily chose a bound for
now).

Differential Revision: https://reviews.llvm.org/D95707
2021-01-29 17:42:23 -08:00
karimnosseir 0af2527536 Update ElementsAttr::isValidIndex to handle ElementsAttr with a scalar. Scalar will have rank 0.
Update ElementsAttr::isValidIndex to handle ElementsAttr with a scalar. Scalar will have rank 0.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D95663
2021-01-29 16:56:00 -08:00
Mehdi Amini e9dc94291e Introduce a new DialectIdentifier structure, extending Identifier with a Dialect information
This class is looking up a dialect prefix on the identifier on initialization
and keeping a pointer to the Dialect when found.

The NamedAttribute key is now a DialectIdentifier.

Reviewed By: rriddle, jpienaar

Differential Revision: https://reviews.llvm.org/D95418
2021-01-29 00:05:36 +00:00
Jacques Pienaar acaf85f700 Add convenience function for checking arrays of shapes compatible.
Expand existing one to handle the common case for verifying compatible
is existing and inferred. This considers arrays equivalent if they they
have the same size and pairwise compatible elements.
2021-01-28 10:47:08 -08:00
Nicolas Vasilache 7e6fe5c48a [mlir] Fix subview verifier.
The subview verifier in the rank-reduced case is plainly skipping verification
when the resulting type is a memref with empty affine map. This is generally incorrect.

Instead, form the actual expected rank-reduced MemRefType that takes into account the projections of 1's dimensions. Then, check the canonicalized expected rank-reduced type against the canonicalized candidate type.

Differential Revision: https://reviews.llvm.org/D95316
2021-01-28 13:55:39 +00:00
River Riddle 02bc4c95f0 [mlir][PassManager] Only reinitialize the pass manager if the context registry changes
This prevents needless reinitialization for clients that want to reuse a pass manager multiple times. A new `getRegisryHash` function is exposed by the context to give a rough indicator of when the context registry has changed.

Differential Revision: https://reviews.llvm.org/D95493
2021-01-27 17:41:51 -08:00
Jacques Pienaar 73de3df1d2 Add more explicit assert for failures
Differential Revision: https://reviews.llvm.org/D95201
2021-01-22 11:45:25 -08:00
mikeurbach 0a7a1ac73d [mlir] Support FuncOpSignatureConversion for more FunctionLike ops.
This extracts the implementation of getType, setType, and getBody from
FunctionSupport.h into the mlir::impl namespace and defines them
generically in FunctionSupport.cpp. This allows them to be used
elsewhere for any FunctionLike ops that use FunctionType for their
type signature.

Using the new helpers, FuncOpSignatureConversion is generalized to
work with all such FunctionLike ops. Convenience helpers are added to
configure the pattern for a given concrete FunctionLike op type.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D95021
2021-01-21 18:35:09 -07:00
Christian Sigg 8827e07aaf Remove deprecated methods from OpState.
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D95123
2021-01-21 21:29:08 +01:00
River Riddle c78219f644 [mlir] Add a new builtin `unrealized_conversion_cast` operation
An `unrealized_conversion_cast` operation represents an unrealized conversion
from one set of types to another, that is used to enable the inter-mixing of
different type systems. This operation should not be attributed any special
representational or execution semantics, and is generally only intended to be
used to satisfy the temporary intermixing of type systems during the conversion
of one type system to another.

This operation was discussed in the following RFC(and ODM):

https://llvm.discourse.group/t/open-meeting-1-14-dialect-conversion-and-type-conversion-the-question-of-cast-operations/

Differential Revision: https://reviews.llvm.org/D94832
2021-01-20 16:28:18 -08:00
River Riddle 6ccf2d62b4 [mlir] Add an interface for Cast-Like operations
A cast-like operation is one that converts from a set of input types to a set of output types. The arity of the inputs may be from 0-N, whereas the arity of the outputs may be anything from 1-N. Cast-like operations are removable in cases where they produce a "no-op", i.e when the input types and output types match 1-1.

Differential Revision: https://reviews.llvm.org/D94831
2021-01-20 16:28:17 -08:00
Nicolas Vasilache 93a873dfc9 [mlir][Affine] Revisit and simplify composeAffineMapAndOperands.
In prehistorical times, AffineApplyOp was allowed to produce multiple values.
This allowed the creation of intricate SSA use-def chains.
AffineApplyNormalizer was originally introduced as a means of reusing the AffineMap::compose method to write SSA use-def chains.
Unfortunately, symbols that were produced by an AffineApplyOp needed to be promoted to dims and reordered for the mathematical composition to be valid.

Since then, single result AffineApplyOp became the law of the land but the original assumptions were not revisited.

This revision revisits these assumptions and retires AffineApplyNormalizer.

Differential Revision: https://reviews.llvm.org/D94920
2021-01-19 13:52:07 +00:00
River Riddle 2a27a9819a [mlir][AsmPrinter] Properly escape strings when printing locations
This fixes errors when location strings contains newlines, or other non-ascii characters.

Differential Revision: https://reviews.llvm.org/D94847
2021-01-15 17:14:57 -08:00
Valentin Clement cf0173de69 [mlir] Add better support for f80 and f128
Add builtin f80 and f128 following @schweitz proposition
https://llvm.discourse.group/t/rfc-adding-better-support-for-higher-precision-floating-point/2526/5

Reviewed By: ftynse, rriddle

Differential Revision: https://reviews.llvm.org/D94737
2021-01-15 10:29:48 -05:00
River Riddle c8fb6ee341 [mlir][PatternRewriter] Add a new hook to selectively replace uses of an operation
This revision adds a new `replaceOpWithIf` hook that replaces uses of an operation that satisfy a given functor. If all uses are replaced, the operation gets erased in a similar manner to `replaceOp`. DialectConversion support will be added in a followup as this requires adjusting how replacements are tracked there.

Differential Revision: https://reviews.llvm.org/D94632
2021-01-14 11:58:21 -08:00
Rahul Joshi 67a339e968 [MLIR] Disallow `sym_visibility`, `sym_name` and `type` attributes in the parsed attribute dictionary.
Differential Revision: https://reviews.llvm.org/D94200
2021-01-12 09:11:02 -08:00
River Riddle d79642b3db [mlir][IR][NFC] Move the definitions of Complex/Function/Integer/Opaque/TupleType to ODS
The type tablegen backend now has enough support to represent these types well enough, so we can now move them to be declaratively defined.

Differential Revision: https://reviews.llvm.org/D94275
2021-01-11 12:06:22 -08:00
Kazuaki Ishizaki f88fab5006 [mlir] NFC: fix trivial typos
fix typo under include and lib directories

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D94220
2021-01-08 02:10:12 +09:00
Christian Sigg c3529a5b08 [mlir] Mark methods from mlir::OpState that just forward to mlir::Operation as deprecated.
The functions will be removed by January 20th.

All call sites within MLIR have been converted in previous changes.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D94191
2021-01-07 09:08:47 +01:00
Chris Lattner 7510c1152f Update for review feedback: Inline var declaration and expand names.
Depends on D93908.

Differential Revision: https://reviews.llvm.org/D94208
2021-01-06 20:59:24 -08:00
Chris Lattner 25f23a6039 [AsmPrinter] Make OpAsmPrinter::printFunctionalType be resilient to null values.
A previous patch made Value::getType() be resilient to null values which was
considered to be too sweeping.  This is a more targeted change which requires
deabstracting some templates.

A middle ground would be to make ValueTypeIterator be tolerant to null values.

Differential Revision: https://reviews.llvm.org/D93908
2021-01-06 20:59:24 -08:00
Chengji Yao 3bcca6b12d [MLIR] Fix affine_map compose with multi-symbols
Fix bug: https://bugs.llvm.org/show_bug.cgi?id=46845

Differential Revision: https://reviews.llvm.org/D93831
2021-01-02 06:57:16 +05:30
Chris Lattner 87c032f7b4 [IR] Make Value::getType() work better with invalid IR.
The asmprinter would crash when dumping IR objects that had their
operands dropped.  With this change, we now get this output, which
makes op->dump() style debugging more useful.

%5 = "firrtl.eq"(<<NULL>>, <<NULL>>) : (<<NULL TYPE>>, <<NULL TYPE>>) -> !firrtl.uint<1>

Previously the asmprinter would crash getting the types of the null operands.

Differential Revision: https://reviews.llvm.org/D93869
2020-12-28 12:37:01 -08:00
River Riddle fc5cf50e89 [mlir] Remove the MutableDictionaryAttr class
This class used to serve a few useful purposes:
* Allowed containing a null DictionaryAttr
* Provided some simple mutable API around a DictionaryAttr

The first of which is no longer an issue now that there is much better caching support for attributes in general, and a cache in the context for empty dictionaries. The second results in more trouble than it's worth because it mutates the internal dictionary on every action, leading to a potentially large number of dictionary copies. NamedAttrList is a much better alternative for the second use case, and should be modified as needed to better fit it's usage as a DictionaryAttrBuilder.

Differential Revision: https://reviews.llvm.org/D93442
2020-12-17 17:18:42 -08:00
Sean Silva 129d6e554e [mlir] Move `std.tensor_cast` -> `tensor.cast`.
This is almost entirely mechanical.

Differential Revision: https://reviews.llvm.org/D93357
2020-12-17 16:06:56 -08:00
River Riddle 1b97cdf885 [mlir][IR][NFC] Move context/location parameters of builtin Type::get methods to the start of the parameter list
This better matches the rest of the infrastructure, is much simpler, and makes it easier to move these types to being declaratively specified.

Differential Revision: https://reviews.llvm.org/D93432
2020-12-17 13:01:36 -08:00
Mehdi Amini c21ee1a942 Improve the verifier diagnostic on dominance error
Address PR47937

Differential Revision: https://reviews.llvm.org/D93361
2020-12-16 22:05:17 +00:00
Tres Popp f43e67cc6c [mlir] Allow SymbolTable to update existing symbols
Previous behavior would fail if inserting an operation that already
existed. Now SymbolTable::insert can also be used as a way to make a
symbol's name unique even after insertion.

Further TODOs have been left over naming and consistent behavior
considerations.

Differential Revision: https://reviews.llvm.org/D93349
2020-12-16 00:44:40 +01:00
River Riddle 95019de8a1 [mlir][IR] Define the singleton builtin types in ODS instead of C++
This exposes several issues with the current generation that this revision also fixes.
 * TypeDef now allows specifying the base class to use when generating.
 * TypeDef now inherits from DialectType, which allows for using it as a TypeConstraint
 * Parser/Printers are now no longer generated in the header(removing duplicate symbols), and are now only generated when necessary.
    - Now that generatedTypeParser/Printer are only generated in the definition file,
      existing users will need to manually expose this functionality when necessary.
 * ::get() is no longer generated for singleton types, because it isn't necessary.

Differential Revision: https://reviews.llvm.org/D93270
2020-12-15 13:42:19 -08:00
River Riddle c234b65cef [mlir][OpFormat] Add support for emitting newlines from the custom format of an operation
This revision adds a new `printNewline` hook to OpAsmPrinter that allows for printing a newline within the custom format of an operation, that is then indented to the start of the operation. Support for the declarative assembly format is also added, in the form of a `\n` literal.

Differential Revision: https://reviews.llvm.org/D93151
2020-12-14 12:00:43 -08:00