Commit Graph

1122 Commits

Author SHA1 Message Date
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
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
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
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
Mehdi Amini 1e484b8a24 Remove spurious empty line at the beginning of source file (NFC) 2020-08-14 08:02:59 +00:00
Mehdi Amini 5035d192fa Fix BufferPlacement Pass to derive from the TableGen generated parent class (NFC) 2020-08-14 08:01:47 +00:00
avarmapml 6d4f7801b1 [MLIR] Support for ReturnOps in memref map layout normalization
-- This commit handles the returnOp in memref map layout normalization.
-- An initial filter is applied on FuncOps which helps us know which functions can be
   a suitable candidate for memref normalization which doesn't lead to invalid IR.
-- Handles memref map normalization for external function assuming the external function
   is normalizable.

Differential Revision: https://reviews.llvm.org/D85226
2020-08-13 19:10:47 +05:30
Mehdi Amini b28e3db88d Merge OpFolderDialectInterface with DialectFoldInterface (NFC)
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85823
2020-08-13 00:39:22 +00:00
Vincent Zhao 654e8aadfd [MLIR] Consider AffineIfOp when getting the index set of an Op wrapped in nested loops
This diff attempts to resolve the TODO in `getOpIndexSet` (formerly
known as `getInstIndexSet`), which states "Add support to handle IfInsts
surronding `op`".

Major changes in this diff:

1. Overload `getIndexSet`. The overloaded version considers both
`AffineForOp` and `AffineIfOp`.
2. The `getInstIndexSet` is updated accordingly: its name is changed to
`getOpIndexSet` and its implementation is based on a new API `getIVs`
instead of `getLoopIVs`.
3. Add `addAffineIfOpDomain` to `FlatAffineConstraints`, which extracts
new constraints from the integer set of `AffineIfOp` and merges it to
the current constraint system.
4. Update how a `Value` is determined as dim or symbol for
`ValuePositionMap` in `buildDimAndSymbolPositionMaps`.

Differential Revision: https://reviews.llvm.org/D84698
2020-08-09 03:16:03 +05:30
Diego Caballero 3bfbc5df87 [MLIR][Affine] Fix createPrivateMemRef in affine fusion
Always define a remapping for the memref replacement (`indexRemap`)
with the proper number of inputs, including all the `outerIVs`, so that
the number of inputs and the operands provided for the map don't mismatch.

Reviewed By: bondhugula, andydavis1

Differential Revision: https://reviews.llvm.org/D85177
2020-08-04 12:17:48 -07:00
MaheshRavishankar 32f3a9a9d6 [mlir][DialectConversion] Remove usage of std::distance to track position.
Remove use of iterator::difference_type to know where to insert a
moved or erased block during undo actions.

Differential Revision: https://reviews.llvm.org/D85066
2020-08-03 10:06:05 -07:00
MaheshRavishankar e888886cc3 [mlir][DialectConversion] Add support for mergeBlocks in ConversionPatternRewriter.
Differential Revision: https://reviews.llvm.org/D84795
2020-08-03 10:06:04 -07:00
Julian Gross 6d47431d7e [mlir] Extended Buffer Assignment to support AllocaOps.
Added support for AllocaOps in Buffer Assignment.

Differential Revision: https://reviews.llvm.org/D85017
2020-08-03 11:20:30 +02:00
Abhishek Varma 76d07503f0 [MLIR] Introduce inter-procedural memref layout normalization
-- Introduces a pass that normalizes the affine layout maps to the identity layout map both within and across functions by rewriting function arguments and call operands where necessary.
-- Memref normalization is now implemented entirely in the module pass '-normalize-memrefs' and the limited intra-procedural version has been removed from '-simplify-affine-structures'.
-- Run using -normalize-memrefs.
-- Return ops are not handled and would be handled in the subsequent revisions.

Signed-off-by: Abhishek Varma <abhishek.varma@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D84490
2020-07-30 18:12:56 +05:30
Rahul Joshi 706d992ced [NFC] Add getArgumentTypes() to Region
- Add getArgumentTypes() to Region (missed from before)
- Adopt Region argument API in `hasMultiplyAddBody`
- Fix 2 typos in comments

Differential Revision: https://reviews.llvm.org/D84807
2020-07-28 18:27:42 -07:00
Anand Kodnani 834133c950 [MLIR] Vector store to load forwarding
The MemRefDataFlow pass does store to load forwarding
only for affine store/loads. This patch updates the pass
to use affine read/write interface which enables vector
forwarding.

Reviewed By: dcaballe, bondhugula, ftynse

Differential Revision: https://reviews.llvm.org/D84302
2020-07-28 11:30:54 -07:00
Ehsan Toosi 486d2750c7 [mlir][NFC] Polish copy removal transform
Address a few remaining comments in copy removal transform.

Differential Revision: https://reviews.llvm.org/D84529
2020-07-28 08:34:44 +02:00
River Riddle 4589dd924d [mlir][DialectConversion] Enable deeper integration of type conversions
This revision adds support for much deeper type conversion integration into the conversion process, and enables auto-generating cast operations when necessary. Type conversions are now largely automatically managed by the conversion infra when using a ConversionPattern with a provided TypeConverter. This removes the need for patterns to do type cast wrapping themselves and moves the burden to the infra. This makes it much easier to perform partial lowerings when type conversions are involved, as any lingering type conversions will be automatically resolved/legalized by the conversion infra.

To support this new integration, a few changes have been made to the type materialization API on TypeConverter. Materialization has been split into three separate categories:
* Argument Materialization: This type of materialization is used when converting the type of block arguments when calling `convertRegionTypes`. This is useful for contextually inserting additional conversion operations when converting a block argument type, such as when converting the types of a function signature.
* Source Materialization: This type of materialization is used to convert a legal type of the converter into a non-legal type, generally a source type. This may be called when uses of a non-legal type persist after the conversion process has finished.
* Target Materialization: This type of materialization is used to convert a non-legal, or source, type into a legal, or target, type. This type of materialization is used when applying a pattern on an operation, but the types of the operands have not yet been converted.

Differential Revision: https://reviews.llvm.org/D82831
2020-07-23 19:40:31 -07:00
Haruki Imai 7f44a7130b [MLIR] Set alignment in AllocOp of normalizeMemref()
AllocOp is updated in normalizeMemref(AllocOp allocOp), but, when the
AllocOp has `alignment` attribute, it was ignored and updated AllocOp
does not have `alignment` attribute. This patch fixes it.

Differential Revision: https://reviews.llvm.org/D83656
2020-07-22 12:34:35 +05:30
Stephen Neuendorffer 628288658c [MLIR] Add RegionKindInterface
Some dialects have semantics which is not well represented by common
SSA structures with dominance constraints.  This patch allows
operations to declare the 'kind' of their contained regions.
Currently, two kinds are allowed: "SSACFG" and "Graph".  The only
difference between them at the moment is that SSACFG regions are
required to have dominance, while Graph regions are not required to
have dominance.  The intention is that this Interface would be
generated by ODS for existing operations, although this has not yet
been implemented. Presumably, if someone were interested in code
generation, we might also have a "CFG" dialect, which defines control
flow, but does not require SSA.

The new behavior is mostly identical to the previous behavior, since
registered operations without a RegionKindInterface are assumed to
contain SSACFG regions.  However, the behavior has changed for
unregistered operations.  Previously, these were checked for
dominance, however the new behavior allows dominance violations, in
order to allow the processing of unregistered dialects with Graph
regions.  One implication of this is that regions in unregistered
operations with more than one op are no longer CSE'd (since it
requires dominance info).

I've also reorganized the LangRef documentation to remove assertions
about "sequential execution", "SSA Values", and "Dominance".  Instead,
the core IR is simply "ordered" (i.e. totally ordered) and consists of
"Values".  I've also clarified some things about how control flow
passes between blocks in an SSACFG region. Control Flow must enter a
region at the entry block and follow terminator operation successors
or be returned to the containing op.  Graph regions do not define a
notion of control flow.

see discussion here:
https://llvm.discourse.group/t/rfc-allowing-dialects-to-relax-the-ssa-dominance-condition/833/53

Differential Revision: https://reviews.llvm.org/D80358
2020-07-15 14:27:05 -07:00
Uday Bondhugula ec85d7c8f3 [MLIR][NFC] Fix clang tidy warnings in misc utilities
Fix clang tidy warnings in misc utilities - missing const or a star in
declaration.

Differential Revision: https://reviews.llvm.org/D83861
2020-07-16 00:27:30 +05:30
River Riddle b98f414a04 [mlir][DialectConversion] Emit an error if an operation marked as erased has live users after conversion
Up until now, there has been an implicit agreement that when an operation is marked as
"erased" all uses of that operation's results are guaranteed to be removed during conversion. How this works in practice is that there is either an assert/crash/asan failure/etc. This revision adds support for properly detecting when an erased operation has dangling users, emits and error and fails the conversion.

Differential Revision: https://reviews.llvm.org/D82830
2020-07-14 13:06:08 -07:00
Uday Bondhugula 9b974dfa72 [MLIR] [NFC] Buffer placement pass - clang tidy warnings
Add missing const - addresses clang tidy warnings.

Differential Revision: https://reviews.llvm.org/D83794
2020-07-14 23:49:24 +05:30
Rahul Joshi e2b716105b [MLIR] Add argument related API to Region
- Arguments of the first block of a region are considered region arguments.
- Add API on Region class to deal with these arguments directly instead of
  using the front() block.
- Changed several instances of existing code that can use this API
- Fixes https://bugs.llvm.org/show_bug.cgi?id=46535

Differential Revision: https://reviews.llvm.org/D83599
2020-07-14 09:28:29 -07:00
Nicolai Hähnle 3fa989d4fd DomTree: remove explicit use of DomTreeNodeBase::iterator
Summary:
Almost all uses of these iterators, including implicit ones, really
only need the const variant (as it should be). The only exception is
in NewGVN, which changes the order of dominator tree child nodes.

Change-Id: I4b5bd71e32d71b0c67b03d4927d93fe9413726d4

Reviewers: arsenm, RKSimon, mehdi_amini, courbet, rriddle, aartbik

Subscribers: wdng, Prazek, hiraditya, kuhar, rogfer01, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, stephenneuendorffer, Joonsoo, grosul1, vkmr, Kayjukh, jurahul, msifontes, cfe-commits, llvm-commits

Tags: #clang, #mlir, #llvm

Differential Revision: https://reviews.llvm.org/D83087
2020-07-08 18:18:49 +02:00
Alexander Belyaev 1a2ed71a8a [mlir] Support unranked types in func signature conversion in BufferPlacement.
Currently, only ranked tensor args and results can be converted to memref types.

Differential Revision: https://reviews.llvm.org/D83324
2020-07-07 19:43:48 +02:00
River Riddle 9db53a1827 [mlir][NFC] Remove usernames and google bug numbers from TODO comments.
These were largely leftover from when MLIR was a google project, and don't really follow LLVM guidelines.
2020-07-07 01:40:52 -07:00
Julian Gross 91c320e9d8 [mlir] Add check for ViewLikeOpInterface that creates additional aliases.
ViewLikeOpInterfaces introduce new aliases that need to be added to the alias
list. This is necessary to place deallocs in the right positions.

Differential Revision: https://reviews.llvm.org/D83044
2020-07-03 16:38:21 +02:00
Ehsan Toosi 0f03b2bfda [mlir] Add redundant copy removal transform
This pass removes redundant dialect-independent Copy operations in different
situations like the following:

%from = ...
%to = ...
... (no user/alias for %to)
copy(%from, %to)
... (no user/alias for %from)
dealloc %from
use(%to)

Differential Revision: https://reviews.llvm.org/D82757
2020-07-03 15:36:25 +02:00
Marcel Koester 6f5da84f7b [mlir] Extended BufferPlacement to support nested region control flow.
Summary: The current BufferPlacement implementation does not support
nested region control flow. This CL adds support for nested regions via
the RegionBranchOpInterface and the detection of branch-like
(ReturnLike) terminators inside nested regions.

Differential Revision: https://reviews.llvm.org/D81926
2020-06-30 12:10:01 +02:00
Rahul Joshi ee394e6842 [MLIR] Add variadic isa<> for Type, Value, and Attribute
- Also adopt variadic llvm::isa<> in more places.
- Fixes https://bugs.llvm.org/show_bug.cgi?id=46445

Differential Revision: https://reviews.llvm.org/D82769
2020-06-29 15:04:48 -07:00
Tobias Gysi 652a79659a [mlir] fix off-by-one error in collapseParallelLoops
Summary: The patch fixes an off by one error in the method collapseParallelLoops. It ensures the same normalized bound is used for the computation of the division and the remainder.

Reviewers: herhut

Reviewed By: herhut

Subscribers: mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, stephenneuendorffer, Joonsoo, grosul1, Kayjukh, jurahul, msifontes

Tags: #mlir

Differential Revision: https://reviews.llvm.org/D82634
2020-06-26 15:39:46 +02:00
Tung D. Le 2b5d1776ff [MLIR][Affine-loop-fusion] Fix a bug in affine-loop-fusion pass when there are non-affine operations
When there is a mix of affine load/store and non-affine operations (e.g. std.load, std.store),
affine-loop-fusion ignores the present of non-affine ops, thus changing the program semantics.

E.g. we have a program of three affine loops operating on the same memref in which one of them uses std.load and std.store, as follows.
```
affine.for
  affine.store %1
affine.for
  std.load %1
  std.store %1
affine.for
  affine.load %1
  affine.store %1
```
affine-loop-fusion will produce the following result which changed the program semantics:
```
affine.for
  std.load %1
  std.store %1
affine.for
  affine.store %1
  affine.load %1
  affine.store %1
```

This patch is to fix the above problem by checking non-affine users of the memref that are between the source and destination nodes of interest.

Differential Revision: https://reviews.llvm.org/D82158
2020-06-26 18:26:42 +05:30
River Riddle e6a343e491 [mlir][DialectConversion][NFC] Add comment blocks and organize a bit of the code
This helps improve the readability when scrolling through the many functions of ConversionPatternRewriterImpl.
2020-06-24 17:42:10 -07:00
Rahul Joshi d891d738d9 [MLIR][NFC] Adopt variadic isa<>
Differential Revision: https://reviews.llvm.org/D82489
2020-06-24 17:02:44 -07:00
Uday Bondhugula aec5344f48 [MLIR] Fix affine loop fusion private memref alloc
Drop stale code that provided the wrong operands to alloc.

Reported-by: rjnw on discourse

Differential Revision: https://reviews.llvm.org/D82409
2020-06-24 22:19:29 +05:30
Rahul Joshi 60f914e5b1 [NFC][MLIR] Undo anonymous namespace change from https://reviews.llvm.org/D82417
Undo as it does not conform to LLVM coding style
(https://llvm.org/docs/CodingStandards.html#anonymous-namespaces)
2020-06-23 20:21:42 -07:00
Rahul Joshi e7f7137cd7 [MLIR] [NFC] Add new line and empty line before printing modified loop
to make the debug output readable.

Differential Revision: https://reviews.llvm.org/D82417
2020-06-23 17:27:43 -07:00
Rahul Joshi d150662024 [MLIR][NFC] Eliminate .getBlocks() when not needed
Differential Revision: https://reviews.llvm.org/D82229
2020-06-19 14:16:21 -07:00
River Riddle 8d67d187ba [mlir][DialectConversion] Refactor how block argument types get converted
This revision removes the TypeConverter parameter passed to the apply* methods, and instead moves the responsibility of region type conversion to patterns. The types of a region can be converted using the 'convertRegionTypes' method, which acts similarly to the existing 'applySignatureConversion'. This method ensures that all blocks within, and including those moved into, a region will have the block argument types converted using the provided converter.

This has the benefit of making more of the legalization logic controlled by patterns, instead of being handled explicitly by the driver. It also opens up the possibility to support multiple type conversions at some point in the future.

This revision also adds a new utility class `FailureOr<T>` that provides a LogicalResult friendly facility for returning a failure or a valid result value.

Differential Revision: https://reviews.llvm.org/D81681
2020-06-18 15:59:22 -07:00
River Riddle 80d7ac3bc7 [mlir] Allow for patterns to match any root kind.
Traditionally patterns have always had the root operation kind hardcoded to a specific operation name. This has worked well for quite some time, but it has certain limitations that make it undesirable. For example, some lowering have the same implementation for many different operations types with a few lowering entire dialects using the same pattern implementation. This problem has led to several "solutions":
a) Provide a template implementation to the user so that they can instantiate it for each operation combination, generally requiring the inclusion of the auto-generated operation definition file.
b) Use a non-templated pattern that allows for providing the name of the operation to match
  - No one ever does this, because enumerating operation names can be cumbersome and so this quickly devolves into solution a.

