Commit Graph

1063 Commits

Author SHA1 Message Date
Matthias Springer c777e51468 [mlir][Analysis][NFC] FlatAffineConstraints: Use BoundType enum in functions
Differential Revision: https://reviews.llvm.org/D108185
2021-08-19 10:33:42 +09:00
Matthias Springer c19c51e357 [mlir][Analysis][NFC] Clean up FlatAffineValueConstraints
* Rename ids to values in FlatAffineValueConstraints.
* Overall cleanup of comments in FlatAffineConstraints and FlatAffineValueConstraints.

Differential Revision: https://reviews.llvm.org/D107947
2021-08-17 10:38:57 +09:00
Matthias Springer 4c4ab673f1 [mlir][Analysis][NFC] Split FlatAffineConstraints class
* Extract "value" functionality of `FlatAffineConstraints` into a new derived `FlatAffineValueConstraints` class. Current users of `FlatAffineConstraints` can use `FlatAffineValueConstraints` without additional code changes, thus NFC.
* `FlatAffineConstraints` no longer associates dimensions with SSA Values. All functionality that requires this, is moved to `FlatAffineValueConstraints`.
* `FlatAffineConstraints` no longer makes assumptions about where Values associated with dimensions are coming from.

Differential Revision: https://reviews.llvm.org/D107725
2021-08-17 10:09:17 +09:00
Tyler Augustine 3a2ff982d7 Support post-processing Ops in unrolled loop iterations
This can be useful when one needs to know which unrolled iteration an Op belongs to, for example, conveying noalias information among memory-affecting ops in parallel-access loops.

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D107789
2021-08-11 23:11:10 +00:00
Matthias Springer 66b1e629d8 [mlir] Cleanup: Fix warnings in MLIR
Tested with gcc-10. Other compilers may generate additional warnings. This does not fix all warnings. There are a few extra ones in LLVMCore and MLIR.

* `OpEmitter::getAttrNameIndex`: -Wunused-function (function is private and not used anywhere)
* `PrintOpPass` copy constructor: -Wextra ("Base class should be explicitly initialized in the copy constructor")
* `LegalizeForLLVMExport.cpp`: -Woverflow (overflow is expected, silence warning by making the cast explicit)

Differential Revision: https://reviews.llvm.org/D107525
2021-08-06 10:36:37 +09:00
Matthias Springer 12b34e056c [mlir] Clean up includes in Transforms/Passes.h
Differential Revision: https://reviews.llvm.org/D107520
2021-08-05 11:52:19 +09:00
Matthias Springer 438f700b4d [mlir] Fix gcc-5 build in ViewOpGraph.cpp
Differential Revision: https://reviews.llvm.org/D107458
2021-08-04 22:49:34 +09:00
Matthias Springer b6408fa169 [mlir] Include llvm/Support/Debug.h in Transforms/Passes.h
There are many downstream users of llvm::dbgs, which is defined in Debug.h. Before D106342, many users included that dependency transitively via the now deleted ViewRegionGraph.h. Adding it back to Transforms/Passes.h for convenience.

Differential Revision: https://reviews.llvm.org/D107451
2021-08-04 21:45:28 +09:00
Matthias Springer 9102a16bef [mlir] Support drawing control-flow graphs in ViewOpGraph.cpp
* Add new pass option `print-data-flow-edges`, default value `true`.
* Add new pass option `print-control-flow-edges`, default value `false`.
* Remove `PrintCFGPass`. Same functionality now provided by
  `PrintOpPass`.

Differential Revision: https://reviews.llvm.org/D106342
2021-08-04 20:45:15 +09:00
Matthias Springer 7f163931b9 [mlir] Fix CMake linker rules for ViewOpGraph.cpp
Differential Revision: https://reviews.llvm.org/D107439
2021-08-04 19:25:15 +09:00
Matthias Springer a87be1c1bd [mlir] Truncate/skip long strings in ViewOpGraph.cpp
* New pass option `max-label-len`: Truncate attributes/result types that have more #chars.
* New pass option `print-attrs`: Activate/deactivate rendering of attributes.
* New pass option `printResultTypes`: Activate/deactivate rendering of result types.

