Commit Graph

1341 Commits

Author SHA1 Message Date
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
Nicolas Vasilache 7310501f74 [mlir][ArmNeon][RFC] Add a Neon dialect
This revision starts an Arm-specific ArmNeon dialect discussed in the [discourse RFC thread](https://llvm.discourse.group/t/rfc-vector-dialects-neon-and-sve/2284).

Differential Revision: https://reviews.llvm.org/D92171
2020-12-11 13:49:40 +00:00
River Riddle 47364f95e8 [mlir][IR] Move the storage for results to before the Operation instead of after.
Trailing objects are really nice for storing additional data inline with the main class, and is something that we heavily take advantage of for Operation(and many other classes). To get the address of the inline data you need to compute the address by doing some pointer arithmetic taking into account any objects stored before the object you want to access. Most classes keep the count of the number of objects, so this is relatively cheap to compute. This is not the case for results though, which have two different types(inline and trailing) that are not necessarily as cheap to compute as the count for other objects. This revision moves the storage for results to before the operation and stores them in reverse order. This allows for getting results to still be very fast given that they are never iterated directly in order, and also greatly improves the speed when accessing the other trailing objects of an operation(operands/regions/blocks/etc).

This reduced compile time when compiling a decently sized mlir module by about ~400ms, or 2.17s -> 1.76s.

Differential Revision: https://reviews.llvm.org/D92687
2020-12-04 21:01:42 -08:00
Rahul Joshi fe7fdcac87 [MLIR] Fix parseFunctionLikeOp() to fail parsing empty regions
- Change parseOptionalRegion to return an OptionalParseResult.
- Change parseFunctionLikeOp() to fail parsing if the function body was parsed but was
  empty.
- See https://llvm.discourse.group/t/funcop-parsing-bug/2164

Differential Revision: https://reviews.llvm.org/D91886
2020-12-04 09:09:59 -08:00
River Riddle c7cae0e4fa [mlir][Attributes][NFC] Move all builtin Attribute classes to BuiltinAttributes.h
This mirrors the file structure of Types.

Differential Revision: https://reviews.llvm.org/D92499
2020-12-03 18:02:11 -08:00
River Riddle 09f7a55fad [mlir][Types][NFC] Move all of the builtin Type classes to BuiltinTypes.h
This is part of a larger refactoring the better congregates the builtin structures under the BuiltinDialect. This also removes the problematic "standard" naming that clashes with the "standard" dialect, which is not defined within IR/. A temporary forward is placed in StandardTypes.h to allow time for downstream users to replaced references.

Differential Revision: https://reviews.llvm.org/D92435
2020-12-03 18:02:10 -08:00
River Riddle 672cc75cce [mlir][IR] Remove references to BuiltinOps from IR/
There isn't a good reason for anything within IR to specifically reference any of the builtin operations. The only place that had a good reason in the past was AsmPrinter, but the behavior there doesn't need to hardcode ModuleOp anymore.

Differential Revision: https://reviews.llvm.org/D92448
2020-12-03 15:47:01 -08:00
Uday Bondhugula b276bf5a57 [MLIR][NFC] Fix mix up between dialect attribute values and names
Clear up documentation on dialect attribute values. Fix/improve
ModuleOp verifier error message on dialect prefixed attribute names.
Additional discussion is here:
https://llvm.discourse.group/t/moduleop-attributes/2325

Differential Revision: https://reviews.llvm.org/D92502
2020-12-03 02:34:15 +05:30
Christian Sigg c4a0405902 Add `Operation* OpState::operator->()` to provide more convenient access to members of Operation.
Given that OpState already implicit converts to Operator*, this seems reasonable.

The alternative would be to add more functions to OpState which forward to Operation.

Reviewed By: rriddle, ftynse

Differential Revision: https://reviews.llvm.org/D92266
2020-12-02 15:46:20 +01:00
River Riddle abfd1a8b3b [mlir][PDL] Add support for PDL bytecode and expose PDL support to OwningRewritePatternList
PDL patterns are now supported via a new `PDLPatternModule` class. This class contains a ModuleOp with the pdl::PatternOp operations representing the patterns, as well as a collection of registered C++ functions for native constraints/creations/rewrites/etc. that may be invoked via the pdl patterns. Instances of this class are added to an OwningRewritePatternList in the same fashion as C++ RewritePatterns, i.e. via the `insert` method.

The PDL bytecode is an in-memory representation of the PDL interpreter dialect that can be efficiently interpreted/executed. The representation of the bytecode boils down to a code array(for opcodes/memory locations/etc) and a memory buffer(for storing attributes/operations/values/any other data necessary). The bytecode operations are effectively a 1-1 mapping to the PDLInterp dialect operations, with a few exceptions in cases where the in-memory representation of the bytecode can be more efficient than the MLIR representation. For example, a generic `AreEqual` bytecode op can be used to represent AreEqualOp, CheckAttributeOp, and CheckTypeOp.

The execution of the bytecode is split into two phases: matching and rewriting. When matching, all of the matched patterns are collected to avoid the overhead of re-running parts of the matcher. These matched patterns are then considered alongside the native C++ patterns, which rewrite immediately in-place via `RewritePattern::matchAndRewrite`,  for the given root operation. When a PDL pattern is matched and has the highest benefit, it is passed back to the bytecode to execute its rewriter.

Differential Revision: https://reviews.llvm.org/D89107
2020-12-01 15:05:50 -08:00
Tamas Berghammer e4c74fd9dd Don't elide splat attributes during printing
A splat attribute have a single element during printing so we should
treat it as such when we decide if we elide it or not based on the flag
intended to elide large attributes.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D92165
2020-11-27 14:42:26 +00:00
Haruki Imai fbfbfa5c71 [mlir] Support big-endian systems in DenseElementsAttr (multiple word)
D78076 supports big endian in DenseElementsAttr, but does not work when
APInt has multiple words(the number of bits > 64). This patch updates
D78076 to support it.
This patch removed the fix in D78076 and re-implemented to support multiple words.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D80272
2020-11-20 05:09:33 +00:00
Alex Zinenko 9bb5bff570 [mlir] Add an assertion on creating an Operation with null result types
Null types are commonly used as an error marker. Catch them in the constructor
of Operation if they are present in the result type list, as otherwise this
could lead to further surprising behavior when querying op result types.

Fix AsyncToLLVM and StandardToLLVM that were using null types when constructing
operations.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D91770
2020-11-19 22:28:38 +01:00
River Riddle 65fcddff24 [mlir][BuiltinDialect] Resolve comments from D91571
* Move ops to a BuiltinOps.h
* Add file comments
2020-11-19 11:12:49 -08:00
daquexian 6bfb4120ea set the alignment of mlir::AttributeStorage to 64 bit explicitly to fix 32 bit platform
On some platform (like WebAssembly), alignof(mlir::AttributeStorage) is 4 instead of 8. As a result, it makes the program crashes since PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable is 3.

So I explicitly set the alignment of mlir::AttributeStoarge to 64 bits, and set PointerLikeTypeTraits<mlir::Attribute>::NumLowBitsAvailable according to it.

I also fixed an another related error (alignof(NamedAttribute) -> alignof(DictionaryAttributeStorage)) based on reviewer's comments.

Reviewed By: dblaikie, rriddle

Differential Revision: https://reviews.llvm.org/D91062
2020-11-17 17:51:53 -08:00
River Riddle 73ca690df8 [mlir][NFC] Remove references to Module.h and Function.h
These includes have been deprecated in favor of BuiltinDialect.h, which contains the definitions of ModuleOp and FuncOp.

Differential Revision: https://reviews.llvm.org/D91572
2020-11-17 00:55:47 -08:00
River Riddle c51e4c4f01 [mlir][IR] Use tablegen for the BuiltinDialect and operations
This has been a long standing TODO, and cleans up a bit of IR/. This will also make it easier to move FuncOp out of IR/ at some point in the future. For now, Module.h and Function.h just forward BuiltinDialect.h. These files will be removed in a followup.

Differential Revision: https://reviews.llvm.org/D91571
2020-11-17 00:53:40 -08:00
Tei Jeong 65d4b5cb18 Add const qualifier to Type's utility functions
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D91491
2020-11-17 03:56:17 +00:00
Aart Bik 9ddb464d37 [mlir] refactor common idiom into AffineMap method
motivated by a refactoring in the new sparse code (yet to be merged), this avoids some lengthy code dup

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D91465
2020-11-13 19:18:13 -08:00
River Riddle 48e8129edf [mlir][Asm] Add support for resolving operation locations after parsing has finished
This revision adds support in the parser/printer for "deferrable" aliases, i.e. those that can be resolved after printing has finished. This allows for printing aliases for operation locations after the module instead of before, i.e. this is now supported:

```
"foo.op"() : () -> () loc(#loc)

#loc = loc("some_location")
```

Differential Revision: https://reviews.llvm.org/D91227
2020-11-12 23:34:36 -08:00
Rahul Joshi dea24b422c [NFC] Switch printFunctionLikeOp and parseFunctionLikeOp to only support "inline" visibility.
- Remove the default valued arguments from these functions.
- Besides FuncOp, looks like no other in-tree op is using these functions.

Differential Revision: https://reviews.llvm.org/D91369
2020-11-12 11:29:01 -08:00
MaheshRavishankar 5ca20851e4 [mlir][Linalg] Improve the logic to perform tile and fuse with better dependence tracking.
This change does two main things
1) An operation might have multiple dependences to the same
   producer. Not tracking them correctly can result in incorrect code
   generation with fusion. To rectify this the dependence tracking
   needs to also have the operand number in the consumer.