This revision removes the restriction that patterns have a hardcoded root type, and allows for a class patterns that could match "any" operation type. The major downside of root-agnostic patterns is that they make certain pattern analyses more difficult, so it is still very highly encouraged that an operation specific pattern be used whenever possible.

Differential Revision: https://reviews.llvm.org/D82066
2020-06-18 13:58:47 -07:00
River Riddle 3e98fbf4f5 [mlir] Refactor RewritePatternMatcher into a new PatternApplicator class.
This class enables for abstracting more of the details for the rewrite process, and will allow for clients to apply specific cost models to the pattern list. This allows for DialectConversion and the GreedyPatternRewriter to share the same underlying matcher implementation. This also simplifies the plumbing necessary to support dynamic patterns.

Differential Revision: https://reviews.llvm.org/D81985
2020-06-18 13:58:47 -07:00
River Riddle f4ef77cbb4 [mlir][Inliner] Properly handle callgraph node deletion
We previously weren't properly updating the SCC iterator when nodes were removed, leading to asan failures in certain situations. This commit adds a CallGraphSCC class and defers operation deletion until inlining has finished.

Differential Revision: https://reviews.llvm.org/D81984
2020-06-17 15:45:56 -07:00
Rahul Joshi 2eaadfc4fe [NFC] Use llvm::hasSingleElement() in place of .size() == 1
- Also use functions in Region instead of Region::getBlocks() where possible.

Differential Revision: https://reviews.llvm.org/D82032
2020-06-17 13:26:10 -07:00
Alex Zinenko 3adced3494 [mlir] Introduce callback-based builders to SCF Parallel and Reduce ops
Similarly to `scf::ForOp`, introduce additional `function_ref` arguments to
`::build` functions of SCF `ParallelOp` and `ReduceOp`. The provided functions
will be called to construct the body of the respective operations while
constructing the operation itself. Exercise them in LoopUtils.

Differential Revision: https://reviews.llvm.org/D81872
2020-06-16 20:51:32 +02:00
River Riddle 0e360744f3 [mlir][DialectConversion] Cache type conversions and add a few useful helpers
It is quite common for the same type to be converted many types throughout the conversion process, and there isn't any good reason why we aren't caching that result. Especially given that we currently use identity conversion to signify legality. This revision also adds a few additional helpers to TypeConverter.

Differential Revision: https://reviews.llvm.org/D81679
2020-06-15 15:57:43 -07:00
Marcel Koester 33879aa0bf [mlir] Fixed GCC compile issues and linking problems using SHARED_LIBS.
Differential Revision: https://reviews.llvm.org/D81839
2020-06-15 15:46:21 +02:00
Marcel Koester ff4c510337 [mlir] Extended BufferPlacement to support more sophisticated scenarios in which
allocations cannot be moved freely and can remain in divergent control flow.

The current BufferPlacement pass does not support allocation nodes that carry
additional dependencies (like in the case of dynamic shaped types). These
allocations can often not be moved freely and in turn might remain in divergent
control-flow branches. This requires a different strategy with respect to block
arguments and aliases. This CL adds additinal functionality to support
allocation nodes in divergent control flow while avoiding memory leaks.

Differential Revision: https://reviews.llvm.org/D79850
2020-06-15 12:19:23 +02:00
Diego Caballero 2e7a084591 [mlir][Affine] Revisit fusion candidates after successful fusion
This patch changes the fusion algorithm so that after fusing two loop nests
we revisit previously visited nodes so that they are considered again for
fusion in the context of the new fused loop nest.

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D81609
2020-06-11 14:53:08 -07:00
Rahul Joshi 475935113c [MLIR] Emit debug message if inlining fails
Summary: Emit a debug message if inlining fails.

Differential Revision: https://reviews.llvm.org/D81320
2020-06-10 17:38:41 -07:00
Ehsan Toosi 4214031d43 [mlir] Introduce allowMemrefFunctionResults for the helper operation converters of buffer placement
This parameter gives the developers the freedom to choose their desired function
signature conversion for preparing their functions for buffer placement. It is
introduced for BufferAssignmentFuncOpConverter, and also for
BufferAssignmentReturnOpConverter, and BufferAssignmentCallOpConverter to adapt
the return and call operations with the selected function signature conversion.
If the parameter is set, buffer placement won't also deallocate the returned
buffers.

Differential Revision: https://reviews.llvm.org/D81137
2020-06-08 09:25:41 +02:00
Nicolas Vasilache 38c407bf00 [mlir][SCF] Add single iteration scf.for promotion to the FuncOp level helper.
Previously only the Affine version would be folded.

Differential Revision: https://reviews.llvm.org/D81261
2020-06-05 11:28:21 -04:00
Nicolas Vasilache 6953cf6502 [mlir][Linalg] Add a hoistRedundantVectorTransfers helper function
This revision adds a helper function to hoist vector.transfer_read /
vector.transfer_write pairs out of immediately enclosing scf::ForOp
iteratively, if the following conditions are true:
   1. The 2 ops access the same memref with the same indices.
   2. All operands are invariant under the enclosing scf::ForOp.
   3. No uses of the memref either dominate the transfer_read or are
   dominated by the transfer_write (i.e. no aliasing between the write and
   the read across the loop)

To improve hoisting opportunities, call the `moveLoopInvariantCode` helper
function on the candidate loop above which to hoist. Hoisting the transfers
results in scf::ForOp yielding the value that originally transited through
memory.

This revision additionally exposes `moveLoopInvariantCode` as a helper in
LoopUtils.h and updates SliceAnalysis to support return scf::For values and
allow hoisting across multiple scf::ForOps.

Differential Revision: https://reviews.llvm.org/D81199
2020-06-05 06:50:24 -04:00
Diego Caballero 8a418e5f8e [mlir][Affine] Enable fusion of loops with vector loads/stores
This patch enables affine loop fusion for loops with affine vector loads
and stores. For that, we only had to use affine memory op interfaces in
LoopFusionUtils.cpp and Utils.cpp so that vector loads and stores are
also taken into account.

Reviewed By: andydavis1, ftynse

Differential Revision: https://reviews.llvm.org/D80971
2020-06-03 01:26:22 +03:00
Alex Zinenko 5c5dafc534 [mlir] support materialization for 1-1 type conversions
Dialect conversion infrastructure supports 1->N type conversions by requiring
individual conversions to provide facilities to generate operations
retrofitting N values into 1 of the original type when N > 1. This
functionality can also be used to materialize explicit "cast"-like operations,
but it did not support 1->1 type conversions until now. Modify TypeConverter to
support materialization of cast operations for 1-1 conversions.

This also makes materialization specification more extensible following the
same pattern as type conversions. Instead of overloading a virtual function,
users or subclasses of TypeConversion can now register type-specific
materialization callbacks that will be called in order for the given type.

Differential Revision: https://reviews.llvm.org/D79729
2020-06-02 13:48:33 +02:00
Alex Zinenko 195d8571b9 [mlir] post-commit review fixes
This fixes several post-commit nits from D79688 and D80135, namely
typos, debug output and control flow inversion.
2020-06-02 12:08:17 +02:00
Ehsan Toosi 3f6a35e3ff [mlir] Introduce CallOp converter for buffer placement
Add BufferAssignmentCallOpConverter as a pattern rewriter for Buffer
Placement. It matches the signature of the caller operation with the callee
after rewriting the callee with FunctionAndBlockSignatureConverter.

Differential Revision: https://reviews.llvm.org/D80785
2020-06-02 11:35:24 +02:00
Chris Lattner 0cf5ef176b Change some extraneous /// comments to // comments inside methods. NFC. 2020-05-31 11:43:54 -07:00
Mehdi Amini 21fee0921d Use .empty() instead of .size() == 0 (NFC)
Cleanup / Fix a clang-tidy warning
2020-05-30 03:36:22 +00:00
Ehsan Toosi 7a3a253585 [MLIR][BufferPlacement] Support functions that return Memref typed results
Buffer placement can now operates on functions that return buffers. These
buffers escape from the deallocation phase of buffer placement.

Differential Revision: https://reviews.llvm.org/D80696
2020-05-29 11:03:22 +02:00
Alex Zinenko df48026b4c [mlir] DialectConversion: support erasing blocks
PatternRewriter has support for erasing a Block from its parent region, but
this feature has not been implemented for ConversionPatternRewriter that needs
to keep track of and be able to undo block actions. Introduce support for
undoing block erasure in the ConversionPatternRewriter by marking all the ops
it contains for erasure and by detaching the block from its parent region. The
detached block is stored in the action description and is not actually deleted
until the rewrites are applied.