Differential Revision: https://reviews.llvm.org/D106337
2021-08-04 12:14:46 +09:00
Matthias Springer 8d15b7dcba [mlir] Improve Graphviz visualization in PrintOpPass
* Visualize blocks and regions as subgraphs.
* Generate DOT file directly instead of using `GraphTraits`. `GraphTraits` does not support subgraphs.

Differential Revision: https://reviews.llvm.org/D106253
2021-08-04 11:56:26 +09:00
Uday Bondhugula bf6c46d917 [MLIR] NFC Clean up doc comments on memref replacement utility
NFC. Clean up stale doc comments on memref replacement utility and some
variable renaming in it to avoid confusion.

Differential Revision: https://reviews.llvm.org/D107144
2021-07-31 15:14:52 +05:30
Tung D. Le a2186277be [mlir][affine-loop-fusion] Fix a bug that AffineIfOp prevents fusion of the other loops
The presence of AffineIfOp inside AffineFor prevents fusion of the other loops to happen. For example:

```
  affine.for %i0 = 0 to 10 {
    affine.store %cf7, %a[%i0] : memref<10xf32>
  }
  affine.for %i1 = 0 to 10 {
    %v0 = affine.load %a[%i1] : memref<10xf32>
    affine.store %v0, %b[%i1] : memref<10xf32>
  }
  affine.for %i2 = 0 to 10 {
    affine.if #set(%i2) {
      %v0 = affine.load %b[%i2] : memref<10xf32>
    }
  }
```

The first two loops were not be fused because of `affine.if` inside the last `affine.for`.

The issue seems to come from a conservative constraint that does not allow fusion if there are ops whose number of regions != 0 (affine.if is one of them).

This patch just removes such a constraint when`affine.if` is inside `affine.for`.  The existing `canFuseLoops` method is able to handle `affine.if` correctly.

Reviewed By: bondhugula, vinayaka-polymage

Differential Revision: https://reviews.llvm.org/D105963
2021-07-30 15:22:46 +05:30
Benjamin Kramer 1c9c2c91d4 [mlir] Remove the default isDynamicallyLegal hook
This is redundant with the callback variant and untested. Also remove
the callback-less methods for adding a dynamically legal op, as they
are no longer useful.

Differential Revision: https://reviews.llvm.org/D106786
2021-07-29 11:00:57 +02:00
Mehdi Amini 0be5d1a96c Implement recursive support into OperationEquivalence::isEquivalentTo()
This allows to use OperationEquivalence to track structural comparison for equality
between two operations.

Differential Revision: https://reviews.llvm.org/D106422
2021-07-29 05:06:37 +00:00
River Riddle f8479d9de5 [mlir] Set the namespace of the BuiltinDialect to 'builtin'
Historically the builtin dialect has had an empty namespace. This has unfortunately created a very awkward situation, where many utilities either have to special case the empty namespace, or just don't work at all right now. This revision adds a namespace to the builtin dialect, and starts to cleanup some of the utilities to no longer handle empty namespaces. For now, the assembly form of builtin operations does not require the `builtin.` prefix. (This should likely be re-evaluated though)

Differential Revision: https://reviews.llvm.org/D105149
2021-07-28 21:00:10 +00:00
Tres Popp 539437e288 [mlir] split type conversion to two lines for GCC's sake 2021-07-26 14:15:47 +02:00
Marcel Koester 0425332015 [mlir] Added new RegionBranchTerminatorOpInterface and adapted uses of hasTrait<ReturnLike>.
This CL adds a new RegionBranchTerminatorOpInterface to query information about operands that can be
passed to successor regions. Similar to the BranchOpInterface, it allows to freely define the
involved operands. However, in contrast to the BranchOpInterface, it expects an additional region
number to distinguish between various use cases which might require different operands passed to
different regions.

Moreover, we added new utility functions (namely getMutableRegionBranchSuccessorOperands and
getRegionBranchSuccessorOperands) to query (mutable) operand ranges for operations equiped with the
ReturnLike trait and/or implementing the newly added interface.  This simplifies reasoning about
terminators in the scope of the nested regions.

We also adjusted the SCF.ConditionOp to benefit from the newly added capabilities.