2) Improve the logic used to find the fused loops making it easier to
   follow. The only constraint for fusion is that linalg ops (on
   buffers) have update semantics for the result. Fusion should be
   such that only one iteration of the fused loop (which is also a
   tiled loop) must touch only one (disjoint) tile of the output. This
   could be relaxed by allowing for recomputation that is the default
   when oeprands are tensors, or can be made legal with promotion of
   the fused view (in future).

Differential Revision: https://reviews.llvm.org/D90579
2020-11-12 00:25:24 -08:00
Thomas Raoux 023f2400f2 [mlir] Fix post-dominance between blocks of different regions.
If block A and B are in different regions and region of A is not an ancestor of
B, either A is included in region of B or the two regions are disjoint. In both
case A doesn't post-dominate B.

Differential Revision: https://reviews.llvm.org/D91225
2020-11-11 11:20:53 -08:00
Sean Silva b4fa28b408 [mlir] Add ElementwiseMappable trait and apply it to std elementwise ops.
This patch adds an `ElementwiseMappable` trait as discussed in the RFC
here:
https://llvm.discourse.group/t/rfc-std-elementwise-ops-on-tensors/2113/23

This trait can power a number of transformations and analyses.
A subsequent patch adds a convert-elementwise-to-linalg pass exhibits
how this trait allows writing generic transformations.
See https://reviews.llvm.org/D90354 for that patch.