Differential Revision: https://reviews.llvm.org/D80135
2020-05-20 16:12:05 +02:00
Alex Zinenko 5d5df06aac [mlir] DialectConversion: avoid double-free when rolling back op creation
Dialect conversion infrastructure may roll back op creation by erasing the
operations in the reverse order of their creation. While this guarantees uses
of values will be deleted before their definitions, this does not guarantee
that a parent operation will not be deleted before its child. (This may happen
in case of block inlining or if child operations, such as terminators, are
created in the parent's `build` function before the parent itself.) Handle the
parent/child relationship between ops by removing all child ops from the blocks
before erasing the parent. The child ops remain live, detached from a block,
and will be safely destroyed in their turn, which may come later than that of
the parent.

Differential Revision: https://reviews.llvm.org/D80134
2020-05-20 16:12:05 +02:00
Diego Caballero a45fb1942f [mlir][Affine] Introduce affine memory interfaces
This patch introduces interfaces for read and write ops with affine
restrictions. I used `read`/`write` intead of `load`/`store` for the
interfaces so that they can also be implemented by dma ops.
For now, they are only implemented by affine.load, affine.store,
affine.vector_load and affine.vector_store.

For testing purposes, this patch also migrates affine loop fusion and
required analysis to use the new interfaces. No other changes are made
beyond that.

Co-authored-by: Alex Zinenko <zinenko@google.com>

Reviewed By: bondhugula, ftynse

Differential Revision: https://reviews.llvm.org/D79829
2020-05-19 17:32:50 -07:00
Ehsan Toosi 3468300511 [MLIR] Update the FunctionAndBlockSignatureConverter and NonVoidToVoidReturnOpConverter of Buffer Assignment
Making these two converters more generic. FunctionAndBlockSignatureConverter now
moves only memref results (after type conversion) to the function argument and
keeps other legal function results unchanged. NonVoidToVoidReturnOpConverter is
renamed to NoBufferOperandsReturnOpConverter. It removes only the buffer
operands from the operands of the converted ReturnOp and inserts CopyOps to copy
each buffer to the target function argument.

Differential Revision: https://reviews.llvm.org/D79329
2020-05-19 17:04:59 +02:00
Stephen Neuendorffer eb623ae832 [MLIR] Continue renaming of "SideEffects"
MLIRSideEffects -> MLIRSideEffectInterfaces
SideEffects.h -> SideEffectInterfaces.h
SideEffects.cpp -> SideEffectInterface.cpp

Note that I haven't renamed TableGen/SideEffects.h or TableGen/SideEffects.cpp

find -name "*.h" -exec sed -i "s/SideEffects.h/SideEffectInterfaces.h/" "{}" \;
find -name "CMakeLists.txt" -exec sed -i "s/MLIRSideEffects/MLIRSideEffectInterfaces/" "{}" \;

Differential Revision: https://reviews.llvm.org/D79890
2020-05-15 14:37:09 -07:00
Sean Silva 98eead8186 [mlir][Value] Add v.getDefiningOp<OpTy>()
Summary:
This makes a common pattern of
`dyn_cast_or_null<OpTy>(v.getDefiningOp())` more concise.

Differential Revision: https://reviews.llvm.org/D79681
2020-05-11 12:55:27 -07:00
Alex Zinenko c25b20c0f6 [mlir] NFC: Rename LoopOps dialect to SCF (Structured Control Flow)
This dialect contains various structured control flow operaitons, not only
loops, reflect this in the name. Drop the Ops suffix for consistency with other
dialects.

Note that this only moves the files and changes the C++ namespace from 'loop'
to 'scf'. The visible IR prefix remains the same and will be updated
separately. The conversions will also be updated separately.

Differential Revision: https://reviews.llvm.org/D79578
2020-05-11 15:04:27 +02:00
Uday Bondhugula 2affcd664e [MLIR] Fix affine fusion bug/efficiency issue / enable more fusion
The list of destination load ops while evaluating producer-consumer
fusion wasn't being maintained as a set, and as such, duplicate load ops
were being added to it. Although this is harmless correctness-wise, it's
a killer efficiency-wise and it prevents interesting/useful fusions
(including for eg. reshapes into a matmul). The reason the latter
fusions would be missed is that a slice union would be unnecessarily
needed due to the duplicate load ops on a memref added to the 'dst
loads' list. Since slice union is unimplemented for the local var case,
a single destination load op that leads to local vars (like a floordiv /
mod producing fusion), a common case, would not get fused due to an
unnecessary union being tried with itself.  (The union would actually be
the same thing but we would bail out.)

Besides the above, this would also significantly speed up fusion as all
the unnecessary slice computations / unions, checks, etc. due to the
duplicates go away.

Differential Revision: https://reviews.llvm.org/D79547
2020-05-07 10:51:34 +05:30
Uday Bondhugula ca09dab303 [MLIR][NFC] Fix/update debug messages for analysis utils and affine fusion
Drop trailing period in debug messages. Add an extra line for fusion
debug info.

Differential Revision: https://reviews.llvm.org/D79471
2020-05-06 12:27:59 +05:30
Reid Kleckner 932f0276ea [Support] Move LLD's parallel algorithm wrappers to support
Essentially takes the lld/Common/Threads.h wrappers and moves them to
the llvm/Support/Paralle.h algorithm header.

The changes are:
- Remove policy parameter, since all clients use `par`.
- Rename the methods to `parallelSort` etc to match LLVM style, since
  they are no longer C++17 pstl compatible.
- Move algorithms from llvm::parallel:: to llvm::, since they have
  "parallel" in the name and are no longer overloads of the regular
  algorithms.
- Add range overloads
- Use the sequential algorithm directly when 1 thread is requested
  (skips task grouping)
- Fix the index type of parallelForEachN to size_t. Nobody in LLVM was
  using any other parameter, and it made overload resolution hard for
  for_each_n(par, 0, foo.size(), ...) because 0 is int, not size_t.

Remove Threads.h and update LLD for that.

This is a prerequisite for parallel public symbol processing in the PDB
library, which is in LLVM.

Reviewed By: MaskRay, aganea

Differential Revision: https://reviews.llvm.org/D79390
2020-05-05 15:21:05 -07:00
Andy Davis 93d1108801 [MLIR][LoopOps] Adds the loop unroll transformation for loop::ForOp.
Summary:
Adds the loop unroll transformation for loop::ForOp.
Adds support for promoting the body of single-iteration loop::ForOps into its containing block.
Adds check tests for loop::ForOps with dynamic and static lower/upper bounds and step.
Care was taken to share code (where possible) with the AffineForOp unroll transformation to ease maintenance and potential future transition to a LoopLike construct on which loop transformations for different loop types can implemented.

Reviewers: ftynse, nicolasvasilache

Reviewed By: ftynse

Subscribers: bondhugula, mgorny, zzheng, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, grosul1, frgossen, Kayjukh, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D79184
2020-05-05 10:42:36 -07:00
Stephen Neuendorffer 5469f434bb [MLIR] Reapply: Adjust libMLIR building to more closely follow libClang
This reverts commit ab1ca6e60f.
2020-05-04 20:47:57 -07:00
River Riddle 469c02d058 [mlir] Add support for merging identical blocks during canonicalization
This revision adds support for merging identical blocks, or those with the same operations that branch to the same successors. Operands that mismatch between the different blocks are replaced with new block arguments added to the merged block.

Differential Revision: https://reviews.llvm.org/D79134
2020-05-04 19:56:46 -07:00
River Riddle 1e4faf23ff [mlir][IR] Add a Region::getOps method that returns a range of immediately nested operations
This allows for walking the operations nested directly within a region, without traversing nested regions.

Differential Revision: https://reviews.llvm.org/D79056
2020-05-04 17:46:25 -07:00
Stephen Neuendorffer ab1ca6e60f Revert "[MLIR] Adjust libMLIR building to more closely follow libClang"
This reverts commit 4f0f436749.

This seems to show some compile dependence problems, and also breaks flang.
2020-05-04 12:40:12 -07:00
Valentin Churavy 4f0f436749 [MLIR] Adjust libMLIR building to more closely follow libClang
- Exports MLIR targets to be used out-of-tree.
- mimicks `add_clang_library` and `add_flang_library`.
- Fixes libMLIR.so

After https://reviews.llvm.org/D77515 libMLIR.so was no longer containing
any object files. We originally had a cludge there that made it work with
the static initalizers and when switchting away from that to the way the
clang shlib does it, I noticed that MLIR doesn't create a `obj.{name}` target,
and doesn't export it's targets to `lib/cmake/mlir`.

This is due to MLIR using `add_llvm_library` under the hood, which adds
the target to `llvmexports`.

Differential Revision: https://reviews.llvm.org/D78773

[MLIR] Fix libMLIR.so and LLVM_LINK_LLVM_DYLIB

Primarily, this patch moves all mlir references to LLVM libraries into
either LLVM_LINK_COMPONENTS or LINK_COMPONENTS.  This enables magic in
the llvm cmake files to automatically replace reference to LLVM components
with references to libLLVM.so when necessary.  Among other things, this
completes fixing libMLIR.so, which has been broken for some configurations
since D77515.

Unlike previously, the pattern is now that mlir libraries should almost
always use add_mlir_library.  Previously, some libraries still used
add_llvm_library.  However, this confuses the export of targets for use
out of tree because libraries specified with add_llvm_library are exported
by LLVM.  Instead users which don't need/can't be linked into libMLIR.so
can specify EXCLUDE_FROM_LIBMLIR

A common error mode is linking with LLVM libraries outside of LINK_COMPONENTS.
This almost always results in symbol confusion or multiply defined options
in LLVM when the same object file is included as a static library and
as part of libLLVM.so.  To catch these errors more directly, there's now
mlir_check_all_link_libraries.

To simplify usage of add_mlir_library, we assume that all mlir
libraries depend on LLVMSupport, so it's not necessary to separately specify
it.

tested with:
BUILD_SHARED_LIBS=on,
BUILD_SHARED_LIBS=off + LLVM_BUILD_LLVM_DYLIB,
BUILD_SHARED_LIBS=off + LLVM_BUILD_LLVM_DYLIB + LLVM_LINK_LLVM_DYLIB.

By: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
Differential Revision: https://reviews.llvm.org/D79067

[MLIR] Move from using target_link_libraries to LINK_LIBS

This allows us to correctly generate dependencies for derived targets,
such as targets which are created for object libraries.

By: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
Differential Revision: https://reviews.llvm.org/D79243

Three commits have been squashed to avoid intermediate build breakage.
2020-05-04 11:40:46 -07:00
Marcel Koester 67b466deda [mlir] Removed tight coupling of BufferPlacement pass to Alloc and Dealloc.
The current BufferPlacement implementation tries to find Alloc and Dealloc
operations in order to move them. However, this is a tight coupling to
standard-dialect ops which has been removed in this CL.

Differential Revision: https://reviews.llvm.org/D78993
2020-05-04 14:23:15 +02:00
River Riddle cb9ae0025c [mlir] Add a new context flag for disabling/enabling multi-threading
This is useful for several reasons:
* In some situations the user can guarantee that thread-safety isn't necessary and don't want to pay the cost of synchronization, e.g., when parsing a very large module.

* For things like logging threading is not desirable as the output is not guaranteed to be in stable order.

This flag also subsumes the pass manager flag for multi-threading.

Differential Revision: https://reviews.llvm.org/D79266
2020-05-02 12:32:25 -07:00
Stephen Neuendorffer 57818885be [MLIR] Move Verifier and Dominance Analysis from /Analysis to /IR
These libraries are distinct from other things in Analysis in that they
operate only on core IR concepts.  This also simplifies dependencies
so that Dialect -> Analysis -> Parser -> IR.  Previously, the parser depended
on portions of the the Analysis directory as well, which sometimes
caused issues with the way the cmake makefile generator discovers
dependencies on generated files during compilation.

Differential Revision: https://reviews.llvm.org/D79240
2020-05-01 20:01:46 -07:00
River Riddle 359164f810 [mlir][OpBuilder] Remove the vtable from OpBuilder in favor of using the listener pattern
The current OpBuilder has a set of virtual functions required by the fact that the PatternRewriter inherits from it for convenience. The PatternRewriter is required to know about IR mutations for correctness. This revision changes the relationship to be explicit by having users register a listener with the builder instead of using inheritance/vtables. This still requires that users properly transfer the listener when creating new builders, but has several benefits:

* More than one builder can be created during pattern rewrites(assuming that the listener is properly forwarded)
* OpBuilder no longer requires a vtable, and thus does not incur the cost when a listener isn't present.

Differential Revision: https://reviews.llvm.org/D79206
2020-04-30 21:29:25 -07:00
Lucy Fox 8de482ea9a [MLIR] Modify Partial op conversion mode to optionally track all non-legalizable operations.
There are three op conversion modes: Partial, Full, and Analysis. This change modifies the Partial mode to optionally take a set of non-legalizable ops. If this parameter is specified, all ops that are not legalizable (i.e. would cause full conversion to fail) are tracked throughout the partial legalization.

Differential Revision: https://reviews.llvm.org/D78788
2020-04-30 09:52:37 -07:00
River Riddle 0752d98ccf [mlir] Simplify BranchOpInterface by using MutableOperandRange
This range allows for performing many different operations on successor operands, including erasing/adding/setting. This removes the need for the explicit canEraseSuccessorOperand and eraseSuccessorOperand methods.

Differential Revision: https://reviews.llvm.org/D79077
2020-04-29 16:48:15 -07:00
River Riddle df00e466da [mlir] Move the operation equivalence out of CSE and into OperationSupport
This provides a general hash and comparison for checking if two operations are equivalent. This revision also optimizes the handling of result types to take advantage of how result types are stored on the operation.

Differential Revision: https://reviews.llvm.org/D79029
2020-04-29 16:48:15 -07:00
Jacques Pienaar 5439582781 Rename NamedAttributeList to MutableDictionaryAttr
Makes the relationship and function clearer. Accordingly rename getAttrList to getMutableAttrDict.

Differential Revision: https://reviews.llvm.org/D79125
2020-04-29 14:58:02 -07:00
Ehsan Toosi 5c352e69e7 Providing buffer assignment for MLIR
We have provided a generic buffer assignment transformation ported from
TensorFlow. This generic transformation pass automatically analyzes the values
and their aliases (also in other blocks) and returns the valid positions for
Alloc and Dealloc operations. To find these positions, the algorithm uses the
block Dominator and Post-Dominator analyses. In our proposed algorithm, we have
considered aliasing, liveness, nested regions, branches, conditional branches,
critical edges, and independency to custom block terminators. This
implementation doesn't support block loops. However, we have considered this in
our design. For this purpose, it is only required to have a loop analysis to
insert Alloc and Dealloc operations outside of these loops in some special
cases.

Differential Revision: https://reviews.llvm.org/D78484
2020-04-28 10:17:59 +02:00
River Riddle a90151d67e [mlir][SCCP] Add support for propagating across symbol based calls
This revision adds support for propagating constants across symbol-based callgraph edges. It uses the existing Call/CallableOpInterfaces to detect the dataflow edges, and propagates constants through arguments and out of returns.

Differential Revision: https://reviews.llvm.org/D78592
2020-04-27 13:04:49 -07:00
River Riddle 7c221a7d4f [mlir][Symbol] Change Symbol from a Trait into an OpInterface.
This provides a much cleaner interface into Symbols, and allows for users to start injecting op-specific information. For example, derived op can now inject when a symbol can be discarded if use_empty. This would let us drop unused external functions, which generally have public visibility.

This revision also adds a new `extraTraitClassDeclaration` field to ODS OpInterface to allow for injecting declarations into the trait class that gets attached to the operations.

Differential Revision: https://reviews.llvm.org/D78522
2020-04-27 13:04:49 -07:00
Alexander Belyaev ed5363a674 [MLIR] Add getBody() method to SingleImplicitBlockTerminator op trait.
Many ops with this trait have `getBody()` and `getBodyBuilder()` methods defined in `extraClassDeclaration` in tablegen. `getBody()` implementation is the same accross all these ops, but `getBodyBuilder()` can return builders with varying insertion points set. In this PR, `getBody()` is moved into `SingleImplicitBlockTerminator` struct and `getBodyBuilder()` is replaced with `OpBuilder::atBlock(End|Terminator)(op.getBody);`.

Differential Revision: https://reviews.llvm.org/D78864
2020-04-27 21:48:52 +02:00
River Riddle 4dfd1b5fcb [mlir] Optimize operand storage such that all operations can have resizable operand lists
This revision refactors the structure of the operand storage such that there is no additional memory cost for resizable operand lists until it is required. This is done by using two different internal representations for the operand storage:
* One using trailing operands
* One using a dynamically allocated std::vector<OpOperand>

This allows for removing the resizable operand list bit, and will free up APIs from needing to workaround non-resizable operand lists.

Differential Revision: https://reviews.llvm.org/D78875
2020-04-26 21:34:01 -07:00
River Riddle 0816de167a [mlir][DialectConversion] Add support for properly tracking replaceUsesOfBlockArgument
The current implementation of this method performs the replacement directly, and thus doesn't support proper back tracking.

Differential Revision: https://reviews.llvm.org/D78790
2020-04-24 12:37:32 -07:00
River Riddle 2eda87dfbe [mlir][SCCP] Add support for propagating constants across inter-region control flow.
This is possible by adding two new ControlFlowInterface additions:

- A new interface, RegionBranchOpInterface
This interface allows for region holding operations to describe how control flows between regions. This interface initially contains two methods:

* getSuccessorEntryOperands
Returns the operands of this operation used as the entry arguments when entering the region at `index`, which was specified as a successor by `getSuccessorRegions`. when entering. These operands should correspond 1-1 with the successor inputs specified in `getSuccessorRegions`, and may be a subset of the entry arguments for that region.

*  getSuccessorRegions
Returns the viable successors of a region, or the possible successor when branching from the parent op. This allows for describing which regions may be executed when entering an operation, and which regions are executed after having executed another region of the parent op. For example, a structured loop operation may always enter into the loop body region. The loop body region may branch back to itself, or exit to the operation.

- A trait, ReturnLike
This trait signals that a terminator exits a region and forwards all of its operands as "exiting" values.

These additions allow for performing more general dataflow analysis in the presence of region holding operations.

Differential Revision: https://reviews.llvm.org/D78447
2020-04-21 02:59:25 -07:00
River Riddle 152d29cc74 [mlir][Transforms] Add pass to perform sparse conditional constant propagation
This revision adds the initial pass for performing SCCP generically in MLIR. SCCP is an algorithm for propagating constants across control flow, and optimistically assumes all values to be constant unless proven otherwise. It currently supports branching control, with support for regions and inter-procedural propagation being added in followups.

Differential Revision: https://reviews.llvm.org/D78397
2020-04-21 02:59:25 -07:00
Sean Silva 22219cfc6a Fix inlining multi-block callees with type conversion.
The previous code result a mismatch between block argument types and
predecessor successor args when a type conversion was needed in a
multiblock case. It was assuming the replaced result types matched the
region result types.

Also, slighly improve the debug output from the inliner.

Differential Revision: https://reviews.llvm.org/D78415
2020-04-20 16:54:01 -07:00
Alexander Belyaev def3e10eac [MLIR] Add #include "llvm/ADT/SmallPtrSet.h" back to LoopUtils.h. 2020-04-20 10:21:18 +02:00
Alexander Belyaev ad9988f4da [MLIR] Move `replaceAllUsesExcept` from LoopUtil.h to Value.h.
Differential Revision: https://reviews.llvm.org/D78426
2020-04-20 09:21:06 +02:00
Uday Bondhugula ecddafd84a [MLIR] NFC affine for op tiling cleanup / utility rename
Rename mlir::tileCodeGen -> mlir::tilePerfectlyNested to be consistent.
NFC clean up tiling utility code, drop dead code, better comments.
Expose isPerfectlyNested and reuse.

Differential Revision: https://reviews.llvm.org/D78423
2020-04-19 00:53:34 +05:30
Uday Bondhugula f043677f6d [MLIR] Make isPerfectlyNested check more efficient
Make mlir::isPerfectlyNested more efficient; use O(1) check instead of
O(N) size() method.

Differential Revision: https://reviews.llvm.org/D78428
2020-04-18 23:34:49 +05:30
Stephen Neuendorffer f061295732 [MLIR] Complete refactoring of Affine dialect into sub-libraries.
There were some unused CMakeFiles for Affine/IR and Affine/EDSC.
This change builds separate MLIRAffineOps and MLIRAffineEDSC libraries
using those CMakeFiles.  This combination replaces the old MLIRAffine
library.

Differential Revision: https://reviews.llvm.org/D78317
2020-04-16 13:41:17 -07:00
Alexander Belyaev be9c3bdc44 [MLIR] Fix fusion of linalg.indexed_generic producer into tiled (Indexed)GenericOp.
Differential Revision: https://reviews.llvm.org/D78209
2020-04-16 10:45:17 +02:00
Lorenzo Chelini a60fdd2ba4 [MLIR] NFC after commit D77478.
Remove leftovers 'applyPatternsGreedily' from the codebase.

Differential Revision: https://reviews.llvm.org/D78274
2020-04-16 10:32:01 +02:00
River Riddle 4f37450b2c [mlir][Inliner] Store the resolved call by-value instead of by-reference
This avoids asan failures as more calls may be added during inlining, invalidating the reference.

Differential Revision: https://reviews.llvm.org/D78258
2020-04-15 17:42:27 -07:00
Jeremy Bruestle 9f3ab92ec8 [MLIR] Improve support for 0-dimensional Affine Maps.
Summary:
Modified AffineMap::get to remove support for the overload which allowed
an ArrayRef of AffineExpr but no context (and gathered the context from a
presumed first entry, resulting in bugs when there were 0 results).

Instead, we support only a ArrayRef and a context, and a version which
takes a single AffineExpr.

Additionally, removed some now needless case logic which previously
special cased which call to AffineMap::get to use.

Reviewers: flaub, bondhugula, rriddle!, nicolasvasilache, ftynse, ulysseB, mravishankar, antiagainst, aartbik

Subscribers: mehdi_amini, jpienaar, burmako, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, bader, grosul1, frgossen, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D78226
2020-04-15 14:15:02 -07:00
Uday Bondhugula 04b5274ede [MLIR] Introduce applyOpPatternsAndFold for op local rewrites
Introduce mlir::applyOpPatternsAndFold which applies patterns as well as
any folding only on a specified op (in contrast to
applyPatternsAndFoldGreedily which applies patterns only on the regions
of an op isolated from above).  The caller is made aware of the op being
folded away or erased.

Depends on D77485.

Differential Revision: https://reviews.llvm.org/D77487
2020-04-15 14:10:01 +05:30
River Riddle 92f1562f3d [mlir][NFC] Remove the STLExtras.h header file now that it has been merged into LLVM.
Now that no more utilities exist within, this file can be deleted.

Differential Revision: https://reviews.llvm.org/D78079
2020-04-14 15:14:41 -07:00
River Riddle ebf190fcda [llvm][ADT] Move TypeSwitch class from MLIR to LLVM
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionality. Each `Case<T>` takes a callable to be invoked if the root value isa<T>, the callable is invoked with the result of dyn_cast<T>() as a parameter.

Differential Revision: https://reviews.llvm.org/D78070
2020-04-14 15:14:41 -07:00
River Riddle 2f21a57966 [llvm][STLExtras] Move the algorithm `interleave*` methods from MLIR to LLVM
These have proved incredibly useful for interleaving values between a range w.r.t to streams. After this revision, the mlir/Support/STLExtras.h is empty. A followup revision will remove it from the tree.

Differential Revision: https://reviews.llvm.org/D78067
2020-04-14 15:14:40 -07:00
River Riddle 204c3b5516 [llvm][STLExtras] Move various iterator/range utilities from MLIR to LLVM
This revision moves the various range utilities present in MLIR to LLVM to enable greater reuse. This revision moves the following utilities:

* indexed_accessor_*
This is set of utility iterator/range base classes that allow for building a range class where the iterators are represented by an object+index pair.

* make_second_range
Given a range of pairs, returns a range iterating over the `second` elements.

* hasSingleElement
Returns if the given range has 1 element. size() == 1 checks end up being very common, but size() is not always O(1) (e.g., ilist). This method provides O(1) checks for those cases.

Differential Revision: https://reviews.llvm.org/D78064
2020-04-14 15:14:40 -07:00
Uday Bondhugula ac047d9fce [MLIR] Remove dead affine.applys while generating pointwise copies
This makes no impact on the test cases because affine-data-copy-generate
runs whole function canonicalization at its end; however, the latter
will be removed in a pending revision. It is thus useful to clean up
these affine.applys right here, and eventually, not even generate
these (when the right API to compose by construction is in place).

Differential Revision: https://reviews.llvm.org/D78055
2020-04-14 09:47:14 +05:30
Uday Bondhugula 42ada5fee9 [MLIR] NFC cleanup/modernize memref-dataflow-opt / getNestingDepth
Bring code to date with recent changes to the core infrastructure /
coding style.

Differential Revision: https://reviews.llvm.org/D77998
2020-04-14 00:03:06 +05:30
Uday Bondhugula cbcb12fd44 [MLIR] Handle in-place folding properly in greedy pattern rewrite driver
OperatioFolder::tryToFold performs both true folding and in a few
instances in-place updates through op rewrites. In the latter case, we
should still be applying the supplied pattern rewrites in the same
iteration; however this wasn't the case since tryToFold returned
success() for both true folding and in-place updates, and the patterns
for the in-place updated ops were being applied only in the next
iteration of the driver's outer loop. This fix would make it converge
faster.

Differential Revision: https://reviews.llvm.org/D77485
2020-04-11 19:57:29 +05:30
Uday Bondhugula a5b9316b24 [MLIR][NFC] applyPatternsGreedily -> applyPatternsAndFoldGreedily
Rename mlir::applyPatternsGreedily -> applyPatternsAndFoldGreedily. The
new name is a more accurate description of the method - it performs
both, application of the specified patterns and folding of all ops in
the op's region irrespective of whether any patterns have been supplied.

Differential Revision: https://reviews.llvm.org/D77478
2020-04-10 12:55:21 +05:30
River Riddle bd1ccfe6df [mlir] Add a new RewritePattern::hasBoundedRewriteRecursion hook.
Summary: Some pattern rewriters, like dialect conversion, prohibit the unbounded recursion(or reapplication) of patterns on generated IR. Most patterns are not written with recursive application in mind, so will generally explode the stack if uncaught. This revision adds a hook to RewritePattern, `hasBoundedRewriteRecursion`, to signal that the pattern can safely be applied to the generated IR of a previous application of the same pattern. This allows for establishing a contract between the pattern and rewriter that the pattern knows and can handle the potential recursive application.

Differential Revision: https://reviews.llvm.org/D77782
2020-04-09 12:42:28 -07:00
River Riddle 400ad6f95d [mlir] Eliminate the remaining usages of cl::opt instead of PassOption.
Summary: Pass options are a better choice for various reasons and avoid the need for static constructors.

Differential Revision: https://reviews.llvm.org/D77707
2020-04-08 13:05:08 -07:00
River Riddle 1834ad4a69 [mlir][Pass] Update the PassGen to generate base classes instead of utilities
Summary:
This is much cleaner, and fits the same structure as many other tablegen backends. This was not done originally as the CRTP in the pass classes made it overly verbose/complex.

Differential Revision: https://reviews.llvm.org/D77367
2020-04-07 14:08:52 -07:00
River Riddle 80aca1eaf7 [mlir][Pass] Remove the use of CRTP from the Pass classes
This revision removes all of the CRTP from the pass hierarchy in preparation for using the tablegen backend instead. This creates a much cleaner interface in the C++ code, and naturally fits with the rest of the infrastructure. A new utility class, PassWrapper, is added to replicate the existing behavior for passes not suitable for using the tablegen backend.

Differential Revision: https://reviews.llvm.org/D77350
2020-04-07 14:08:52 -07:00
River Riddle 722f909f7a [mlir][Pass][NFC] Replace usages of ModulePass with OperationPass<ModuleOp>
ModulePass doesn't provide any special utilities and thus doesn't give enough benefit to warrant a special pass class. This revision replaces all usages with the more general OperationPass.

Differential Revision: https://reviews.llvm.org/D77339
2020-04-07 14:08:52 -07:00
Uday Bondhugula 70da33bf30 [MLIR] fix/update affine data copy utility for max/min bounds
Fix point-wise copy generation to work with bounds that have max/min.
Change structure of copy loop nest to use absolute loop indices and
subtracting base from the indexes of the fast buffers. Update supporting
utilities: Fix FlatAffineConstraints::getLowerAndUpperBound to look at
equalities as well and for a missing division. Update unionBoundingBox
to not discard common constraints (leads to a tighter system). Update
MemRefRegion::getConstantBoundingSizeAndShape to add memref dimension
constraints. Run removeTrivialRedundancy at the end of
MemRefRegion::compute.  Run single iteration loop promotion and
load/store canonicalization after affine data copy (in its test pass as
well).

Differential Revision: https://reviews.llvm.org/D77320
2020-04-07 13:55:42 +05:30
Uday Bondhugula 3f9cdd44d7 [MLIR] Add pattern rewriter util to erase block; remove dead else
Add a pattern rewriter utility to erase blocks (while notifying the
pattern rewriting driver of the erased ops). Use this to remove trivial
else blocks in affine.if ops.

Differential Revision: https://reviews.llvm.org/D77083
2020-04-05 19:24:43 +05:30
Uday Bondhugula cc6738949d [MLIR][NFC] fix name operand -> userOp
The wrong name was confusing to read. value.getUsers() yields
Operation *s.

Differential Revision: https://reviews.llvm.org/D77486
2020-04-05 19:17:15 +05:30
Uday Bondhugula f875e55ba9 [MLIR] fix greedy pattern rewrite driver iteration on change
Removing dead ops should make the outer loop of the pattern rewriting
driver run again. Although its operands are added to the worklist, if no
changes happenned to them or remaining ops in the worklist, the driver
wouldn't run once again - but it should be.

Differential Revision: https://reviews.llvm.org/D77483
2020-04-05 19:15:46 +05:30
Kazuaki Ishizaki 5aacce3db2 [mlir] NFC: Fix trivial typo
Differential Revision: https://reviews.llvm.org/D77473
2020-04-05 11:30:30 +09:00
Alex Zinenko f27f1e8c27 [mlir] DialectConversion: support block creation in ConversionPatternRewriter
PatternRewriter and derived classes provide a set of virtual methods to
manipulate blocks, which ConversionPatternRewriter overrides to keep track of
the manipulations and undo them in case the conversion fails. However, one can
currently create a block only by splitting another block into two. This not
only makes the API inconsistent (`splitBlock` is allowed in conversion
patterns, but `createBlock` is not), but it also make it impossible for one to
create blocks with argument lists different from those of already existing
blocks since in-place block updates are not supported either. Such
functionality precludes dialect conversion infrastructure from being used more
extensively on region-containing ops, for example, for value-returning "if"
operations. At the same time, ConversionPatternRewriter already allows one to
undo block creation as block creation is one of the primitive operations in
already supported region inlining.

Support block creation in conversion patterns by hooking `createBlock` on the
block action undo mechanism. This requires to make `Builder::createBlock`
virtual, similarly to Op insertion. This is a minimal change to the Builder
infrastructure that will later help support additional use cases such as block
signature changes. `createBlock` now additionally takes the types of the block
arguments that are added immediately so as to avoid in-place argument list
manipulation that would be illegal in conversion patterns.
2020-04-03 20:30:03 +02:00
Uday Bondhugula 5e8093134a [MLIR] Add method to drop duplicate result exprs from AffineMap
Add a method that given an affine map returns another with just its unique
results. Use this to drop redundant bounds in max/min for affine.for. Update
affine.for's canonicalization pattern and createCanonicalizedForOp to use
this.

Differential Revision: https://reviews.llvm.org/D77237
2020-04-02 03:00:19 +05:30
Mehdi Amini 0dd21130ef Add LLVM_ATTRIBUTE_UNUSED to function used only in assert (NFC) 2020-04-01 17:21:07 +00:00
Uday Bondhugula 68316afb29 [MLIR][NFC] loop transforms/analyis utils cleanup / modernize
Modernize/cleanup code in loop transforms utils - a lot of this code was
written prior to the currently available IR support / code style. This
patch also does some variable renames including inst -> op, comment
updates, turns getCleanupLoopLowerBound into a local function.

Differential Revision: https://reviews.llvm.org/D77175
2020-04-01 22:36:25 +05:30
River Riddle 9a277af2d4 [mlir][Pass] Add support for generating pass utilities via tablegen
This revision adds support for generating utilities for passes such as options/statistics/etc. that can be inferred from the tablegen definition. This removes additional boilerplate from the pass, and also makes it easier to remove the reliance on the pass registry to provide certain things(e.g. the pass argument).

Differential Revision: https://reviews.llvm.org/D76659
2020-04-01 02:10:46 -07:00
River Riddle 8155e41ac6 [mlir][Pass] Add a tablegen backend for defining Pass information
This will greatly simplify a number of things related to passes:
* Enables generation of pass registration
* Enables generation of boiler plate pass utilities
* Enables generation of pass documentation

This revision focuses on adding the basic structure and adds support for generating the registration for passes in the Transforms/ directory. Future revisions will add more support and move more passes over.

Differential Revision: https://reviews.llvm.org/D76656
2020-04-01 02:10:46 -07:00
Tres Popp 90b7bbffdd [MLIR] Rename collapsePLoops -> collapseParallelLoops
Summary:
Additionally, NFC code cleanups were done.

This is to address additional comments on
https://reviews.llvm.org/D76363

Differential Revision: https://reviews.llvm.org/D77052
2020-04-01 10:15:13 +02:00
Uday Bondhugula f273e5c507 [MLIR] Fix permuteLoops utility
Rewrite mlir::permuteLoops (affine loop permutation utility) to fix
incorrect approach. Avoiding using sinkLoops entirely - use single move
approach. Add test pass.

This fixes https://bugs.llvm.org/show_bug.cgi?id=45328

Depends on D77003.

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D77004
2020-03-30 23:38:23 +05:30
scentini 3b20970de8 Fix unused-variable error when assertions are disabled 2020-03-30 13:55:43 +02:00
Uday Bondhugula 4e4ea2cde4 [MLIR] Add missing asserts in interchangeLoops util, doc comment update
Add missing assert checks for input to mlir::interchangeLoops utility.
Rename interchangeLoops -> permuteLoops; update doc comments to clarify
inputs / return val. Other than the assert checks, this is NFC.

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D77003
2020-03-30 00:03:12 +05:30
Uday Bondhugula 43a95a543f [MLIR] Introduce full/partial tile separation using if/else
This patch introduces a utility to separate full tiles from partial
tiles when tiling affine loop nests where trip counts are unknown or
where tile sizes don't divide trip counts. A conditional guard is
generated to separate out the full tile (with constant trip count loops)
into the then block of an 'affine.if' and the partial tile to the else
block. The separation allows the 'then' block (which has constant trip
count loops) to be optimized better subsequently: for eg. for
unroll-and-jam, register tiling, vectorization without leading to
cleanup code, or to offload to accelerators. Among techniques from the
literature, the if/else based separation leads to the most compact
cleanup code for multi-dimensional cases (because a single version is
used to model all partial tiles).

INPUT

  affine.for %i0 = 0 to %M {
    affine.for %i1 = 0 to %N {
      "foo"() : () -> ()
    }
  }

OUTPUT AFTER TILING W/O SEPARATION

  map0 = affine_map<(d0) -> (d0)>
  map1 = affine_map<(d0)[s0] -> (d0 + 32, s0)>

  affine.for %arg2 = 0 to %M step 32 {
    affine.for %arg3 = 0 to %N step 32 {
      affine.for %arg4 = #map0(%arg2) to min #map1(%arg2)[%M] {
        affine.for %arg5 = #map0(%arg3) to min #map1(%arg3)[%N] {
          "foo"() : () -> ()
        }
      }
    }
  }

  OUTPUT AFTER TILING WITH SEPARATION

  map0 = affine_map<(d0) -> (d0)>
  map1 = affine_map<(d0) -> (d0 + 32)>
  map2 = affine_map<(d0)[s0] -> (d0 + 32, s0)>

  #set0 = affine_set<(d0, d1)[s0, s1] : (-d0 + s0 - 32 >= 0, -d1 + s1 - 32 >= 0)>

  affine.for %arg2 = 0 to %M step 32 {
    affine.for %arg3 = 0 to %N step 32 {
      affine.if #set0(%arg2, %arg3)[%M, %N] {
        // Full tile.
        affine.for %arg4 = #map0(%arg2) to #map1(%arg2) {
          affine.for %arg5 = #map0(%arg3) to #map1(%arg3) {
            "foo"() : () -> ()
          }
        }
      } else {
        // Partial tile.
        affine.for %arg4 = #map0(%arg2) to min #map2(%arg2)[%M] {
          affine.for %arg5 = #map0(%arg3) to min #map2(%arg3)[%N] {
            "foo"() : () -> ()
          }
        }
      }
    }
  }