Differential Revision: https://reviews.llvm.org/D105018
2021-07-26 06:39:31 +02:00
Butygin b7a4649899 [mlir] ConversionTarget legality callbacks refactoring
* Get rid of Optional<std::function> as std::function already have a null state
* Add private setLegalityCallback function to set legality callback for unknown ops
* Get rid of unknownOpsDynamicallyLegal flag, use unknownLegalityFn state insted. This causes behavior change when user first calls markUnknownOpDynamicallyLegal with callback and then without but I am not sure is the original behavior was really a 'feature', or just oversignt in the original implementation.

Differential Revision: https://reviews.llvm.org/D105496
2021-07-24 14:59:36 +03:00
Rahul Joshi f8d3755f00 [MLIR][memref] Fix findDealloc() to handle > 1 dealloc for the given alloc.
- Change findDealloc() to return Optional<Operation *> and return None if > 1
  dealloc is associated with the given alloc.
- Add findDeallocs() to return all deallocs associated with the given alloc.
- Fix current uses of findDealloc() to bail out if > 1 dealloc is found.

Differential Revision: https://reviews.llvm.org/D106456
2021-07-22 09:34:19 -07:00
Uday Bondhugula 7932d21f5d [MLIR] Introduce a new rewrite driver to simplify supplied list of ops
Introduce a new rewrite driver (MultiOpPatternRewriteDriver) to rewrite
a supplied list of ops and other ops. Provide a knob to restrict
rewrites strictly to those ops or also to affected ops (but still not to
completely related ops).

This rewrite driver is commonly needed to run any simplification and
cleanup at the end of a transforms pass or transforms utility in a way
that only simplifies relevant IR. This makes it easy to write test cases
while not performing unrelated whole IR simplification that may
invalidate other state at the caller.

The introduced utility provides more freedom to developers of transforms
and transform utilities to perform focussed and local simplification. In
several cases, it provides greater efficiency as well as more
simplification when compared to repeatedly calling
`applyOpPatternsAndFold`; in other cases, it avoids the need to
undesirably call `applyPatternsAndFoldGreedily` to do unrelated
simplification in a FuncOp.

Update a few transformations that were earlier using
applyOpPatternsAndFold (SimplifyAffineStructures,
affineDataCopyGenerate, a linalg transform).

TODO:
- OpPatternRewriteDriver can be removed as it's a special case of
  MultiOpPatternRewriteDriver, i.e., both can be merged.

Differential Revision: https://reviews.llvm.org/D106232
2021-07-21 20:25:16 +05:30
Rahul Joshi 0cc2346cbf [MLIR][NFC] Minor cleanup for BufferDeallocation pass.
- Change walkReturnOperations() to be a non-template and look at block terminator
  for ReturnLike trait.
- Clarify description of validateSupportedControlFlow
- Eliminate unused argument in Backedges::recurse.
- Eliminate repeated calls to getFunction()
- Fix wording for non-SCF loop failure

Differential Revision: https://reviews.llvm.org/D106373
2021-07-20 09:43:22 -07:00
Sumesh Udayakumaran ada580863f [mlir] Enable cleanup of single iteration reduction loops being sibling-fused maximally
Changes include the following:
    1. Single iteration reduction loops being sibling fused at innermost insertion level
     are skipped from being considered as sequential loops.
    Otherwise, the slice bounds of these loops is reset.

    2. Promote loops that are skipped in previous step into outer loops.

    3. Two utility function - buildSliceTripCountMap, getSliceIterationCount - are moved from
mlir/lib/Transforms/Utils/LoopFusionUtils.cpp to mlir/lib/Analysis/Utils.cpp

Reviewed By: bondhugula, vinayaka-polymage

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

Depends On D105299

Reviewed By: mehdi_amini, bondhugula

Differential Revision: https://reviews.llvm.org/D105300
2021-07-10 16:40:00 +00:00
Uday Bondhugula 0c29f45ac9 [MLIR] Fix dialect conversion cancelRootUpdate
Fix dialect conversion ConversionPatternRewriter::cancelRootUpdate: the
erasure of operations here from the list of root update was off by one.
Should have been:
```
rootUpdates.erase(rootUpdates.begin() + (rootUpdates.rend() - it - 1));
```
instead of
```
rootUpdates.erase(rootUpdates.begin() + (rootUpdates.rend() - it));
```