This trait slightly changes some verifier messages, but the diagnostics
are usually about as good. I fiddled with the ordering of the trait in
the .td file trait lists to minimize the changes here.

Differential Revision: https://reviews.llvm.org/D90731
2020-11-10 13:44:44 -08:00
River Riddle 892605b449 [mlir][Asm] Add support for using an alias for trailing operation locations
Locations often get very long and clutter up operations when printed inline with them. This revision adds support for using aliases with trailing operation locations, and makes printing with aliases the default behavior. Aliases in the trailing location take the form `loc(<alias>)`, such as `loc(#loc0)`. As with all aliases, using `mlir-print-local-scope` can be used to disable them and get the inline behavior.

Differential Revision: https://reviews.llvm.org/D90652
2020-11-09 21:54:47 -08:00
River Riddle ebcc022507 [mlir][AsmPrinter] Refactor printing to only print aliases for attributes/types that will exist in the output.
This revision refactors the way that attributes/types are considered when generating aliases. Instead of considering all of the attributes/types of every operation, we perform a "fake" print step that prints the operations using a dummy printer to collect the attributes and types that would actually be printed during the real process. This removes a lot of attributes/types from consideration that generally won't end up in the final output, e.g. affine map attributes in an `affine.apply`/`affine.for`.

This resolves a long standing TODO w.r.t aliases, and helps to have a much cleaner textual output format. As a datapoint to the latter, as part of this change several tests were identified as testing for the presence of attributes aliases that weren't actually referenced by the custom form of any operation.

To ensure that this wouldn't cause a large degradation in compile time due to the second full print, I benchmarked this change on a very large module with a lot of operations(The file is ~673M/~4.7 million lines long). This file before this change take ~6.9 seconds to print in the custom form, and ~7 seconds after this change. In the custom assembly case, this added an average of a little over ~100 miliseconds to the compile time. This increase was due to the way that argument attributes on functions are structured and how they get printed; i.e. with a better representation the negative impact here can be greatly decreased. When printing in the generic form, this revision had no observable impact on the compile time. This benchmarking leads me to believe that the impact of this change on compile time w.r.t printing is closely related to `print` methods that perform a lot of additional/complex processing outside of the OpAsmPrinter.

Differential Revision: https://reviews.llvm.org/D90512
2020-11-09 21:54:47 -08:00
Rahul Joshi 8b5a3e4632 [MLIR] Change FuncOp assembly syntax to print visibility inline instead of in attrib dict.
- Change syntax for FuncOp to be `func <visibility>? @name` instead of printing the
  visibility in the attribute dictionary.
- Since printFunctionLikeOp() and parseFunctionLikeOp() are also used by other
  operations, make the "inline visibility" an opt-in feature.
- Updated unit test to use and check the new syntax.

Differential Revision: https://reviews.llvm.org/D90859
2020-11-09 11:08:08 -08:00
Rahul Joshi c96168975b [MLIR] Flag no-terminator error on the last operation of non-empty blocks
- When a block is not empty and does not end with a terminator, flag the error on the
  last operation of the block instead of the start of the block.

Differential Revision: https://reviews.llvm.org/D90988
2020-11-09 09:42:11 -08:00
Frederik Gossen 1664462d70 [MLIR] Support walks over regions and blocks
Relands
- [MLIR] Support walks over regions and blocks
         (dbae3d50f1)
- [MLIR] Use llvm::is_one_of in walk templates
         (56299b1e58)

Differential Revision: https://reviews.llvm.org/D90753
2020-11-04 12:50:05 +00:00
Rahul Joshi c298824f9c [MLIR] Check for duplicate entries in attribute dictionary during custom parsing
- Verify that attributes parsed using a custom parser do not have duplicates.
- If there are duplicated in the attribute dictionary in the input, they get caught during the
  dictionary parsing.
- This check verifies that there is no duplication between the parsed dictionary and any
  attributes that might be added by the custom parser (or when the custom parsing code
  adds duplicate attributes).
- Fixes https://bugs.llvm.org/show_bug.cgi?id=48025

Differential Revision: https://reviews.llvm.org/D90502
2020-11-03 16:40:46 -08:00
mikeurbach 2e36e0dad5 [MLIR] Move eraseArguments and eraseResults to FunctionLike
Previously, they were only defined for `FuncOp`.

To support this, `FunctionLike` needs a way to get an updated type
from the concrete operation. This adds a new hook for that purpose,
called `getTypeWithoutArgsAndResults`.