The separation is tested via a cmd line flag on the loop tiling pass.
The utility itself allows one to pass in any band of contiguously nested
loops, and can be used by other transforms/utilities. The current
implementation works for hyperrectangular loop nests.

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D76700
2020-03-28 06:58:35 +05:30
Uday Bondhugula ad4b4acbb0 [MLIR][NFC] drop some unnecessary includes
Drop unnecessary includes

Differential Revision: https://reviews.llvm.org/D76898
2020-03-27 09:17:27 +05:30
Tres Popp 27c201aa1d [MLIR] Add parallel loop collapsing.
This allows conversion of a ParallelLoop from N induction variables to
some nuber of induction variables less than N.

The first intended use of this is for the GPUDialect to convert
ParallelLoops to iterate over 3 dimensions so they can be launched as
GPU Kernels.

To implement this:
- Normalize each iteration space of the ParallelLoop
- Use the same induction variable in a new ParallelLoop for multiple
  original iterations.
- Split the new induction variable back into the original set of values
  inside the body of the ParallelLoop.

Subscribers: mgorny, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D76363
2020-03-26 09:32:52 +01:00
Uday Bondhugula 98fa615002 [MLIR] move loopUnrollJamBy*Factor to loop transforms utils
The declarations for these were already part of transforms utils, but
the definitions were left in affine transforms. Move definitions to loop
transforms utils.

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D76633
2020-03-24 08:08:57 +05:30
MaheshRavishankar 04f2b717d2 [mlir] Fix unsafe create operation in GreedyPatternRewriter
When trying to fold an operation during operation creation check that
the operation folding succeeds before inserting the op.

Differential Revision: https://reviews.llvm.org/D76415
2020-03-23 11:50:40 -07:00
Uday Bondhugula b873761496 [MLIR][NFC] Move some of the affine transforms / tests to dialect dirs
Move some of the affine transforms and their test cases to their
respective dialect directory. This patch does not complete the move, but
takes care of a good part.

Renames: prefix 'affine' to affine loop tiling cl options,
vectorize -> super-vectorize

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D76565
2020-03-23 08:25:07 +05:30
River Riddle e9482ed194 [mlir] Move several static cl::opts to be pass options instead.
This removes the reliance on global options, and also simplifies the pass registration.

Differential Revision: https://reviews.llvm.org/D76552
2020-03-22 03:16:21 -07:00
Rob Suderman e708471395 [mlir][NFC] Cleanup AffineOps directory structure
Summary:
Change AffineOps Dialect structure to better group both IR and Tranforms. This included extracting transforms directly related to AffineOps. Also move AffineOps to Affine.

Differential Revision: https://reviews.llvm.org/D76161
2020-03-20 14:23:43 -07:00
Uday Bondhugula 0ddd04391d [MLIR] Fix op folding to not run pre-replace when not constant folding
OperationFolder::tryToFold was running the pre-replacement
action even when there was no constant folding, i.e., when the operation
was just being updated in place but was not going to be replaced. This
led to nested ops being unnecessarily removed from the worklist and only
being processed in the next outer iteration of the greedy pattern
rewriter, which is also why this didn't affect the final output IR but
only the convergence rate. It also led to an op's results' users to be
unnecessarily added to the worklist.

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D76268
2020-03-20 07:49:49 +05:30
Yaxun (Sam) Liu f528df8e26 Revert "Add a test for UsedDeclVisitor"
This reverts commit b58f6bb120.
2020-03-19 00:15:47 -04:00
Yaxun (Sam) Liu b58f6bb120 Add a test for UsedDeclVisitor
This test is reduced from mlir/lib/Transforms/AffineDataCopyGeneration.cpp
to make sure there is no assertion due to UsedDeclVisitor.
2020-03-19 00:05:10 -04:00
River Riddle 4be504a97f [mlir] Add support for detecting single use callables in the Inliner.
Summary: This is somewhat complex(annoying) as it involves directly tracking the uses within each of the callgraph nodes, and updating them as needed during inlining. The benefit of this is that we can have a more exact cost model, enable inlining some otherwise non-inlinable cases, and also ensure that newly dead callables are properly disposed of.

Differential Revision: https://reviews.llvm.org/D75476
2020-03-18 13:10:41 -07:00
River Riddle 34d0d6ba74 [mlir][DialectConversion] Print the operation being legalized if it has no regions
This helps when looking at the debug log and understanding what properties the invalid operation has when legalization fails.
2020-03-17 21:05:58 -07:00
River Riddle 3145427dd7 [mlir][NFC] Replace all usages of PatternMatchResult with LogicalResult
This also replaces usages of matchSuccess/matchFailure with success/failure respectively.