or more directly:
```
rootUpdates.erase(it.base() - 1)
```

While on this, add an assertion to improve dev experience when a cancel is
called on an op on which a root update hasn't been started.

Differential Revision: https://reviews.llvm.org/D105397
2021-07-06 15:19:49 +05:30
Matthias Springer 2c115ecc41 [mlir][NFC] MemRef cleanup: Remove helper functions
Remove `getDynOperands` and `createOrFoldDimOp` from MemRef.h to decouple MemRef a bit from Tensor. These two functions are used in other dialects/transforms.

Differential Revision: https://reviews.llvm.org/D105260
2021-07-05 10:10:21 +09:00
Uday Bondhugula 071d26f808 [MLIR] Fix generateCopyForMemRefRegion
Fix generateCopyForMemRefRegion for a missing check: in some cases, when
the thing to generate copies for itself is empty, no fast buffer/copy
loops would have been allocated/generated. Add an extra assertion there
while at this.

Differential Revision: https://reviews.llvm.org/D105170
2021-06-30 10:24:10 +05:30
River Riddle 6569cf2a44 [mlir] Add a ThreadPool to MLIRContext and refactor MLIR threading usage
This revision refactors the usage of multithreaded utilities in MLIR to use a common
thread pool within the MLIR context, in addition to a new utility that makes writing
multi-threaded code in MLIR less error prone. Using a unified thread pool brings about
several advantages:

* Better thread usage and more control
We currently use the static llvm threading utilities, which do not allow multiple
levels of asynchronous scheduling (even if there are open threads). This is due to
how the current TaskGroup structure works, which only allows one truly multithreaded
instance at a time. By having our own ThreadPool we gain more control and flexibility
over our job/thread scheduling, and in a followup can enable threading more parts of
the compiler.

* The static nature of TaskGroup causes issues in certain configurations
Due to the static nature of TaskGroup, there have been quite a few problems related to
destruction that have caused several downstream projects to disable threading. See
D104207 for discussion on some related fallout. By having a ThreadPool scoped to
the context, we don't have to worry about destruction and can ensure that any
additional MLIR thread usage ends when the context is destroyed.

Differential Revision: https://reviews.llvm.org/D104516
2021-06-23 01:29:24 +00:00
Jacques Pienaar 0e760a0870 Add hook for dialect specializing processing blocks post inlining calls
This allows for dialects to do different post-processing depending on operations with the inliner (my use case requires different attribute propagation rules depending on call op). This hook runs before the regular processInlinedBlocks method.

Differential Revision: https://reviews.llvm.org/D104399
2021-06-16 12:53:21 -07:00
Uday Bondhugula 88e4aae57d [MLIR][NFC] Rename MemRefDataFlow -> AffineScalarReplacement
NFC. Rename MemRefDataFlow -> AffineScalarReplacement and move to
AffineTransforms library. Pass command line rename: -memref-dataflow-opt
-> affine-scalrep. Update outdated pass documentation.

Rationale:
https://llvm.discourse.group/t/move-and-rename-memref-dataflow-opt-lib-transforms-lib-affine-dialect-transforms/3640

Differential Revision: https://reviews.llvm.org/D104190
2021-06-14 17:52:53 +05:30
Amy Zhuang 986bef9782 [mlir] Remove redundant loads
Reviewed By: vinayaka-polymage, bondhugula

Differential Revision: https://reviews.llvm.org/D103294
2021-06-03 15:51:46 -07:00
River Riddle 0289a2692e [mlir] Add support for filtering patterns based on debug names and labels
This revision allows for attaching "debug labels" to patterns, and provides to FrozenRewritePatternSet for  filtering patterns based on these labels (in addition to the debug name of the pattern). This will greatly simplify the ability to write tests targeted towards specific patterns (in cases where many patterns may interact),  will also simplify debugging pattern application by observing how application changes when enabling/disabling specific patterns.

To enable better reuse of pattern rewrite options between passes, this revision also adds a new PassUtil.td file to the Rewrite/ library that will allow for passes to easily hook into a common interface for pattern debugging. Two options are used to seed this utility, `disable-patterns` and `enable-patterns`, which are used to enable the filtering behavior indicated above.