For now, `FunctionLike` continues to assume the type is
`FunctionType`, and concrete operations that use another type can hide
the `getType`, `setType`, and `getTypeWithoutArgsAndResults` methods.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D90363
2020-11-03 16:53:46 -07:00
River Riddle b870d9ec83 [mlir] Optimize Op definitions and registration to optimize for code size
This revision refactors the base Op/AbstractOperation classes to reduce the amount of generated code size when defining a new operation. The current scheme involves taking the address of functions defined directly on Op and Trait classes. This is problematic because even when these functions are empty/unused we still result in these functions being defined in the main executable. In this revision, we switch to using SFINAE and template type filtering to remove remove functions that are not needed/used. For example, if an operation does not define a custom `print` method we shouldn't define a templated `printAssembly` method for it. The same applies to parsing/folding/verification/etc. This dropped MLIR code size for a large downstream library by ~10%(~1 mb in an opt build).

Differential Revision: https://reviews.llvm.org/D90196
2020-11-02 14:39:43 -08:00
Frederik Gossen 327bf5c2d9 Revert "[MLIR] Support walks over regions and blocks"
This reverts commit dbae3d50f1.
Cannot build with gcc/g++ 7.5.0.
2020-11-02 16:21:29 +00:00
River Riddle 235dfcf70a [mlir][AsmPrinter] Fix crash in windows build after D89354
Switch to an index based loop instead of using enumerate.
2020-10-31 14:21:49 -07:00
River Riddle a463ea50a4 [mlir][ASM] Refactor how attribute/type aliases are specified.
Previously they were separated into "instance" and "kind" aliases, and also required that the dialect know ahead of time all of the instances that would have a corresponding alias. This approach was very clunky and not ergonomic to interact with. The new approach is to provide the dialect with an instance  of an attribute/type to provide an alias for, fully replacing the original split approach.

Differential Revision: https://reviews.llvm.org/D89354
2020-10-30 00:39:46 -07:00
Frederik Gossen dbae3d50f1 [MLIR] Support walks over regions and blocks
Add specializations for `walk` to allow traversal of regions and blocks.