Differential Revision: https://reviews.llvm.org/D76313
2020-03-17 20:21:32 -07:00
Rob Suderman 4d60f47b08 [mlir][NFC] Renamed VectorOps to Vector
Summary: Renamed VectorOps to Vector to avoid the redundant Ops suffix.

Differential Revision: https://reviews.llvm.org/D76317
2020-03-17 15:28:08 -07:00
River Riddle 5267f5e6b4 [mlir] Add a hook to PatternRewriter to allow for patterns to notify why a match failed.
Summary:
This revision adds a new hook, `notifyMatchFailure`, that allows for notifying the rewriter that a match failure is coming with the provided reason. This hook takes as a parameter a callback that fills a `Diagnostic` instance with the reason why the match failed. This allows for the rewriter to decide how this information can be displayed to the end-user, and may completely ignore it if desired(opt mode). For now, DialectConversion is updated to include this information in the debug output.

Differential Revision: https://reviews.llvm.org/D76203
2020-03-17 12:12:21 -07:00
River Riddle bd5941b9ce [mlir] Remove the PatternState class and simplify PatternMatchResult.
Summary: PatternState was a mechanism to pass state between the match and rewrite calls of a RewritePattern. With the rise of matchAndRewrite, this class is unused and unnecessary. This revision removes PatternState and simplifies PatternMatchResult to just be a LogicalResult. A future revision will replace all usages of PatternMatchResult/matchSuccess/matchFailure with LogicalResult equivalents.

Differential Revision: https://reviews.llvm.org/D76202
2020-03-16 17:55:54 -07:00
Uday Bondhugula d811aee5d9 [MLIR][NFC] update/clean up affine PDT, related utils, its test case
- rename vars that had inst suffixes (due to ops earlier being
  known as insts); other renames for better readability
- drop unnecessary matches in test cases
- iterate without block terminator
- comment/doc updates
- instBodySkew -> affineForOpBodySkew

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D76214
2020-03-17 06:12:16 +05:30
River Riddle 43959a2592 [mlir][NFC] Move the LoopLike interface out of Transforms/ and into Interfaces/
Differential Revision: https://reviews.llvm.org/D76155
2020-03-14 13:37:56 -07:00
Uday Bondhugula bf0cc6b328 [mlir][NFC] modernize / clean up some loop transform utils, affine analysis utils
Summary:
- remove stale declarations on flat affine constraints
- avoid allocating small vectors where possible
- clean up code comments, rename some variables

Differential Revision: https://reviews.llvm.org/D76117
2020-03-13 21:16:05 -07:00
Rob Suderman 40f4a9fdaa [mlir][NFC] Removed unnecessary StandardOp includes
Summary: A number of transform import StandardOps despite not being dependent on it. Cleaned it up to better understand what dialects each of these transforms depend on.

Differential Revision: https://reviews.llvm.org/D76112
2020-03-12 18:31:09 -07:00
River Riddle 0ddba0bd59 [mlir][SideEffects] Replace HasNoSideEffect with the memory effect interfaces.
HasNoSideEffect can now be implemented using the MemoryEffectInterface, removing the need to check multiple things for the same information. This also removes an easy foot-gun for users as 'Operation::hasNoSideEffect' would ignore operations that dynamically, or recursively, have no side effects. This also leads to an immediate improvement in some of the existing users, such as DCE, now that they have access to more information.

Differential Revision: https://reviews.llvm.org/D76036
2020-03-12 14:26:15 -07:00
River Riddle 907403f342 [mlir] Add a new `ConstantLike` trait to better identify operations that represent a "constant".
The current mechanism for identifying is a bit hacky and extremely adhoc, i.e. we explicit check 1-result, 0-operand, no side-effect, and always foldable and then assume that this is a constant. Adding a trait adds structure to this, and makes checking for a constant much more efficient as we can guarantee that all of these things have already been verified.

Differential Revision: https://reviews.llvm.org/D76020
2020-03-12 14:26:15 -07:00
River Riddle d5f53253a0 [mlir][SideEffects] Mark the CFG only terminator operations as NoSideEffect
These terminator operations don't really have any side effects, and this allows for more accurate side-effect analysis for region operations. For example, currently we can't detect like a loop.for or affine.for are dead because the affine.terminator is "side effecting".

Note: Marking as NoSideEffect doesn't mean that these operations can be opaquely erased.

Differential Revision: https://reviews.llvm.org/D75888
2020-03-12 14:26:14 -07:00
Tim Shen d00f5632f3 [mlir] Add a simplifying wrapper for generateCopy and expose it.
Summary:
affineDataCopyGenerate is a monolithinc function that
combines several steps for good reasons, but it makes customizing
the behaivor even harder. The major two steps by affineDataCopyGenerate are:
a) Identify interesting memrefs and collect their uses.
b) Create new buffers to forward these uses.

Step (a) actually has requires tremendous customization options. One could see
that from the recently added filterMemRef parameter.

This patch adds a function that only does (b), in the hope that (a)
can be directly implemented by the callers. In fact, (a) is quite
simple if the caller has only one buffer to consider, or even one use.

Differential Revision: https://reviews.llvm.org/D75965
2020-03-11 16:22:31 -07:00
Tim Shen ced0dd8e51 [MLIR] Guard DMA-specific logic with DMA option
Differential Revision: https://reviews.llvm.org/D75963
2020-03-11 11:23:13 -07:00
River Riddle 153720a0a5 [mlir][NFC] Move the interfaces and traits for side effects out of IR/ to Interfaces/
Summary:
Interfaces/ is the designated directory for these types of interfaces, and also removes the need for including them directly in IR/.

Differential Revision: https://reviews.llvm.org/D75886
2020-03-10 12:45:45 -07:00
River Riddle 7ce1e7ab07 [mlir][NFC] Move the operation interfaces out of Analysis/ and into a new Interfaces/ directory.
The interfaces themselves aren't really analyses, they may be used by analyses though. Having them in Analysis can also create cyclic dependencies if an analysis depends on a specific dialect, that also provides one of the interfaces.

Differential Revision: https://reviews.llvm.org/D75867
2020-03-10 12:45:45 -07:00
River Riddle b10c662514 [mlir][SideEffects] Replace the old SideEffects dialect interface with the newly added op interfaces/traits.
Summary:
The old interface was a temporary stopgap to allow for implementing simple LICM that took side effects of region operations into account. Now that MLIR has proper support for specifying memory effects, this interface can be deleted.

Differential Revision: https://reviews.llvm.org/D74441
2020-03-09 16:02:21 -07:00
Uday Bondhugula 82e9160aab [MLIR][Affine] NFC: add convenience method for affine data copy for a loop body
add convenience method for affine data copy generation for a loop body

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Differential Revision: https://reviews.llvm.org/D75822
2020-03-09 04:23:54 +00:00
Valentin Churavy 7c64f6bf52 [MLIR] Add support for libMLIR.so
Putting this up mainly for discussion on
how this should be done. I am interested in MLIR from
the Julia side and we currently have a strong preference
to dynamically linking against the LLVM shared library,
and would like to have a MLIR shared library.

This patch adds a new cmake function add_mlir_library()
which accumulates a list of targets to be compiled into
libMLIR.so.  Note that not all libraries make sense to
be compiled into libMLIR.so.  In particular, we want
to avoid libraries which primarily exist to support
certain tools (such as mlir-opt and mlir-cpu-runner).

Note that the resulting libMLIR.so depends on LLVM, but
does not contain any LLVM components.  As a result, it
is necessary to link with libLLVM.so to avoid linkage
errors. So, libMLIR.so requires LLVM_BUILD_LLVM_DYLIB=on

FYI, Currently it appears that LLVM_LINK_LLVM_DYLIB is broken
because mlir-tblgen is linked against libLLVM.so and
and independent LLVM components.

Previous version of this patch broke depencies on TableGen
targets.  This appears to be because it compiled all
libraries to OBJECT libraries (probably because cmake
is generating different target names).  Avoiding object
libraries results in correct dependencies.

(updated by Stephen Neuendorffer)

Differential Revision: https://reviews.llvm.org/D73130
2020-03-06 13:25:18 -08:00
Stephen Neuendorffer 4594d0e943 [MLIR] Move from add_dependencies() to DEPENDS
add_llvm_library and add_llvm_executable may need to create new targets with
appropriate dependencies.  As a result, it is not sufficient in some
configurations (namely LLVM_BUILD_LLVM_DYLIB=on) to only call
add_dependencies().  Instead, the explicit TableGen dependencies must
be passed to add_llvm_library() or add_llvm_executable() using the DEPENDS
keyword.

Differential Revision: https://reviews.llvm.org/D74930
2020-03-06 13:25:17 -08:00
Stephen Neuendorffer 1c82dd39f9 [MLIR] Ensure that target_link_libraries() always has a keyword.
CMake allows calling target_link_libraries() without a keyword,
but this usage is not preferred when also called with a keyword,
and has surprising behavior.  This patch explicitly specifies a
keyword when using target_link_libraries().

Differential Revision: https://reviews.llvm.org/D75725
2020-03-06 09:14:01 -08:00
River Riddle cb1777127c [mlir] Remove successor operands from the Operation class
Summary:
This revision removes all of the functionality related to successor operands on the core Operation class. This greatly simplifies a lot of handling of operands, as well as successors. For example, DialectConversion no longer needs a special "matchAndRewrite" for branching terminator operations.(Note, the existing method was also broken for operations with variadic successors!!)

This also enables terminator operations to define their own relationships with successor arguments, instead of the hardcoded "pass-through" behavior that exists today.

Differential Revision: https://reviews.llvm.org/D75318
2020-03-05 12:53:02 -08:00
River Riddle 988249a506 [mlir] Refactor a few users to no longer rely on the successor operand API of Operation.
The existing API for successor operands on operations is in the process of being removed. This revision simplifies a later one that completely removes the existing API.

Differential Revision: https://reviews.llvm.org/D75316
2020-03-05 12:51:59 -08:00
Matthias Kramm 7a25bd1d19 [mlir][DialectConversion] Abort early if a subregion has a disconnected CFG.
Summary:
Make computeConversionSet bubble up errors from nested regions. Note
that this doesn't change top-level behavior - since the nested region
calls emitError, the error was visible before, just not surfaced as
quickly.

Differential Revision: https://reviews.llvm.org/D75369
2020-03-02 09:28:21 -08:00
River Riddle de5a81b102 [mlir] Update several usages of IntegerType to properly handled unsignedness.
Summary: For example, DenseElementsAttr currently does not properly round-trip unsigned integer values.

Differential Revision: https://reviews.llvm.org/D75374
2020-03-02 09:19:26 -08:00
Stephen Neuendorffer 798e661567 Revert "[MLIR] Move from using target_link_libraries to LINK_LIBS for llvm libraries."
This reverts commit 7a6c689771.
This breaks the build with cmake 3.13.4, but succeeds with cmake 3.15.3
2020-02-29 11:52:08 -08:00
Stephen Neuendorffer d675df0379 Revert "[MLIR] Move from add_dependencies() to DEPENDS"
This reverts commit 31e07d716a.
2020-02-29 11:52:08 -08:00
Stephen Neuendorffer dd046c9612 Revert "[MLIR] Add support for libMLIR.so"
This reverts commit e17d9c11d4.
It breaks the build.
2020-02-29 11:09:21 -08:00
Valentin Churavy e17d9c11d4 [MLIR] Add support for libMLIR.so
Putting this up mainly for discussion on
how this should be done. I am interested in MLIR from
the Julia side and we currently have a strong preference
to dynamically linking against the LLVM shared library,
and would like to have a MLIR shared library.

This patch adds a new cmake function add_mlir_library()
which accumulates a list of targets to be compiled into
libMLIR.so.  Note that not all libraries make sense to
be compiled into libMLIR.so.  In particular, we want
to avoid libraries which primarily exist to support
certain tools (such as mlir-opt and mlir-cpu-runner).

Note that the resulting libMLIR.so depends on LLVM, but
does not contain any LLVM components.  As a result, it
is necessary to link with libLLVM.so to avoid linkage
errors. So, libMLIR.so requires LLVM_BUILD_LLVM_DYLIB=on

FYI, Currently it appears that LLVM_LINK_LLVM_DYLIB is broken
because mlir-tblgen is linked against libLLVM.so and
and independent LLVM components.

Previous version of this patch broke depencies on TableGen
targets.  This appears to be because it compiled all
libraries to OBJECT libraries (probably because cmake
is generating different target names).  Avoiding object
libraries results in correct dependencies.

(updated by Stephen Neuendorffer)

Differential Revision: https://reviews.llvm.org/D73130
2020-02-29 10:47:27 -08:00
Stephen Neuendorffer 31e07d716a [MLIR] Move from add_dependencies() to DEPENDS
add_llvm_library and add_llvm_executable may need to create new targets with
appropriate dependencies.  As a result, it is not sufficient in some
configurations (namely LLVM_BUILD_LLVM_DYLIB=on) to only call
add_dependencies().  Instead, the explicit TableGen dependencies must
be passed to add_llvm_library() or add_llvm_executable() using the DEPENDS
keyword.

Differential Revision: https://reviews.llvm.org/D74930
2020-02-29 10:47:27 -08:00
Stephen Neuendorffer 7a6c689771 [MLIR] Move from using target_link_libraries to LINK_LIBS for llvm libraries.
When compiling libLLVM.so, add_llvm_library() manipulates the link libraries
being used.  This means that when using add_llvm_library(), we need to pass
the list of libraries to be linked (using the LINK_LIBS keyword) instead of
using the standard target_link_libraries call.  This is preparation for
properly dealing with creating libMLIR.so as well.

Differential Revision: https://reviews.llvm.org/D74864
2020-02-29 10:47:26 -08:00
Stephen Neuendorffer dc1056a3f1 Revert "[MLIR] Move from using target_link_libraries to LINK_LIBS for llvm libraries."
This reverts commit 2f265e3528.
2020-02-28 14:13:30 -08:00
Stephen Neuendorffer 67f2a43cf8 Revert "[MLIR] Move from add_dependencies() to DEPENDS"
This reverts commit 8a2b86b2c2.
2020-02-28 12:17:40 -08:00
Stephen Neuendorffer c6f3fc4999 Revert "[MLIR] Add support for libMLIR.so"
This reverts commit 1246e86716.
2020-02-28 12:17:39 -08:00
Valentin Churavy 1246e86716 [MLIR] Add support for libMLIR.so
Putting this up mainly for discussion on
how this should be done. I am interested in MLIR from
the Julia side and we currently have a strong preference
to dynamically linking against the LLVM shared library,
and would like to have a MLIR shared library.

This patch adds a new cmake function add_mlir_library()
which accumulates a list of targets to be compiled into
libMLIR.so.  Note that not all libraries make sense to
be compiled into libMLIR.so.  In particular, we want
to avoid libraries which primarily exist to support
certain tools (such as mlir-opt and mlir-cpu-runner).

Note that the resulting libMLIR.so depends on LLVM, but
does not contain any LLVM components.  As a result, it
is necessary to link with libLLVM.so to avoid linkage
errors. So, libMLIR.so requires LLVM_BUILD_LLVM_DYLIB=on

FYI, Currently it appears that LLVM_LINK_LLVM_DYLIB is broken
because mlir-tblgen is linked against libLLVM.so and
and independent LLVM components

(updated by Stephen Neuendorffer)

Differential Revision: https://reviews.llvm.org/D73130
2020-02-28 11:35:19 -08:00
Stephen Neuendorffer 8a2b86b2c2 [MLIR] Move from add_dependencies() to DEPENDS
add_llvm_library and add_llvm_executable may need to create new targets with
appropriate dependencies.  As a result, it is not sufficient in some
configurations (namely LLVM_BUILD_LLVM_DYLIB=on) to only call
add_dependencies().  Instead, the explicit TableGen dependencies must
be passed to add_llvm_library() or add_llvm_executable() using the DEPENDS
keyword.

Differential Revision: https://reviews.llvm.org/D74930
2020-02-28 11:35:18 -08:00
Stephen Neuendorffer 2f265e3528 [MLIR] Move from using target_link_libraries to LINK_LIBS for llvm libraries.
When compiling libLLVM.so, add_llvm_library() manipulates the link libraries
being used.  This means that when using add_llvm_library(), we need to pass
the list of libraries to be linked (using the LINK_LIBS keyword) instead of
using the standard target_link_libraries call.  This is preparation for
properly dealing with creating libMLIR.so as well.