Differential Revision: https://reviews.llvm.org/D102441
2021-06-02 12:05:25 -07:00
Chris Lattner 6134231a78 [CSE] Ask DominanceInfo about "hasSSADominance" instead of reconstructing it.
I backed this off to make the previous patch easier to wrangle, but now
this is an efficient query and it is better to not replace it in CSE.

Differential Revision: https://reviews.llvm.org/D103494
2021-06-01 15:16:23 -07:00
Chris Lattner 412ae15de4 [Dominators] Rewrite the dominator implementation for efficiency. NFC.
The previous impl densely scanned the entire region starting with an op
when dominators were created, creating a DominatorTree for every region.

This is extremely expensive up front -- particularly for clients like
Linalg/Transforms/Fusion.cpp that construct DominanceInfo for a single
query.  It is also extremely memory wasteful for IRs that use single
block regions commonly (e.g. affine.for) because it's making a
dominator tree for a region that has trivial dominance.  The
implementation also had numerous unnecessary minor efficiencies, e.g.
doing multiple walks of the region tree or tryGetBlocksInSameRegion
building a DenseMap that it didn't need.

This patch switches to an approach where [Post]DominanceInfo is free
to construct, and which lazily constructs DominatorTree's for any
multiblock regions that it needs.  This avoids the up-front cost
entirely, making its runtime proportional to the complexity of the
region tree instead of # ops in a region.  This also avoids the memory
and time cost of creating DominatorTree's for single block regions.

Finally this rewrites the implementation for simplicity and to avoids
the constant factor problems the old implementation had.

Differential Revision: https://reviews.llvm.org/D103384
2021-06-01 14:46:37 -07:00
Chris Lattner 1e344ce4f3 [CSE] Make domInfo a stored property, cut use of DominanceInfo::hasDominanceInfo. NFC.
CSE is the only client of this API, refactor it a bit to pull the query
internally to make changes to DominanceInfo a bit easier.  This commit
also improves comments a bit.
2021-05-30 12:23:39 -07:00
Jacques Pienaar 82f7b5e1b9 [mlir] Add missing namespace to createCanonicalizerPass. 2021-05-28 09:12:55 -07:00
Matthias Springer 108ca7a7e7 [mlir] Support dialect-wide canonicalization pattern registration
* Add `hasCanonicalizer` option to Dialect.
* Initialize canonicalizer with dialect-wide canonicalization patterns.
* Add test case to TestDialect.

Dialect-wide canonicalization patterns are useful if a canonicalization pattern does not conceptually associate with any single operation, i.e., it should not be registered as part of an operation's `getCanonicalizationPatterns` function. E.g., this is the case for canonicalization patterns that match an op interface.

Differential Revision: https://reviews.llvm.org/D103226
2021-05-27 17:35:21 +09:00
thomasraoux e5eff533f7 [mlir] Make StripDebugInfo strip out block arguments locs
Differential Revision: https://reviews.llvm.org/D103187
2021-05-26 11:05:38 -07:00
Chris Lattner 2f23f9e641 [Canonicalize] Fully parameterize the pass based on config options. NFC.
This allows C++ clients of the Canonicalize pass to specify their own
Config option struct to control how Canonicalize works, increasing reusability.

This also allows controlling these settings for the default Canonicalize pass
using command line options.  This is useful for testing and for playing with
things on the command line.

Differential Revision: https://reviews.llvm.org/D103069
2021-05-25 13:09:51 -07:00
Tres Popp 6054bfa813 [mlir] Support buffer hoisting on allocas
This adds support for hoisting allocas in both BufferHoisting and
BufferLoopHoisting.

Differential Revision: https://reviews.llvm.org/D102681
2021-05-25 14:50:01 +02:00
Chris Lattner 64716b2c39 [GreedyPatternRewriter] Introduce a config object that allows controlling internal parameters. NFC.
This exposes the iterations and top-down processing as flags, and also
allows controlling whether region simplification is desirable for a client.
This allows deleting some duplicated entrypoints to
applyPatternsAndFoldGreedily.

This also deletes the Constant Preprocessing pass, which isn't worth it
on balance.

All defaults are all kept the same, so no one should see a behavior change.