Differential Revision: https://reviews.llvm.org/D90379
2020-10-29 14:34:22 +00:00
River Riddle 73547b08de [mlir][SymbolTable] Small optimization to walking symbol references
* Check region count for unknown symbol tables first, as it is a faster check
* Add an accessor to MutableDictionaryAttr to get the internal dictionary without creating a new one if it is empty. This avoids an otherwise unnecessary lookup of an MLIRContext.
2020-10-28 22:01:10 -07:00
Haruki Imai a66e334ceb [mlir] Convert raw data in dense element attributes for big-endian machines.
This patch fixes a bug [[ https://bugs.llvm.org/show_bug.cgi?id=46091 | 46091 ]]

Raw data for the `dense-element attribute` is written in little endian (LE) format.
This commit converts the format to big endian (BE) in ʻAttribute Parser` on the
 BE machine. Also, when outputting on a BE machine, the BE format is converted
 to LE in "AsmPrinter".

Differential Revision: https://reviews.llvm.org/D80695
2020-10-28 17:06:16 -07:00
Kazuaki Ishizaki 41b09f4eff [mlir] NFC: fix trivial typos
fix typos in comments and documents

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D90089
2020-10-29 04:05:22 +09:00
River Riddle eda450bb27 [mlir][SymbolTable] Use Identifier instead of StringRef when looking up symbol name attributes
Using an Identifier is much more efficient for attribute lookups because it uses pointer comparison as opposed to string comparison.

Differential Revision: https://reviews.llvm.org/D89660
2020-10-26 19:40:19 -07:00
River Riddle b6eb26fd0e [mlir][NFC] Move around the code related to PatternRewriting to improve layering
There are several pieces of pattern rewriting infra in IR/ that really shouldn't be there. This revision moves those pieces to a better location such that they are easier to evolve in the future(e.g. with PDL). More concretely this revision does the following:

* Create a Transforms/GreedyPatternRewriteDriver.h and move the apply*andFold methods there.
The definitions for these methods are already in Transforms/ so it doesn't make sense for the declarations to be in IR.

* Create a new lib/Rewrite library and move PatternApplicator there.
This new library will be focused on applying rewrites, and will also include compiling rewrites with PDL.

Differential Revision: https://reviews.llvm.org/D89103
2020-10-26 18:01:06 -07:00
River Riddle b99bd77162 [mlir][Pattern] Refactor the Pattern class into a "metadata only" class
The Pattern class was originally intended to be used for solely matching operations, but that use never materialized. All of the pattern infrastructure uses RewritePattern, and the infrastructure for pure matching(Matchers.h) is implemented inline. This means that this class isn't a useful abstraction at the moment, so this revision refactors it to solely encapsulate the "metadata" of a pattern. The metadata includes the various state describing a pattern; benefit, root operation, etc. The API on PatternApplicator is updated to now operate on `Pattern`s as nothing special from `RewritePattern` is necessary.

This refactoring is also necessary for the upcoming use of PDL patterns alongside C++ rewrite patterns.

Differential Revision: https://reviews.llvm.org/D86258
2020-10-26 18:01:06 -07:00
Alex Zinenko 03e6f40cdb [mlir] Do not print back 0 alignment in LLVM dialect 'alloca' op
The alignment attribute in the 'alloca' op treats the '0' value as 'unset'.
When parsing the custom form of the 'alloca' op, ignore the alignment attribute
with if its value is '0' instead of actually creating it and producing a
slightly different textually yet equivalent semantically form in the output.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D90179
2020-10-26 23:19:20 +01:00
Mehdi Amini e7021232e6 Remove global dialect registration
This has been deprecated for >1month now and removal was announced in:

https://llvm.discourse.group/t/rfc-revamp-dialect-registration/1559/11

Differential Revision: https://reviews.llvm.org/D86356
2020-10-24 00:35:55 +00:00
Mehdi Amini 6a72635881 Revert "Remove global dialect registration"
This reverts commit b22e2e4c6e.

Investigating broken builds
2020-10-23 21:26:48 +00:00
Mehdi Amini b22e2e4c6e Remove global dialect registration
This has been deprecated for >1month now and removal was announced in:

https://llvm.discourse.group/t/rfc-revamp-dialect-registration/1559/11

Differential Revision: https://reviews.llvm.org/D86356
2020-10-23 20:41:44 +00:00
Sean Silva 1253c40727 [mlir] Add FuncOp::eraseResults
I just found I needed this in an upcoming patch, and it seems generally
useful to have.

Differential Revision: https://reviews.llvm.org/D90000
2020-10-23 11:03:42 -07:00
Christian Sigg 1c1803dbb0 [mlir][gpu] Add customer printer/parser for gpu.launch_func.
Reviewed By: herhut

Differential Revision: https://reviews.llvm.org/D89262
2020-10-21 18:19:00 +02:00
Sean Silva 7885bf8b78 [mlir][DialectConversion] Fix recursive `clone` calls.
The framework was not tracking ops created in any regions of the cloned
op.

Differential Revision: https://reviews.llvm.org/D89668
2020-10-19 15:51:46 -07:00
River Riddle 71eeb5ec4d [mlir] Add a new SymbolUserOpInterface class
The initial goal of this interface is to fix the current problems with verifying symbol user operations, but can extend beyond that in the future. The current problems with the verification of symbol uses are:
* Extremely inefficient:
Most current symbol users perform the symbol lookup using the slow O(N) string compare methods, which can lead to extremely long verification times in large modules.
* Invalid/break the constraints of verification pass
If the symbol reference is not-flat(and even if it is flat in some cases) a verifier for an operation is not permitted to touch the referenced operation because it may be in the process of being mutated by a different thread within the pass manager.

The new SymbolUserOpInterface exposes a method `verifySymbolUses` that will be invoked from the parent symbol table to allow for verifying the constraints of any referenced symbols. This method is passed a `SymbolTableCollection` to allow for O(1) lookups of any necessary symbol operation.

Differential Revision: https://reviews.llvm.org/D89512
2020-10-16 12:08:48 -07:00
River Riddle 7bc7d0ac7a [mlir] Optimize symbol related checks in SymbolDCE
This revision contains two optimizations related to symbol checking:
* Optimize SymbolOpInterface to only check for a name attribute if the operation is an optional symbol.
This removes an otherwise unnecessary attribute lookup from a majority of symbols.
* Add a new SymbolTableCollection class to represent a collection of SymbolTables.
This allows for perfoming non-flat symbol lookups in O(1) time by caching SymbolTables for symbol table operations. This class is very useful for algorithms that operate on multiple symbol tables, either recursively or not.

Differential Revision: https://reviews.llvm.org/D89505
2020-10-16 12:08:48 -07:00
River Riddle f3df3b58e7 [mlir] Add a utility class, ThreadLocalCache, for storing non static thread local objects.
(Note: This is a reland of D82597)

This class allows for defining thread local objects that have a set non-static lifetime. This internals of the cache use a static thread_local map between the various different non-static objects and the desired value type. When a non-static object destructs, it simply nulls out the entry in the static map. This will leave an entry in the map, but erase any of the data for the associated value. The current use cases for this are in the MLIRContext, meaning that the number of items in the static map is ~1-2 which aren't particularly costly enough to warrant the complexity of pruning. If a use case arises that requires pruning of the map, the functionality can be added.

This is especially useful in the context of MLIR for implementing thread-local caching of context level objects that would otherwise have very high lock contention. This revision adds a thread local cache in the MLIRContext for attributes, identifiers, and types to reduce some of the locking burden. This led to a speedup of several seconds when compiling a somewhat large mlir module.

Differential Revision: https://reviews.llvm.org/D89504
2020-10-16 12:08:48 -07:00
ahmedsabie 7dff6b818b [MLIR] Add idempotent trait folding
This trait simply adds a fold of f(f(x)) = f(x) when an operation is labelled as idempotent

Reviewed By: rriddle, andyly

Differential Revision: https://reviews.llvm.org/D89421
2020-10-16 15:51:04 +00:00
Geoffrey Martin-Noble b49787df9a Remove unused SideEffectInterfaces header
This change removes an unnecessary header introduced in
https://github.com/llvm/llvm-project/commit/c0b3abd19a3e.

Differential Revision: https://reviews.llvm.org/D89347
2020-10-13 15:22:00 -07:00
ahmedsabie c0b3abd19a [MLIR] Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait
This is the same diff as https://reviews.llvm.org/D88809/ except side effect
free check is removed for involution and a FIXME is added until the dependency
is resolved for shared builds. The old diff has more details on possible fixes.

Reviewed By: rriddle, andyly

Differential Revision: https://reviews.llvm.org/D89333
2020-10-13 21:26:21 +00:00
James Molloy 8bdbe29519 [mlir] Fix bug in computing operation order
When attempting to compute a differential orderIndex we were calculating the
bailout condition correctly, but then an errant "+ 1" meant the orderIndex we
created was invalid.

Added test.

Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D89115
2020-10-09 12:18:52 +01:00
Mehdi Amini 5367a8b67f Revert "[MLIR] Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait"
This reverts commit 1ceaffd95a.

The build is broken with  -DBUILD_SHARED_LIBS=ON ; seems like a possible
layering issue to investigate:

tools/mlir/lib/IR/CMakeFiles/obj.MLIRIR.dir/Operation.cpp.o: In function `mlir::MemoryEffectOpInterface::hasNoEffect(mlir::Operation*)':
Operation.cpp:(.text._ZN4mlir23MemoryEffectOpInterface11hasNoEffectEPNS_9OperationE[_ZN4mlir23MemoryEffectOpInterface11hasNoEffectEPNS_9OperationE]+0x9c): undefined reference to `mlir::MemoryEffectOpInterface::getEffects(llvm::SmallVectorImpl<mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect> >&)'
2020-10-09 06:16:42 +00:00
ahmedsabie 1ceaffd95a [MLIR] Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait
This change allows folds to be done on a newly introduced involution trait rather than having to manually rewrite this optimization for every instance of an involution

Reviewed By: rriddle, andyly, stephenneuendorffer

Differential Revision: https://reviews.llvm.org/D88809
2020-10-09 03:25:53 +00:00
Mehdi Amini 69efcd03bd Fix typo `DenseElementAttr`-> `DenseElementsAttr` in some comments (NFC) 2020-10-08 19:40:48 +00:00
Christian Sigg cc83dc191c Import llvm::StringSwitch into mlir namespace.
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D88971
2020-10-08 11:39:24 +02:00
Diego Caballero 0a925a813a [mlir][NFC] Promote memory space to BaseMemRefType
This patch moves the memory space field from MemRefType and UnrankedMemRefType
to their base class BaseMemRefType so that it can be retrieved from it without
downcasting it to the specific memref.

Reviewed By: silvas

Differential Revision: https://reviews.llvm.org/D87649
2020-09-24 13:54:06 -07:00
Rahul Joshi a6ae695017 [MLIR][NFC] Adopt use of BlockRange in place of ArrayRef<Block *>
- Use BlockRange in ODS generated builders as well as other places throughout the code

Differential Revision: https://reviews.llvm.org/D87955
2020-09-23 09:21:54 -07:00
Stephen Neuendorffer 3f5031f143 [mlir] Add missing space in debug message 2020-09-21 13:01:45 -07:00
Mehdi Amini dabe679488 Add missing new line after debug logging in MLIRContext (NFC) 2020-09-21 05:55:44 +00:00
Uday Bondhugula 9c40495a35 [MLIR][NFC] Value print update for block arguments
Emit some more information when printing/dumping `Value`s of
`BlockArgument` kind. This is purely to help for debugging purposes.

Differential Revision: https://reviews.llvm.org/D87670
2020-09-16 10:47:28 +05:30
Frederik Gossen 6a494e117c [MLIR] Add debug support for ignored patterns
The rewrite engine's cost model may determine some patterns to be irrelevant
ahead of their application. These patterns were silently ignored previously and
now cause a message in `--debug` mode.

Differential Revision: https://reviews.llvm.org/D87290
2020-09-09 07:18:30 +00:00
Rahul Joshi 8893d0816c [MLIR] Change Operation::create() methods to use Value/Type/Block ranges.
- Introduce a new BlockRange class to represent range of blocks (constructible from
  an ArrayRef<Block *> or a SuccessorRange);
- Change Operation::create() methods to use TypeRange for result types, ValueRange for
  operands and BlockRange for successors.

Differential Revision: https://reviews.llvm.org/D86985
2020-09-08 14:19:05 -07:00
Mehdi Amini 01700c45eb Store an Identifier instead of a StringRef for the OperationName inside an AbstractOperation (NFC)
Instead of storing a StringRef, we keep an Identifier which otherwise requires a lock on the context to retrieve.
This will allow to get an Identifier for any registered Operation for "free".

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86994
2020-09-02 19:10:56 +00:00
Mehdi Amini f54914081f Fix mlir-reduce to explicitly register dialects and disable the global dialect registry by default
Clients who rely on the Context loading dialects from the global
registry can call `mlir::enableGlobalDialectRegistry(true);` before
creating an MLIRContext

Differential Revision: https://reviews.llvm.org/D86897
2020-08-31 22:54:58 +00:00
River Riddle eaeadce9bd [mlir][OpFormatGen] Add initial support for regions in the custom op assembly format
This adds some initial support for regions and does not support formatting the specific arguments of a region. For now this can be achieved by using a custom directive that formats the arguments and then parses the region.

Differential Revision: https://reviews.llvm.org/D86760
2020-08-31 13:26:24 -07:00
Kamlesh Kumar deb99610ab Improve doc comments for several methods returning bools
Differential Revision: https://reviews.llvm.org/D86848
2020-08-30 13:33:05 +05:30
Mehdi Amini 9f2fbfab8d Use report_fatal_error instead of llvm::errs() + abort() (NFC)
This is making the error reporting in line with other fatal errors.
2020-08-29 00:36:08 +00:00
Mehdi Amini 7b00c80888 Add a global flag to disable the global dialect registry "process wise"
This is intended to ease the transition for client with a lot of
dependencies. It'll be removed in the coming weeks.

Differential Revision: https://reviews.llvm.org/D86755
2020-08-28 03:17:15 +00:00
River Riddle d289a97f91 [mlir][PDL] Add a PDL Interpreter Dialect
The PDL Interpreter dialect provides a lower level abstraction compared to the PDL dialect, and is targeted towards low level optimization and interpreter code generation. The dialect operations encapsulates low-level pattern match and rewrite "primitives", such as navigating the IR (Operation::getOperand), creating new operations (OpBuilder::create), etc. Many of the operations within this dialect also fuse branching control flow with some form of a predicate comparison operation. This type of fusion reduces the amount of work that an interpreter must do when executing.

An example of this representation is shown below:

```mlir
// The following high level PDL pattern:
pdl.pattern : benefit(1) {
  %resultType = pdl.type
  %inputOperand = pdl.input
  %root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
  pdl.rewrite %root {
    pdl.replace %root with (%inputOperand)
  }
}

// May be represented in the interpreter dialect as follows:
module {
  func @matcher(%arg0: !pdl.operation) {
    pdl_interp.check_operation_name of %arg0 is "foo.op" -> ^bb2, ^bb1
  ^bb1:
    pdl_interp.return
  ^bb2:
    pdl_interp.check_operand_count of %arg0 is 1 -> ^bb3, ^bb1
  ^bb3:
    pdl_interp.check_result_count of %arg0 is 1 -> ^bb4, ^bb1
  ^bb4:
    %0 = pdl_interp.get_operand 0 of %arg0
    pdl_interp.is_not_null %0 : !pdl.value -> ^bb5, ^bb1
  ^bb5:
    %1 = pdl_interp.get_result 0 of %arg0
    pdl_interp.is_not_null %1 : !pdl.value -> ^bb6, ^bb1
  ^bb6:
    pdl_interp.record_match @rewriters::@rewriter(%0, %arg0 : !pdl.value, !pdl.operation) : benefit(1), loc([%arg0]), root("foo.op") -> ^bb1
  }
  module @rewriters {
    func @rewriter(%arg0: !pdl.value, %arg1: !pdl.operation) {
      pdl_interp.replace %arg1 with(%arg0)
      pdl_interp.return
    }
  }
}
```

Differential Revision: https://reviews.llvm.org/D84579
2020-08-26 05:22:27 -07:00
Mehdi Amini 610706906a Add an assertion to protect against missing Dialect registration in a pass pipeline (NFC)
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86327
2020-08-24 06:49:29 +00:00
Rahul Joshi 9c7b0c4aa5 [MLIR] Add PatternRewriter::mergeBlockBefore() to merge a block in the middle of another block.
- This utility to merge a block anywhere into another one can help inline single
  block regions into other blocks.
- Modified patterns test to use the new function.

Differential Revision: https://reviews.llvm.org/D86251
2020-08-19 16:24:59 -07:00
Mehdi Amini f9dc2b7079 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-19 01:19:03 +00:00
Mehdi Amini e75bc5c791 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit d14cf45735.
The build is broken with GCC-5.
2020-08-19 01:19:03 +00:00
Mehdi Amini d14cf45735 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-18 23:23:56 +00:00
River Riddle 250f43d3ec [mlir] Remove the use of "kinds" from Attributes and Types
This greatly simplifies a large portion of the underlying infrastructure, allows for lookups of singleton classes to be much more efficient and always thread-safe(no locking). As a result of this, the dialect symbol registry has been removed as it is no longer necessary.

For users broken by this change, an alert was sent out(https://llvm.discourse.group/t/removing-kinds-from-attributes-and-types) that helps prevent a majority of the breakage surface area. All that should be necessary, if the advice in that alert was followed, is removing the kind passed to the ::get methods.

Differential Revision: https://reviews.llvm.org/D86121
2020-08-18 16:20:14 -07:00
Mehdi Amini d84fe55e0d Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit e1de2b7550.
Broke a build bot.
2020-08-18 22:16:34 +00:00
Mehdi Amini e1de2b7550 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  mlir::registerDialect<mlir::standalone::StandaloneDialect>();
  mlir::registerDialect<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()
2020-08-18 21:14:39 +00:00
Alex Zinenko 674f2df4fe [mlir] Fix printing of unranked memrefs in non-default memory space
The type printer was ignoring the memory space on unranked memrefs.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86096
2020-08-18 09:32:35 +02:00
Mehdi Amini d0e2c79b61 Fix method name to start with lower case to match style guide (NFC) 2020-08-18 00:19:22 +00:00
Mehdi Amini 45cc86b09b Improve error message when constructing a Tensor with an invalid element type (NFC)
Reviewed By: ftynse

Differential Revision: https://reviews.llvm.org/D86040
2020-08-17 20:40:32 +00:00
Mehdi Amini 25ee851746 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit 2056393387.

Build is broken on a few bots
2020-08-15 09:21:47 +00:00
Mehdi Amini 2056393387 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.

Differential Revision: https://reviews.llvm.org/D85622
2020-08-15 08:07:31 +00:00
Mehdi Amini ba92dadf05 Revert "Separate the Registration from Loading dialects in the Context"
This was landed by accident, will reland with the right comments
addressed from the reviews.
Also revert dependent build fixes.
2020-08-15 07:35:10 +00:00
Stephen Neuendorffer 6ce8e4f46b [mlir] build fix for gcc-5
It appears in this case that an implicit cast from StringRef to std::string
doesn't happen.  Fixed with an explicit cast.

Differential Revision: https://reviews.llvm.org/D85986
2020-08-14 11:39:04 -07:00
Mehdi Amini ebf521e784 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.
2020-08-14 09:40:27 +00:00
River Riddle 65277126bf [mlir][Type] Remove the remaining usages of Type::getKind in preparation for its removal
This revision removes all of the lingering usages of Type::getKind. A consequence of this is that FloatType is now split into 4 derived types that represent each of the possible float types(BFloat16Type, Float16Type, Float32Type, and Float64Type). Other than this split, this revision is NFC.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D85566
2020-08-12 19:33:58 -07:00
Mehdi Amini c224bc71af Remove DialectHooks and introduce a Dialect Interfaces instead
These hooks were introduced before the Interfaces mechanism was available.

DialectExtractElementHook is unused and entirely removed. The
DialectConstantFoldHook is used a fallback in the
operation fold() method, and is replaced by a DialectInterface.
The DialectConstantDecodeHook is used for interpreting OpaqueAttribute
and should be revamped, but is replaced with an interface in 1:1 fashion
for now.

Differential Revision: https://reviews.llvm.org/D85595
2020-08-13 00:38:55 +00:00
Jakub Lichman 9dd7ed24bf [mlir] Added support for Index type inside getZeroAttr function
Differential Revision: https://reviews.llvm.org/D85833
2020-08-12 16:21:35 +00:00
Mehdi Amini 58acda1c16 Revert "[mlir] Add a utility class, ThreadLocalCache, for storing non static thread local objects."
This reverts commit 9f24640b7e.

We hit some dead-locks on thread exit in some configurations: TLS exit handler is taking a lock.
Temporarily reverting this change as we're debugging what is going on.
2020-08-08 05:31:25 +00:00
Sean Silva b0d76f454d [mlir] Centralize handling of memref element types.
This also beefs up the test coverage:
- Make unranked memref testing consistent with ranked memrefs.
- Add testing for the invalid element type cases.

This is not quite NFC: index types are now allowed in unranked memrefs.

Differential Revision: https://reviews.llvm.org/D85541
2020-08-07 15:17:23 -07:00
River Riddle c8c45985fb [mlir][Type] Remove usages of Type::getKind
This is in preparation for removing the use of "kinds" within attributes and types in MLIR.

Differential Revision: https://reviews.llvm.org/D85475
2020-08-07 13:43:25 -07:00
River Riddle fff39b62bb [mlir][Attribute] Remove usages of Attribute::getKind
This is in preparation for removing the use of "kinds" within attributes and types in MLIR.

Differential Revision: https://reviews.llvm.org/D85370
2020-08-07 13:43:25 -07:00
River Riddle 1d6a8deb41 [mlir] Remove the need to define `kindof` on attribute and type classes.
This revision refactors the default definition of the attribute and type `classof` methods to use the TypeID of the concrete class instead of invoking the `kindof` method. The TypeID is already used as part of uniquing, and this allows for removing the need for users to define any of the type casting utilities themselves.

Differential Revision: https://reviews.llvm.org/D85356
2020-08-07 13:43:25 -07:00
River Riddle dd48773396 [mlir][Types] Remove the subclass data from Type
Subclass data is useful when a certain amount of memory is allocated, but not all of it is used. In the case of Type, that hasn't been the case for a while and the subclass is just taking up a full `unsigned`. Removing this frees up ~8 bytes for almost every type instance.

Differential Revision: https://reviews.llvm.org/D85348
2020-08-07 13:43:25 -07:00
River Riddle 9f24640b7e [mlir] Add a utility class, ThreadLocalCache, for storing non static thread local objects.
This class allows for defining thread local objects that have a set non-static lifetime. This internals of the cache use a static thread_local map between the various different non-static objects and the desired value type. When a non-static object destructs, it simply nulls out the entry in the static map. This will leave an entry in the map, but erase any of the data for the associated value. The current use cases for this are in the MLIRContext, meaning that the number of items in the static map is ~1-2 which aren't particularly costly enough to warrant the complexity of pruning. If a use case arises that requires pruning of the map, the functionality can be added.

This is especially useful in the context of MLIR for implementing thread-local caching of context level objects that would otherwise have very high lock contention. This revision adds a thread local cache in the MLIRContext for attributes, identifiers, and types to reduce some of the locking burden. This led to a speedup of several hundred miliseconds when compiling a conversion pass on a very large mlir module(>300K operations).

Differential Revision: https://reviews.llvm.org/D82597
2020-08-07 13:43:25 -07:00
River Riddle 86646be315 [mlir] Refactor StorageUniquer to require registration of possible storage types
This allows for bucketing the different possible storage types, with each bucket having its own allocator/mutex/instance map. This greatly reduces the amount of lock contention when multi-threading is enabled. On some non-trivial .mlir modules (>300K operations), this led to a compile time decrease of a single conversion pass by around half a second(>25%).

Differential Revision: https://reviews.llvm.org/D82596
2020-08-07 13:43:24 -07:00