Differential Revision: https://reviews.llvm.org/D74864
2020-02-28 11:35:17 -08:00
Rob Suderman 69d757c0e8 Move StandardOps/Ops.h to StandardOps/IR/Ops.h
Summary:
NFC - Moved StandardOps/Ops.h to a StandardOps/IR dir to better match surrounding
directories. This is to match other dialects, and prepare for moving StandardOps
related transforms in out for Transforms and into StandardOps/Transforms.

Differential Revision: https://reviews.llvm.org/D74940
2020-02-21 11:58:47 -08:00
Lei Zhang 35b685270b [mlir] Add a signedness semantics bit to IntegerType
Thus far IntegerType has been signless: a value of IntegerType does
not have a sign intrinsically and it's up to the specific operation
to decide how to interpret those bits. For example, std.addi does
two's complement arithmetic, and std.divis/std.diviu treats the first
bit as a sign.

This design choice was made some time ago when we did't have lots
of dialects and dialects were more rigid. Today we have much more
extensible infrastructure and different dialect may want different
modelling over integer signedness. So while we can say we want
signless integers in the standard dialect, we cannot dictate for
others. Requiring each dialect to model the signedness semantics
with another set of custom types is duplicating the functionality
everywhere, considering the fundamental role integer types play.

This CL extends the IntegerType with a signedness semantics bit.
This gives each dialect an option to opt in signedness semantics
if that's what they want and helps code sharing. The parser is
modified to recognize `si[1-9][0-9]*` and `ui[1-9][0-9]*` as
signed and unsigned integer types, respectively, leaving the
original `i[1-9][0-9]*` to continue to mean no indication over
signedness semantics. All existing dialects are not affected (yet)
as this is a feature to opt in.

More discussions can be found at:

https://groups.google.com/a/tensorflow.org/d/msg/mlir/XmkV8HOPWpo/7O4X0Nb_AQAJ

Differential Revision: https://reviews.llvm.org/D72533
2020-02-21 09:16:54 -05:00
Diego Caballero 376c68539c [mlir][NFC] Fix 'gatherLoops' utility
It replaces DenseMap output with a SmallVector and it
removes empty loop levels from the output.

Reviewed By: andydavis1, mehdi_amini

Differential Revision: https://reviews.llvm.org/D74658
2020-02-19 10:48:14 -08:00
River Riddle 0d7ff220ed [mlir] Refactor TypeConverter to add conversions without inheritance
Summary:
This revision refactors the TypeConverter class to not use inheritance to add type conversions. It instead moves to a registration based system, where conversion callbacks are added to the converter with `addConversion`. This method takes a conversion callback, which must be convertible to any of the following forms(where `T` is a class derived from `Type`:
* Optional<Type> (T type)
   - This form represents a 1-1 type conversion. It should return nullptr
     or `llvm::None` to signify failure. If `llvm::None` is returned, the
     converter is allowed to try another conversion function to perform
     the conversion.
* Optional<LogicalResult>(T type, SmallVectorImpl<Type> &results)
   - This form represents a 1-N type conversion. It should return
     `failure` or `llvm::None` to signify a failed conversion. If the new
     set of types is empty, the type is removed and any usages of the
     existing value are expected to be removed during conversion. If
     `llvm::None` is returned, the converter is allowed to try another
     conversion function to perform the conversion.

When attempting to convert a type, the TypeConverter walks each of the registered converters starting with the one registered most recently.

Differential Revision: https://reviews.llvm.org/D74584
2020-02-18 16:17:48 -08:00
Diego Caballero d7058acc14 [mlir] Add MemRef filter to affine data copy optimization
This patch extends affine data copy optimization utility with an
optional memref filter argument. When the memref filter is used, data
copy optimization will only generate copies for such a memref.

Note: this patch is just porting the memref filter feature from Uday's
'hop' branch: https://github.com/bondhugula/llvm-project/tree/hop.

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D74342
2020-02-14 13:41:45 -08:00
Mehdi Amini c64770506b Remove static registration for dialects, and the "alwayslink" hack for passes
In the previous state, we were relying on forcing the linker to include
all libraries in the final binary and the global initializer to self-register
every piece of the system. This change help moving away from this model, and
allow users to compose pieces more freely. The current change is only "fixing"
the dialect registration and avoiding relying on "whole link" for the passes.
The translation is still relying on the global registry, and some refactoring
is needed to make this all more convenient.

Differential Revision: https://reviews.llvm.org/D74461
2020-02-12 09:13:02 +00:00
Andy Davis 40b2eb3530 [mlir][AffineOps] Adds affine loop fusion transformation function to LoopFusionUtils.
Summary:
Adds affine loop fusion transformation function to LoopFusionUtils.
Updates TestLoopFusion utility to run loop fusion transformation until a fixed point is reached.
Adds unit tests to test the transformation.
Includes ASAN bug fix for D73190.

Reviewers: bondhugula, dcaballe

Reviewed By: bondhugula, dcaballe

Subscribers: mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D74330
2020-02-11 13:56:26 -08:00
Stephen Neuendorffer b80a9ca8cb [MLIR] Allow non-binary operations to be commutative
NFC for binary operations.

Differential Revision: https://reviews.llvm.org/D73670
2020-02-10 10:23:55 -08:00
Alex Zinenko 5a1778057f [mlir] use unpacked memref descriptors at function boundaries
The existing (default) calling convention for memrefs in standard-to-LLVM
conversion was motivated by interfacing with LLVM IR produced from C sources.
In particular, it passes a pointer to the memref descriptor structure when
calling the function. Therefore, the descriptor is allocated on stack before
the call. This convention leads to several problems. PR44644 indicates a
problem with stack exhaustion when calling functions with memref-typed
arguments in a loop. Allocating outside of the loop may lead to concurrent
access problems in case the loop is parallel. When targeting GPUs, the contents
of the stack-allocated memory for the descriptor (passed by pointer) needs to
be explicitly copied to the device. Using an aggregate type makes it impossible
to attach pointer-specific argument attributes pertaining to alignment and
aliasing in the LLVM dialect.

Change the default calling convention for memrefs in standard-to-LLVM
conversion to transform a memref into a list of arguments, each of primitive
type, that are comprised in the memref descriptor. This avoids stack allocation
for ranked memrefs (and thus stack exhaustion and potential concurrent access
problems) and simplifies the device function invocation on GPUs.

Provide an option in the standard-to-LLVM conversion to generate auxiliary
wrapper function with the same interface as the previous calling convention,
compatible with LLVM IR porduced from C sources. These auxiliary functions
pack the individual values into a descriptor structure or unpack it. They also
handle descriptor stack allocation if necessary, serving as an allocation
scope: the memory reserved by `alloca` will be freed on exiting the auxiliary
function.

The effect of this change on MLIR-generated only LLVM IR is minimal. When
interfacing MLIR-generated LLVM IR with C-generated LLVM IR, the integration
only needs to require auxiliary functions and change the function name to call
the wrapper function instead of the original function.

This also opens the door to forwarding aliasing and alignment information from
memrefs to LLVM IR pointers in the standrd-to-LLVM conversion.
2020-02-10 15:03:43 +01:00
River Riddle abe3e5babd [mlir] Add support for generating debug locations from intermediate levels of the IR.
Summary:
This revision adds a utility to generate debug locations from the IR during compilation, by snapshotting to a output stream and using the locations that operations were dumped in that stream. The new locations may either;
* Replace the original location of the operation.

old:
   loc("original_source.cpp":1:1)
new:
   loc("snapshot_source.mlir":10:10)

* Fuse with the original locations as NamedLocs with a specific tag.

old:
    loc("original_source.cpp":1:1)
new:
    loc(fused["original_source.cpp":1:1, "snapshot"("snapshot_source.mlir":10:10)])

This feature may be used by a debugger to display the code at various different levels of the IR. It would also be able to show the different levels of IR attached to a specific source line in the original source file.

This feature may also be used to generate locations for operations generated during compilation, that don't necessarily have a user source location to attach to.

This requires changes in the printer to track the locations of operations emitted in the stream. Moving forward we need to properly(and efficiently) track the number of newlines emitted to the stream during printing.

Differential Revision: https://reviews.llvm.org/D74019
2020-02-08 15:11:29 -08:00
River Riddle 5c159b91a2 [mlir] Add a utility method on CallOpInterface for resolving the callable.
Summary: This is the most common operation performed on a CallOpInterface. This just moves the existing functionality from the CallGraph so that other users can access it.

Differential Revision: https://reviews.llvm.org/D74250
2020-02-08 10:44:29 -08:00
River Riddle 1eaa31ce0e [mlir][DialectConversion] Change erroneous return to a continue
This fixes a nasty bug where the loop would return prematurely when
notifying the argument converter that an operation was removed.
2020-02-06 17:55:14 -08:00
Mehdi Amini 2724ada8d2 Revert "[mlir] Adds affine loop fusion transformation function to LoopFusionUtils."
This reverts commit 64871f778d.

ASAN indicates a use-after-free in in mlir::canFuseLoops(mlir::AffineForOp, mlir::AffineForOp, unsigned int, mlir::ComputationSliceState*) lib/Transforms/Utils/LoopFusionUtils.cpp:202:41
2020-02-06 16:46:28 +00:00
River Riddle c33d6970e0 [mlir] Add support for basic location translation to LLVM.
Summary:
This revision adds basic support for emitting line table information when exporting to LLVMIR. We don't yet have a story for supporting all of the LLVM debug metadata, so this revision stubs some features(like subprograms) to enable emitting line tables.

Differential Revision: https://reviews.llvm.org/D73934
2020-02-05 17:41:51 -08:00
Andy Davis 64871f778d [mlir] Adds affine loop fusion transformation function to LoopFusionUtils.
Summary:
Adds affine loop fusion transformation function to LoopFusionUtils.
Updates TestLoopFusion utility to run loop fusion transformation until a fixed point is reached.
Adds unit tests to test the transformation.

Reviewers: bondhugula, dcaballe, nicolasvasilache

Reviewed By: bondhugula, dcaballe

Subscribers: Joonsoo, merge_guards_bot, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73190
2020-02-05 16:01:06 -08:00
Stephen Neuendorffer 7b7e505813 [MLIR] Break cyclic dependencies with MLIRAnalysis
Summary:

MLIRAnalysis depended on MLIRVectorOps
MLIRVectorOps depended on MLIRAnalysis for Loop information.

Both of these can be solved by factoring out libraries related to loop
analysis into their own library. The new MLIRLoopAnalysis might be
better off with the Loop Dialect in the future.

Reviewers: nicolasvasilache, rriddle!, mehdi_amini

Reviewed By: mehdi_amini

Subscribers: Joonsoo, vchuravy, merge_guards_bot, mgorny, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73655
2020-02-05 11:27:28 -08:00
Stephen Neuendorffer b3dd31711a [MLIR] Move test passes out of lib/Analysis
Summary:

This breaks a cyclic library dependency where MLIRPass used the verifier
in MLIRAnalysis, but MLIRAnalysis also contained passes used for testing.
The presence of the test passes here is archaeology, predating
test/lib/Transform.

Reviewers: rriddle

Reviewed By: rriddle

Subscribers: merge_guards_bot, mgorny, mehdi_amini, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, liufengdb, Joonsoo, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D74067
2020-02-05 11:26:49 -08:00
Dimitry Andric 31fd112eb4 Fix x86 32bits MLIR build (NFC)
This is fixing a build error:

error: non-constant-expression cannot be narrowed from type 'unsigned int' to 'Region::iterator::difference_type' (aka 'int') in initializer list

Fix pr44767
2020-02-04 23:58:58 +00:00
Jacques Pienaar 1544cf2d7c [mlir] Fix errors in release & no-assert
Seen on gcc 8, in release mode & assertions off warnings about logger,
made all statements referencing logger inside LLVM_DEBUG blocks and
ifdef a few variables only used in debug.

This is mechanical fix to get CI green.
2020-02-01 08:57:01 -08:00
River Riddle 75c328179e [mlir][DialectConversion] Remove invalid NDEBUG wrapper.
The functions are used, but empty when NDEBUG is set.
2020-01-31 13:26:49 -08:00
River Riddle 4948b8b3cf [mlir][NFC] Refactor DialectConversion debug logging
Summary:
This revision beefs up the debug logging within dialect conversion. Given the nature of multi-level legalization, and legalization in general, it is one of the harder pieces of infrastructure to debug. This revision adds nice formatting to make the output log easier to parse:

```
Legalizing operation : 'std.constant'(0x608000002420) {
  * Fold {
  } -> FAILURE : unable to fold

  * Pattern : 'std.constant -> ()' {
  } -> FAILURE : pattern failed to match

  * Pattern : 'std.constant -> ()' {
  } -> FAILURE : pattern failed to match

  * Pattern : 'std.constant -> (spv.constant)' {
    ** Insert  : 'spv.constant'(0x608000002c20)
    ** Replace : 'std.constant'(0x608000002420)

    //===-------------------------------------------===//
    Legalizing operation : 'spv.constant'(0x608000002c20) {
    } -> SUCCESS : operation marked legal by the target
    //===-------------------------------------------===//
  } -> SUCCESS : pattern applied successfully
} -> SUCCESS
```

Differential Revision: https://reviews.llvm.org/D73747
2020-01-31 12:07:17 -08:00
Tim Shen 3ccaac3cdd [mlir] Add MemRefTypeBuilder and refactor some MemRefType::get().
The refactored MemRefType::get() calls all intend to clone from another
memref type, with some modifications. In fact, some calls dropped memory space
during the cloning. Migrate them to the cloning API so that nothing gets
dropped if they are not explicitly listed.

It's close to NFC but not quite, as it helps with propagating memory spaces in
some places.

Differential Revision: https://reviews.llvm.org/D73296
2020-01-30 23:30:46 -08:00
River Riddle 6b9e2be8ec [mlir][NFC] Explicitly initialize dynamic legality when setting op
action.
2020-01-30 00:21:32 -08:00
Benjamin Kramer adcd026838 Make llvm::StringRef to std::string conversions explicit.
This is how it should've been and brings it more in line with
std::string_view. There should be no functional change here.

This is mostly mechanical from a custom clang-tidy check, with a lot of
manual fixups. It uncovers a lot of minor inefficiencies.

This doesn't actually modify StringRef yet, I'll do that in a follow-up.
2020-01-28 23:25:25 +01:00
River Riddle b276dec5b6 [mlir] Add a DCE pass for dead symbols.
Summary: This pass deletes all symbols that are found to be unreachable. This is done by computing the set of operations that are known to be live, propagating that liveness to other symbols, and then deleting all symbols that are not within this live set.

Differential Revision: https://reviews.llvm.org/D72482
2020-01-27 23:29:30 -08:00
River Riddle aff4ed7326 [mlir][NFC] Update Operation::getResultTypes to use ArrayRef<Type> instead of iterator_range.
Summary: The new internal representation of operation results now allows for accessing the result types to be more efficient. Changing the API to ArrayRef is more efficient and removes the need to explicitly materialize vectors in several places.

Differential Revision: https://reviews.llvm.org/D73429
2020-01-27 19:57:48 -08:00
River Riddle ce674b131b [mlir] Add support for marking 'unknown' operations as dynamically legal.
Summary: This allows for providing a default "catchall" legality check that is not dependent on specific operations or dialects. For example, this can be useful to check legality based on the specific types of operation operands or results.

Differential Revision: https://reviews.llvm.org/D73379
2020-01-27 19:50:52 -08:00
Diego Caballero 6fb3d59746 [mlir] Remove 'valuesToRemoveIfDead' from PatternRewriter API
Summary:
Remove 'valuesToRemoveIfDead' from PatternRewriter API. The removal
functionality wasn't implemented and we decided [1] not to implement it in
favor of having more powerful DCE approaches.

[1] https://github.com/tensorflow/mlir/pull/212

Reviewers: rriddle, bondhugula

Reviewed By: rriddle

Subscribers: liufengdb, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72545
2020-01-27 14:00:34 -08:00
Mehdi Amini 308571074c Mass update the MLIR license header to mention "Part of the LLVM project"
This is an artifact from merging MLIR into LLVM, the file headers are
now aligned with the rest of the project.
2020-01-26 03:58:30 +00:00
Ahmed Taei 8d1ed2940d [mlir] Fix vectorize transform crashing on none-op operand 2020-01-23 09:57:16 -08:00
Kazuaki Ishizaki fc817b09e2 [mlir] NFC: Fix trivial typos in comments
Differential Revision: https://reviews.llvm.org/D73012
2020-01-20 03:17:03 +00:00
aartbik 0361a961c2 [mlir] [VectorOps] Rename Utils.h into VectorUtils.h
Summary:
First step towards the consolidation
of a lot of vector related utilities
that are now all over the place
(or even duplicated).

Reviewers: nicolasvasilache, andydavis1

Reviewed By: nicolasvasilache, andydavis1

Subscribers: merge_guards_bot, mehdi_amini, rriddle, jpienaar, burmako, shauheen, antiagainst, arpith-jacob, mgester, lucyrfox, liufengdb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72955
2020-01-17 13:39:34 -08:00
Benjamin Kramer df186507e1 Make helper functions static or move them into anonymous namespaces. NFC. 2020-01-14 14:06:37 +01:00
River Riddle c774840492 [mlir] Update the CallGraph for nested symbol references, and simplify CallableOpInterface
Summary:
This enables tracking calls that cross symbol table boundaries. It also simplifies some of the implementation details of CallableOpInterface, i.e. there can only be one region within the callable operation.

Depends On D72042

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D72043
2020-01-13 15:51:28 -08:00
River Riddle cb89c7e3f7 [mlir] Remove unnecessary assert for single region.
This was left over debugging.
2020-01-13 13:55:50 -08:00
River Riddle 2bdf33cc4c [mlir] NFC: Remove Value::operator* and Value::operator-> now that Value is properly value-typed.
Summary: These were temporary methods used to simplify the transition.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D72548
2020-01-11 08:54:39 -08:00
River Riddle 0d6ebb4f0d [mlir] Refactor operation results to use a single use list for all results of the operation.
Summary: A new class is added, IRMultiObjectWithUseList, that allows for representing an IR use list that holds multiple sub values(used in this case for OpResults). This class provides all of the same functionality as the base IRObjectWithUseList, but for specific sub-values. This saves a word per operation result and is a necessary step in optimizing the layout of operation results. For now the use list is placed on the operation itself, so zero-result operations grow by a word. When the work for optimizing layout is finished, this can be moved back to being a trailing object based on memory/runtime benchmarking.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D71955
2019-12-30 20:50:07 -08:00
River Riddle e62a69561f NFC: Replace ValuePtr with Value and remove it now that Value is value-typed.
ValuePtr was a temporary typedef during the transition to a value-typed Value.

PiperOrigin-RevId: 286945714
2019-12-23 16:36:53 -08:00
River Riddle 5d5bd2e1da Change the `notifyRootUpdated` API to be transaction based.
This means that in-place, or root, updates need to use explicit calls to `startRootUpdate`, `finalizeRootUpdate`, and `cancelRootUpdate`. The major benefit of this change is that it enables in-place updates in DialectConversion, which simplifies the FuncOp pattern for example. The major downside to this is that the cases that *may* modify an operation in-place will need an explicit cancel on the failure branches(assuming that they started an update before attempting the transformation).

PiperOrigin-RevId: 286933674
2019-12-23 16:26:15 -08:00
Mehdi Amini 56222a0694 Adjust License.txt file to use the LLVM license
PiperOrigin-RevId: 286906740
2019-12-23 15:33:37 -08:00
River Riddle 35807bc4c5 NFC: Introduce new ValuePtr/ValueRef typedefs to simplify the transition to Value being value-typed.
This is an initial step to refactoring the representation of OpResult as proposed in: https://groups.google.com/a/tensorflow.org/g/mlir/c/XXzzKhqqF_0/m/v6bKb08WCgAJ

This change will make it much simpler to incrementally transition all of the existing code to use value-typed semantics.

PiperOrigin-RevId: 286844725
2019-12-22 22:00:23 -08:00
Manuel Freiberger 22954a0e40 Add integer bit-shift operations to the standard dialect.
Rename the 'shlis' operation in the standard dialect to 'shift_left'. Add tests
for this operation (these have been missing so far) and add a lowering to the
'shl' operation in the LLVM dialect.

Add also 'shift_right_signed' (lowered to LLVM's 'ashr') and 'shift_right_unsigned'
(lowered to 'lshr').

The original plan was to name these operations 'shift.left', 'shift.right.signed'
and 'shift.right.unsigned'. This works if the operations are prefixed with 'std.'
in MLIR assembly. Unfortunately during import the short form is ambigous with
operations from a hypothetical 'shift' dialect. The best solution seems to omit
dots in standard operations for now.

Closes tensorflow/mlir#226

PiperOrigin-RevId: 286803388
2019-12-22 10:02:13 -08:00
Sean Silva 553f794b6f Add a couple useful LLVM_DEBUG's to the inliner.
This makes it easier to narrow down on ops that are preventing inlining.

PiperOrigin-RevId: 286243868
2019-12-18 12:33:30 -08:00
River Riddle 2666b97314 NFC: Cleanup non-conforming usages of namespaces.
* Fixes use of anonymous namespace for static methods.
* Uses explicit qualifiers(mlir::) instead of wrapping the definition with the namespace.

PiperOrigin-RevId: 286222654
2019-12-18 10:46:48 -08:00
Uday Bondhugula 47034c4bc5 Introduce prefetch op: affine -> std -> llvm intrinsic
Introduce affine.prefetch: op to prefetch using a multi-dimensional
subscript on a memref; similar to affine.load but has no effect on
semantics, but only on performance.

Provide lowering through std.prefetch, llvm.prefetch and map to llvm's
prefetch instrinsic. All attributes reflected through the lowering -
locality hint, rw, and instr/data cache.

  affine.prefetch %0[%i, %j + 5], false, 3, true : memref<400x400xi32>

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#225

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/225 from bondhugula:prefetch 4c3b4e93bc64d9a5719504e6d6e1657818a2ead0
PiperOrigin-RevId: 286212997
2019-12-18 10:00:04 -08:00
River Riddle 4562e389a4 NFC: Remove unnecessary 'llvm::' prefix from uses of llvm symbols declared in `mlir` namespace.
Aside from being cleaner, this also makes the codebase more consistent.

PiperOrigin-RevId: 286206974
2019-12-18 09:29:20 -08:00
River Riddle 74278dd01e NFC: Use TypeSwitch to simplify existing code.
PiperOrigin-RevId: 286066371
2019-12-17 14:57:41 -08:00
River Riddle ab610e8a99 Insert signature-converted blocks into a region with a parent operation.
This keeps the IR valid and consistent as it is expected that each block should have a valid parent region/operation. Previously, converted blocks were kept floating without a valid parent region.

PiperOrigin-RevId: 285821687
2019-12-16 12:09:45 -08:00
River Riddle b030e4a4ec Try to fold operations in DialectConversion when trying to legalize.
This change allows for DialectConversion to attempt folding as a mechanism to legalize illegal operations. This also expands folding support in OpBuilder::createOrFold to generate new constants when folding, and also enables it to work in the context of a PatternRewriter.

PiperOrigin-RevId: 285448440
2019-12-13 16:47:26 -08:00
River Riddle 851a8516d3 Make OpBuilder::insert virtual instead of OpBuilder::createOperation.
It is sometimes useful to create operations separately from the builder before insertion as it may be easier to erase them in isolation if necessary. One example use case for this is folding, as we will only want to insert newly generated constant operations on success. This has the added benefit of fixing some silent PatternRewriter failures related to cloning, as the OpBuilder 'clone' methods don't call createOperation.

PiperOrigin-RevId: 285086242
2019-12-11 16:26:45 -08:00
Kazuaki Ishizaki ae05cf27c6 Minor spelling tweaks
Closes tensorflow/mlir#304

PiperOrigin-RevId: 284568358
2019-12-09 09:23:48 -08:00
Uday Bondhugula a63f6e0bf9 Replace spurious SmallVector constructions with ValueRange
Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#305

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/305 from bondhugula:value_range 21d1fae73f549e3c8e72b60876eff1b864cea39c
PiperOrigin-RevId: 284541027
2019-12-09 06:26:33 -08:00
River Riddle d6ee6a0310 Update the builder API to take ValueRange instead of ArrayRef<Value *>
This allows for users to provide operand_range and result_range in builder.create<> calls, instead of requiring an explicit copy into a separate data structure like SmallVector/std::vector.

PiperOrigin-RevId: 284360710
2019-12-07 10:35:41 -08:00
River Riddle 9d1a0c72b4 Add a new ValueRange class.
This class represents a generic abstraction over the different ways to represent a range of Values: ArrayRef<Value *>, operand_range, result_range. This class will allow for removing the many instances of explicit SmallVector<Value *, N> construction. It has the same memory cost as ArrayRef, and only suffers cost from indexing(if+elsing the different underlying representations).

This change only updates a few of the existing usages, with more to be changed in followups; e.g. 'build' API.

PiperOrigin-RevId: 284307996
2019-12-06 20:07:23 -08:00
Alexandre E. Eichenberger 3c69ca1e69 fix examples in comments
Closes tensorflow/mlir#301

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/301 from AlexandreEichenberger:vect-doc-update 7e5418a9101a4bdad2357882fe660b02bba8bd01
PiperOrigin-RevId: 284202462
2019-12-06 09:40:50 -08:00
Kazuaki Ishizaki 84a6182ddd minor spelling tweaks
Closes tensorflow/mlir#290

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/290 from kiszk:spelling_tweaks_201912 9d9afd16a723dd65754a04698b3976f150a6054a
PiperOrigin-RevId: 284169681
2019-12-06 05:59:30 -08:00
River Riddle 33a64540ad Add support for instance specific pass statistics.
Statistics are a way to keep track of what the compiler is doing and how effective various optimizations are. It is useful to see what optimizations are contributing to making a particular program run faster. Pass-instance specific statistics take this even further as you can see the effect of placing a particular pass at specific places within the pass pipeline, e.g. they could help answer questions like "what happens if I run CSE again here".

Statistics can be added to a pass by simply adding members of type 'Pass::Statistics'. This class takes as a constructor arguments: the parent pass pointer, a name, and a description. Statistics can be dumped by the pass manager in a similar manner to how pass timing information is dumped, i.e. via PassManager::enableStatistics programmatically; or -pass-statistics and -pass-statistics-display via the command line pass manager options.

Below is an example:

struct MyPass : public OperationPass<MyPass> {
  Statistic testStat{this, "testStat", "A test statistic"};

  void runOnOperation() {
    ...
    ++testStat;
    ...
  }
};

$ mlir-opt -pass-pipeline='func(my-pass,my-pass)' foo.mlir -pass-statistics

Pipeline Display:
===-------------------------------------------------------------------------===
                         ... Pass statistics report ...
===-------------------------------------------------------------------------===
'func' Pipeline
  MyPass
    (S) 15 testStat - A test statistic
  MyPass
    (S)  6 testStat - A test statistic

List Display:
===-------------------------------------------------------------------------===
                         ... Pass statistics report ...
===-------------------------------------------------------------------------===
MyPass
  (S) 21 testStat - A test statistic

PiperOrigin-RevId: 284022014
2019-12-05 11:53:28 -08:00
River Riddle 6f895bec7d [CSE] NFC: Hash the attribute dictionary pointer instead of the list of attributes.
PiperOrigin-RevId: 283810829
2019-12-04 12:32:08 -08:00
Nicolas Vasilache edfaf925cf Drop MaterializeVectorTransfers in favor of simpler declarative unrolling
Now that we have unrolling as a declarative pattern, we can drop a full pass that has gone stale. In the future we may want to add specific unrolling patterns for VectorTransferReadOp.

PiperOrigin-RevId: 283806880
2019-12-04 12:11:42 -08:00
Alex Zinenko 75175134d4 Loop coalescing: fix pointer chainsing in use-chain traversal
In the replaceAllUsesExcept utility function called from loop coalescing the
iteration over the use-chain is incorrect. The use list nodes (IROperands) have
next/prev links, and bluntly resetting the use would make the loop to continue
on uses of the value that was replaced instead of the original one. As a
result, it could miss the existing uses and update the wrong ones. Make sure we
increment the iterator before updating the use in the loop body.

Reported-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#291.

PiperOrigin-RevId: 283754195
2019-12-04 07:42:29 -08:00
Nicolas Vasilache 5c0c51a997 Refactor dependencies to expose Vector transformations as patterns - NFC
This CL refactors some of the MLIR vector dependencies to allow decoupling VectorOps, vector analysis, vector transformations and vector conversions from each other.
This makes the system more modular and allows extracting VectorToVector into VectorTransforms that do not depend on vector conversions.

This refactoring exhibited a bunch of cyclic library dependencies that have been cleaned up.

PiperOrigin-RevId: 283660308
2019-12-03 17:52:10 -08:00
Diego Caballero 330d1ff00e AffineLoopFusion: Prevent fusion of multi-out-edge producer loops
tensorflow/mlir#162 introduced a bug that
incorrectly allowed fusion of producer loops with multiple outgoing
edges. This commit fixes that problem. It also introduces a new flag to
disable sibling loop fusion so that we can test producer-consumer fusion
in isolation.

Closes tensorflow/mlir#259

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/259 from dcaballe:dcaballe/fix_multi_out_edge_producer_fusion 578d5661705fd5c56c555832d5e0528df88c5282
PiperOrigin-RevId: 283531105
2019-12-03 06:09:50 -08:00
Mahesh Ravishankar bd485afda0 Introduce attributes that specify the final ABI for a spirv::ModuleOp.
To simplify the lowering into SPIR-V, while still respecting the ABI
requirements of SPIR-V/Vulkan, split the process into two
1) While lowering a function to SPIR-V (when the function is an entry
   point function), allow specifying attributes on arguments and
   function itself that describe the ABI of the function.
2) Add a pass that materializes the ABI described in the function.