Differential Revision: https://reviews.llvm.org/D102988
2021-05-24 12:40:40 -07:00
Haruki Imai 000a05fd1a [mlir] Normalize dynamic memrefs with a map of tiled-layout.
Steps for normalizing dynamic memrefs for tiled layout map
1. Check if original map is tiled layout. Only tiled layout is supported.
2. Create normalized memrefType. Dimensions that include dynamic dimensions
   in the map output will be dynamic dimensions.
3. Create new maps to calculate each dimension size of new memref.
   In tiled layout, the dimension size can be calculated by replacing
    "floordiv <tile size>" with "ceildiv <tile size>" and
    "mod <tile size>" with "<tile size>".
4. Create AffineApplyOp to apply the new maps. The output of AffineApplyOp is
   dynamicSizes for new AllocOp.
5. Add the new dynamic sizes in new AllocOp.

This patch also set MemRefsNormalizable trant in CastOp and DimOp since
they used with dynamic memrefs.

Reviewed By: bondhugula

Differential Revision: https://reviews.llvm.org/D97655
2021-05-24 08:39:36 +05:30
Stephan Herhut 90e55dfcf4 [mlir][memref] Improve canonicalization of memref.clone
The previous implementation did not handle casting behavior properly and
did not consider aliases.

Differential Revision: https://reviews.llvm.org/D102785
2021-05-21 16:34:50 +02:00
Vinayaka Bandishti a3917d3670 [MLIR][Affine] Privatize certain escaping memrefs
During affine loop fusion, create private memrefs for escaping memrefs
too under the conditions that:
-- the source is not removed after fusion, and
-- the destination does not write to the memref.

This creates more fusion opportunities as illustrated in the test case.

Reviewed By: bondhugula, ayzhuang

Differential Revision: https://reviews.llvm.org/D102604
2021-05-18 22:23:02 +05:30
Chris Lattner 648f34a284 Merge with mainline.
Differential Revision: https://reviews.llvm.org/D102636
2021-05-17 11:15:10 -07:00
Julian Gross 1fbb484ea4 [WIP][mlir] Resolve memref dependency in canonicalize pass.
Splitting the memref dialect lead to an introduction of several dependencies
to avoid compilation issues. The canonicalize pass also depends on the
memref dialect, but it shouldn't. This patch resolves the dependencies
and the unintuitive includes are removed. However, the dependency moves
to the constructor of the std dialect.

Differential Revision: https://reviews.llvm.org/D102060
2021-05-17 11:33:38 +02:00
River Riddle 53b946aa63 [mlir] Refactor the representation of function-like argument/result attributes.
The current design uses a unique entry for each argument/result attribute, with the name of the entry being something like "arg0". This provides for a somewhat sparse design, but ends up being much more expensive (from a runtime perspective) in-practice. The design requires building a string every time we lookup the dictionary for a specific arg/result, and also requires N attribute lookups when collecting all of the arg/result attribute dictionaries.

This revision restructures the design to instead have an ArrayAttr that contains all of the attribute dictionaries for arguments and another for results. This design reduces the number of attribute name lookups to 1, and allows for O(1) lookup for individual element dictionaries. The major downside is that we can end up with larger memory usage, as the ArrayAttr contains an entry for each element even if that element has no attributes. If the memory usage becomes too problematic, we can experiment with a more sparse structure that still provides a lot of the wins in this revision.

This dropped the compilation time of a somewhat large TensorFlow model from ~650 seconds to ~400 seconds.

Differential Revision: https://reviews.llvm.org/D102035
2021-05-07 19:32:31 -07:00
Tres Popp faab8c140a [mlir] Rename BufferAliasAnalysis to BufferViewFlowAnalysis
This it to make more clear the difference between this and
an AliasAnalysis.

For example, given a sequence of subviews that create values
A -> B -> C -> d:
BufferViewFlowAnalysis::resolve(B) => {B, C, D}
AliasAnalysis::resolve(B) => {A, B, C, D}

Differential Revision: https://reviews.llvm.org/D100838
2021-05-07 16:12:54 +02:00
Amy Zhuang 5dc1ed3f62 [mlir] Update dstNode after DenseMap insertion in loop fusion pass.
Reviewed By: vinayaka-polymage

Differential Revision: https://reviews.llvm.org/D101794
2021-05-06 15:23:59 -07:00