Two attributes are needed.
1) Attribute on arguments of the entry point function that describe
   the descriptor_set, binding, storage class, etc, of the
   spv.globalVariable this argument will be replaced by
2) Attribute on function that specifies workgroup size, etc. (for now
   only workgroup size).

Add the pass -spirv-lower-abi-attrs to materialize the ABI described
by the attributes.

This change makes the SPIRVBasicTypeConverter class unnecessary and is
removed, further simplifying the SPIR-V lowering path.

PiperOrigin-RevId: 282387587
2019-11-25 11:19:56 -08:00
Jean-Michel Gorius 104777d8e6 Unify vector op names with other dialects.
Change vector op names from VectorFooOp to Vector_FooOp and from
vector::VectorFooOp to vector::FooOp.

Closes tensorflow/mlir#257

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/257 from Kayjukh:master dfc3a0e04114885aaec8740d5951d6984d6e1577
PiperOrigin-RevId: 281967461
2019-11-22 08:24:49 -08:00
River Riddle 4ea92a0586 NFC: Use Region::getBlocks to fix build failure with drop_begin.
PiperOrigin-RevId: 281656603
2019-11-20 19:30:46 -08:00
River Riddle fafb708b9a Merge DCE and unreachable block elimination into a new utility 'simplifyRegions'.
This moves the different canonicalizations of regions into one place and invokes them in the fixed-point iteration of the canonicalizer.

PiperOrigin-RevId: 281617072
2019-11-20 15:53:19 -08:00
Sean Silva e4f83c6c26 Add multi-level DCE pass.
This is a simple multi-level DCE pass that operates pretty generically on
the IR. Its key feature compared to the existing peephole dead op folding
that happens during canonicalization is being able to delete recursively
dead cycles of the use-def graph, including block arguments.

PiperOrigin-RevId: 281568202
2019-11-20 12:55:10 -08:00
Nicolas Vasilache fa14d4f6ab Implement unrolling of vector ops to finer-grained vector ops as a pattern.
This CL uses the pattern rewrite infrastructure to implement a simple VectorOps -> VectorOps legalization strategy to unroll coarse-grained vector operations into finer grained ones.
The transformation is written using local pattern rewrites to allow composition with other rewrites. It proceeds by iteratively introducing fake cast ops and cleaning canonicalizing or lowering them away where appropriate.

This is an example of writing transformations as compositions of local pattern rewrites that should enable us to make them significantly more declarative.

PiperOrigin-RevId: 281555100
2019-11-20 11:49:36 -08:00
Diego Caballero dd5a7cb488 Add getRemappedValue to ConversionPatternRewriter
This method is needed for N->1 conversion patterns to retrieve remapped
Values used in the original N operations.

Closes tensorflow/mlir#237

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/237 from dcaballe:dcaballe/getRemappedValue 1f64fadcf2b203f7b336ff0c5838b116ae3625db
PiperOrigin-RevId: 281321881
2019-11-19 11:09:39 -08:00
Jing Pu 563b5910a8 Also elide large array attribute in OpGraph Dump
PiperOrigin-RevId: 281114034
2019-11-18 11:27:43 -08:00
Andy Davis 68a8da4a93 Fix Affine Loop Fusion test case reported on github.
This CL utilizies the more robust fusion feasibility analysis being built out in LoopFusionUtils, which will eventually be used to replace the current affine loop fusion pass.

PiperOrigin-RevId: 281112340
2019-11-18 11:20:37 -08:00
Lei Zhang a0986bf43d NFC: Convert CmpIPredicate in StandardOps to use EnumAttr
This turns several hand-written functions to auto-generated ones.

PiperOrigin-RevId: 280684326
2019-11-15 10:17:31 -08:00
Nicolas Vasilache 0b271b7dfe Refactor the LowerVectorTransfers pass to use the RewritePattern infra - NFC
This is step 1/n in refactoring infrastructure along the Vector dialect to make it ready for retargetability and composable progressive lowering.

PiperOrigin-RevId: 280529784
2019-11-14 15:40:07 -08:00
Alex Zinenko 971b8dd4d8 Move Affine to Standard conversion to lib/Conversion
This is essentially a dialect conversion and conceptually belongs to
conversions.

PiperOrigin-RevId: 280460034
2019-11-14 10:35:21 -08:00
Nicolas Vasilache f2b6ae9991 Move VectorOps to Tablegen - (almost) NFC
This CL moves VectorOps to Tablegen and cleans up the implementation.

This is almost NFC but 2 changes occur:
  1. an interface change occurs in the padding value specification in vector_transfer_read:
     the value becomes non-optional. As a shortcut we currently use %f0 for all paddings.
     This should become an OpInterface for vectorization in the future.
  2. the return type of vector.type_cast is trivial and simplified to `memref<vector<...>>`

Relevant roundtrip and invalid tests that used to sit in core are moved to the vector dialect.

The op documentation is moved to the .td file.

PiperOrigin-RevId: 280430869
2019-11-14 08:15:23 -08:00
River Riddle d985c74883 NFC: Refactor block signature conversion to not erase the original arguments.
This refactors the implementation of block signature(type) conversion to not insert fake cast operations to perform the type conversion, but to instead create a new block containing the proper signature. This has the benefit of enabling the use of pre-computed analyses that rely on mapping values. It also leads to a much cleaner implementation overall. The major user facing change is that applySignatureConversion will now replace the entry block of the region, meaning that blocks generally shouldn't be cached over calls to applySignatureConversion.

PiperOrigin-RevId: 280226936
2019-11-13 10:27:53 -08:00
Jacques Pienaar bcfb3d4cd6 Explicitly initialize isRecursivelyLegal
This also previously triggered the warning:

warning: missing field 'isRecursivelyLegal' initializer [-Wmissing-field-initializers]
  legalOperations[op] = {action};
                               ^
PiperOrigin-RevId: 279399175
2019-11-08 15:06:34 -08:00
Sean Silva f6188b5b07 Replace some remnant uses of "inst" with "op".
PiperOrigin-RevId: 278961676
2019-11-06 16:09:23 -08:00
River Riddle 2366561a39 Add a PatternRewriter hook to merge blocks, and use it to support for folding branches.
A pattern rewriter hook, mergeBlock, is added that allows for merging the operations of one block into the end of another. This is used to support a canonicalization pattern for branch operations that folds the branch when the successor has a single predecessor(the branch block).

Example:
  ^bb0:
    %c0_i32 = constant 0 : i32
    br ^bb1(%c0_i32 : i32)
  ^bb1(%x : i32):
    return %x : i32

becomes:
  ^bb0:
    %c0_i32 = constant 0 : i32
    return %c0_i32 : i32
PiperOrigin-RevId: 278677825
2019-11-05 11:57:38 -08:00
Mahesh Ravishankar 9cbbd8f4df Support lowering of imperfectly nested loops into GPU dialect.
The current lowering of loops to GPU only supports lowering of loop
nests where the loops mapped to workgroups and workitems are perfectly
nested. Here a new lowering is added to handle lowering of imperfectly
nested loop body with the following properties
1) The loops partitioned to workgroups are perfectly nested.
2) The loop body of the inner most loop partitioned to workgroups can
contain one or more loop nests that are to be partitioned across
workitems. Each individual loops nests partitioned to workitems should
also be perfectly nested.
3) The number of workgroups and workitems are not deduced from the
loop bounds but are passed in by the caller of the lowering as values.
4) For statements within the perfectly nested loop nest partitioned
across workgroups that are not loops, it is valid to have all threads
execute that statement. This is NOT verified.

PiperOrigin-RevId: 277958868
2019-11-01 10:52:06 -07:00
Jing Pu 736ad2061c Dump op location in createPrintOpGraphPass for easier debugging.
PiperOrigin-RevId: 277546527
2019-10-30 11:22:22 -07:00
River Riddle a32f0dcb5d Add support to GreedyPatternRewriter for erasing unreachable blocks.
Rewrite patterns may make modifications to the CFG, including dropping edges between blocks. This change adds a simple unreachable block elimination run at the end of each iteration to ensure that the CFG remains valid.

PiperOrigin-RevId: 277545805
2019-10-30 11:19:24 -07:00
Diego Caballero c87c7f5732 Bugfix: Keep worklistMap in sync with worklist in GreedyPatternRewriter
When we removed a pattern, we removed it from worklist but not from
worklistMap. Then, when we tried to add a new pattern on the same Operation
again, the pattern wasn't added since it already existed in the
worklistMap (but not in the worklist).

Closes tensorflow/mlir#211

PiperOrigin-RevId: 277319669
2019-10-29 10:58:31 -07:00
River Riddle 2f4d0c085a Add support for marking an operation as recursively legal.
In some cases, it may be desirable to mark entire regions of operations as legal. This provides an additional granularity of context to the concept of "legal". The `ConversionTarget` supports marking operations, that were previously added as `Legal` or `Dynamic`, as `recursively` legal. Recursive legality means that if an operation instance is legal, either statically or dynamically, all of the operations nested within are also considered legal. An operation can be marked via `markOpRecursivelyLegal<>`:

```c++
ConversionTarget &target = ...;

/// The operation must first be marked as `Legal` or `Dynamic`.
target.addLegalOp<MyOp>(...);
target.addDynamicallyLegalOp<MySecondOp>(...);

/// Mark the operation as always recursively legal.
target.markOpRecursivelyLegal<MyOp>();
/// Mark optionally with a callback to allow selective marking.
target.markOpRecursivelyLegal<MyOp, MySecondOp>([](Operation *op) { ... });
/// Mark optionally with a callback to allow selective marking.
target.markOpRecursivelyLegal<MyOp>([](MyOp op) { ... });
```

PiperOrigin-RevId: 277086382
2019-10-28 10:04:34 -07:00
River Riddle 2b61b7979e Convert the Canonicalize and CSE passes to generic Operation Passes.
This allows for them to be used on other non-function, or even other function-like, operations. The algorithms are already generic, so this is simply changing the derived pass type. The majority of this change is just ensuring that the nesting of these passes remains the same, as the pass manager won't auto-nest them anymore.

PiperOrigin-RevId: 276573038
2019-10-24 15:01:09 -07:00
Alex Zinenko edffbbcdae Fix "set-but-unused" warning in DialectConversion
The variable in question is only used in an assertion,
leading to a warning in opt builds.

PiperOrigin-RevId: 276352259
2019-10-23 14:32:13 -07:00
Kazuaki Ishizaki 8bfedb3ca5 Fix minor spelling tweaks (NFC)
Closes tensorflow/mlir#177

PiperOrigin-RevId: 275692653
2019-10-20 00:11:34 -07:00
Nicolas Vasilache 9e7e297da3 Lower vector transfer ops to loop.for operations.
This allows mixing linalg operations with vector transfer operations (with additional modifications to affine ops) and is a step towards solving tensorflow/mlir#189.

PiperOrigin-RevId: 275543361
2019-10-18 14:10:10 -07:00
River Riddle 2acc220f17 NFC: Remove trivial builder get methods.
These don't add any value, and some are even more restrictive than the respective static 'get' method.

PiperOrigin-RevId: 275391240
2019-10-17 20:08:34 -07:00
Geoffrey Martin-Noble 6090643877 Introduce a wrapper around ConversionPattern that operates on the derived class
Analogous to OpRewritePattern, this makes writing conversion patterns more convenient.

PiperOrigin-RevId: 275349854
2019-10-17 15:30:38 -07:00
Nicolas Vasilache 10039d04e2 Rename LoopNestBuilder to AffineLoopNestBuilder - NFC
PiperOrigin-RevId: 275310747
2019-10-17 12:13:59 -07:00
Sana Damani 3940b90d84 Update Chapter 4 of the Toy tutorial
This Chapter now introduces and makes use of the Interface concept
in MLIR to demonstrate ShapeInference.
END_PUBLIC

Closes tensorflow/mlir#191

PiperOrigin-RevId: 275085151
2019-10-16 12:19:39 -07:00
Mahesh Ravishankar e7b49eef1d Allow for remapping argument to a Value in SignatureConversion.
The current SignatureConversion framework (part of DialectConversion)
allows remapping input arguments to a function from 1->0, 1->1 or
1->many arguments during conversion. Another case is where the
argument itself is dropped, but it's use are remapped to another
Value*.

An example of this is: The Vulkan/SPIR-V spec requires entry functions
to be of type void(void). The GPU -> SPIR-V conversion implemented
this without having the DialectConversion framework track the
remapping that lead to some undefined behavior. The changes here
addresses that.

PiperOrigin-RevId: 275059656
2019-10-16 10:21:03 -07:00
River Riddle dfe09cc621 Add support for PatternRewriter::eraseOp.
This hook is useful when an operation is known to be dead, and no replacement values make sense.

PiperOrigin-RevId: 275052756
2019-10-16 09:50:57 -07:00
Mehdi Amini f1f9e3b8d1 Fix CMake configuration after introduction of LICM and LoopLikeInterface
b843cc5d5a introduced a new op LICM transformation and a LoopLike interface,
but missed the CMake aspects of it. This should fix the build.

PiperOrigin-RevId: 275038533
2019-10-16 08:37:39 -07:00
Stephan Herhut b843cc5d5a Implement simple loop-invariant-code-motion based on dialect interfaces.
PiperOrigin-RevId: 275004258
2019-10-16 04:28:38 -07:00
River Riddle 96de7091bc Allowing replacing non-root operations in DialectConversion.
When dealing with regions, or other patterns that need to generate temporary operations, it is useful to be able to replace other operations than the root op being matched. Before this PR, these operations would still be considered for legalization meaning that the conversion would either fail, erroneously need to mark these ops as legal, or add unnecessary patterns.

PiperOrigin-RevId: 274598513
2019-10-14 10:01:59 -07:00
River Riddle 6b1cc3c6ea Add support for canonicalizing callable regions during inlining.
This will allow for inlining newly devirtualized calls, as well as give a more accurate cost model(when we have one). Currently canonicalization will only run for nodes that have no child edges, as the child nodes may be erased during canonicalization. We can support this in the future, but it requires more intricate deletion tracking.

PiperOrigin-RevId: 274011386
2019-10-10 17:06:33 -07:00
River Riddle 438dc176b1 Remove the need to convert operations in regions of operations that have been replaced.
When an operation with regions gets replaced, we currently require that all of the remaining nested operations are still converted even though they are going to be replaced when the rewrite is finished. This cl adds a tracking for a minimal set of operations that are known to be "dead". This allows for ignoring the legalization of operations that are won't survive after conversion.

PiperOrigin-RevId: 274009003
2019-10-10 17:06:25 -07:00
Christian Sigg 35bb732032 Guard rewriter insertion point during signature conversion.
Avoid unexpected side effect in rewriter insertion point.

PiperOrigin-RevId: 273785794
2019-10-09 11:33:28 -07:00
Diego Caballero 3451055614 Add support for some multi-store cases in affine fusion
This PR is a stepping stone towards supporting generic multi-store
source loop nests in affine loop fusion. It extends the algorithm to
support fusion of multi-store loop nests that:
 1. have only one store that writes to a function-local live out, and
 2. the remaining stores are involved in loop nest self dependences
    or no dependences within the function.

Closes tensorflow/mlir#162

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/162 from dcaballe:dcaballe/multi-output-fusion 7fb7dec6fe8b45f5ce176f018bfe37b256420c45
PiperOrigin-RevId: 273773907
2019-10-09 10:37:30 -07:00
River Riddle 49b29dd186 Add a PatternRewriter hook for cloning a region into another.
This is similar to the `inlineRegionBefore` hook, except the original blocks are unchanged. The region to be cloned *must* not have been modified during the conversion process at the point of cloning, i.e. it must belong an operation that has yet to be converted, or the operation that is currently being converted.

PiperOrigin-RevId: 273622533
2019-10-08 15:45:08 -07:00
Uday Bondhugula 6136f33d59 unroll and jam: fix order of jammed bodies
- bodies would earlier appear in the order (i, i+3, i+2, i+1) instead of
  (i, i+1, i+2, i+3) for example for factor 4.

- clean up hardcoded test cases

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#170

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/170 from bondhugula:ujam b66b405b2b1894a03b376952e32a9d0292042665
PiperOrigin-RevId: 273613131
2019-10-08 15:13:11 -07:00
Jing Pu 17606a108b Print result types when dumping graphviz.
PiperOrigin-RevId: 273406833
2019-10-07 16:45:53 -07:00
Uday Bondhugula 89e7a76a1c fix simplify-affine-structures bug
Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#157

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/157 from bondhugula:quickfix bd1fcd79825fc0bd5b4a3e688153fa0993ab703d
PiperOrigin-RevId: 273316498
2019-10-07 10:04:50 -07:00
Christian Sigg 85dcaf19c7 Fix typos, NFC.
PiperOrigin-RevId: 272851237
2019-10-04 04:37:53 -07:00
River Riddle 5830f71a45 Add support for inlining calls with different arg/result types from the callable.
Some dialects have implicit conversions inherent in their modeling, meaning that a call may have a different type that the type that the callable expects. To support this, a hook is added to the dialect interface that allows for materializing conversion operations during inlining when there is a mismatch. A hook is also added to the callable interface to allow for introspecting the expected result types.

PiperOrigin-RevId: 272814379
2019-10-03 23:10:51 -07:00
River Riddle a20d96e436 Update the Inliner pass to work on SCCs of the CallGraph.
This allows for the inliner to work on arbitrary call operations. The updated inliner will also work bottom-up through the callgraph enabling support for multiple levels of inlining.

PiperOrigin-RevId: 272813876
2019-10-03 23:05:21 -07:00
Jacques Pienaar 2b86e27dbd Show type even if elementsattr is elided in graph
The type is quite useful for debugging and shouldn't be too large.

PiperOrigin-RevId: 272390311
2019-10-02 01:46:12 -07:00
Jacques Pienaar c57f202c8c Switch explicit create methods to match generated build's order
The generated build methods have result type before the arguments (operands and attributes, which are also now adjacent in the explicit create method). This also results in changing the create method's ordering to match most build method's ordering.

PiperOrigin-RevId: 271755054
2019-09-28 09:35:58 -07:00
Uday Bondhugula 74eabdd14e NFC - clean up op accessor usage, std.load/store op verify, other stale info
- also remove stale terminology/references in docs

Signed-off-by: Uday Bondhugula <uday@polymagelabs.com>

Closes tensorflow/mlir#148

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/148 from bondhugula:cleanup e846b641a3c2936e874138aff480a23cdbf66591
PiperOrigin-RevId: 271618279
2019-09-27 11:58:24 -07:00
Nicolas Vasilache ddf737c5da Promote MemRefDescriptor to a pointer to struct when passing function boundaries in LLVMLowering.
The strided MemRef RFC discusses a normalized descriptor and interaction with library calls (https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/MaL8m2nXuio).
Lowering of nested LLVM structs as value types does not play nicely with externally compiled C/C++ functions due to ABI issues.
Solving the ABI problem generally is a very complex problem and most likely involves taking
a dependence on clang that we do not want atm.

A simple workaround is to pass pointers to memref descriptors at function boundaries, which this CL implement.

PiperOrigin-RevId: 271591708
2019-09-27 09:57:36 -07:00
Jing Pu 47a7021cc3 Change the return type of createPrintCFGGraphPass to match other passes.
PiperOrigin-RevId: 271252404
2019-09-25 18:33:47 -07:00
Mehdi Amini 5583252173 Add convenience methods to set an OpBuilder insertion point after an Operation (NFC)
PiperOrigin-RevId: 270727180
2019-09-23 11:54:55 -07:00
Christian Sigg c900d4994e Fix a number of Clang-Tidy warnings.
PiperOrigin-RevId: 270632324
2019-09-23 02:34:27 -07:00
Uday Bondhugula f559c38c28 Upgrade/fix/simplify store to load forwarding
- fix store to load forwarding for a certain set of cases (where
  forwarding shouldn't have happened); use AffineValueMap difference
  based MemRefAccess equality checking; utility logic is also greatly
  simplified

- add missing equality/inequality operators for AffineExpr ==/!= ints

- add == != operators on MemRefAccess

Closes tensorflow/mlir#136

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/136 from bondhugula:store-load-forwarding d79fd1add8bcfbd9fa71d841a6a9905340dcd792
PiperOrigin-RevId: 270457011
2019-09-21 10:08:56 -07:00