892 Commits

Author SHA1 Message Date
River Riddle
fd2d7c857b Rename the 'if' operation in the AffineOps dialect to 'affine.if' and namespace
the AffineOps dialect with 'affine'.

PiperOrigin-RevId: 232728977
2019-03-29 16:18:59 -07:00
Lei Zhang
888b9fa8a6 Add constant build() method not requiring result type
Instead, we deduce the result type from the given attribute.

This is in preparation for generating constant ops with TableGen.

PiperOrigin-RevId: 232723467
2019-03-29 16:18:44 -07:00
Stella Laurenzo
c78d708487 Implement Quantization dialect and minimal UniformQuantizedType.
PiperOrigin-RevId: 232723240
2019-03-29 16:18:29 -07:00
Alex Zinenko
e9493cf14d Port alloc/dealloc LLVM IR conversion into the LLVM IR dialect lowering
Implement the lowering of memref allocation and deallocation standard
operations into the LLVM IR dialect.  This largely follows the existing
mechanism in MLIR-to-LLVM-IR translation for the sake of compatibility.
A memref value is transformed into a memref descriptor value which holds the
pointer to the underlying data buffer and the dynamic memref sizes.  The buffer
is allocated using `malloc` and freed using `free`.  The lowering inserts
declarations of these functions if necessary.  Memref descriptors are values of
the LLVM IR structure type wrapped into an MLIR LLVM dialect type.  The pointer
to the buffer and the individual sizes are accessed using `extractvalue` and
`insertvalue` LLVM IR instructions.

PiperOrigin-RevId: 232719419
2019-03-29 16:18:14 -07:00
River Riddle
90d10b4e00 NFC: Rename the 'for' operation in the AffineOps dialect to 'affine.for'. The is the second step to adding a namespace to the AffineOps dialect.
PiperOrigin-RevId: 232717775
2019-03-29 16:17:59 -07:00
River Riddle
905d84851d Address post submit review comments for removing Block::findInstPositionInBlock.
PiperOrigin-RevId: 232713514
2019-03-29 16:17:44 -07:00
River Riddle
3227dee15d NFC: Rename affine_apply to affine.apply. This is the first step to adding a namespace to the affine dialect.
PiperOrigin-RevId: 232707862
2019-03-29 16:17:29 -07:00
MLIR Team
b9dde91ea6 Adds the ability to compute the MemRefRegion of a sliced loop nest. Utilizes this feature during loop fusion cost computation, to compute what the write region of a fusion candidate loop nest slice would be (without having to materialize the slice or change the IR).
*) Adds parameter to public API of MemRefRegion::compute for passing in the slice loop bounds to compute the memref region of the loop nest slice.
*) Exposes public method MemRefRegion::getRegionSize for computing the size of the memref region in bytes.

PiperOrigin-RevId: 232706165
2019-03-29 16:17:15 -07:00
Jacques Pienaar
31f2b3ffa1 Address follow on comments for quickstart doc.
PiperOrigin-RevId: 232705423
2019-03-29 16:16:58 -07:00
River Riddle
42a2d7d6e1 Remove findInstPositionInBlock from the Block api.
PiperOrigin-RevId: 232704766
2019-03-29 16:16:43 -07:00
Lei Zhang
1df6ca5053 [TableGen] Model variadic operands using Variadic<Type>
Previously, we were using the trait mechanism to specify that an op has variadic operands.
That led a discrepancy between how we handle ops with deterministic number of operands.
Besides, we have no way to specify the constraints and match against the variadic operands.

This CL introduced Variadic<Type> as a way to solve the above issues.

PiperOrigin-RevId: 232656104
2019-03-29 16:16:28 -07:00
River Riddle
0c65cf283c Move the AffineFor loop bound folding to a canonicalization pattern on the AffineForOp.
PiperOrigin-RevId: 232610715
2019-03-29 16:16:11 -07:00
River Riddle
423715056d Emit a parser error when the min/max prefix is missing from a multi value AffineFor loop bound AffineMap.
PiperOrigin-RevId: 232609693
2019-03-29 16:15:56 -07:00
River Riddle
10237de8eb Refactor the affine analysis by moving some functionality to IR and some to AffineOps. This is important for allowing the affine dialect to define canonicalizations directly on the operations instead of relying on transformation passes, e.g. ComposeAffineMaps. A summary of the refactoring:
* AffineStructures has moved to IR.

* simplifyAffineExpr/simplifyAffineMap/getFlattenedAffineExpr have moved to IR.

* makeComposedAffineApply/fullyComposeAffineMapAndOperands have moved to AffineOps.

* ComposeAffineMaps is replaced by AffineApplyOp::canonicalize and deleted.

PiperOrigin-RevId: 232586468
2019-03-29 16:15:41 -07:00
River Riddle
6f7470a56a Define the initial g3doc for the Affine dialect.
PiperOrigin-RevId: 232581506
2019-03-29 16:15:26 -07:00
Smit Hinsu
2927297a1c Add derived type attributes for TensorFlow ops generated by TableGen
Motivation for this change is to remove redundant TF type attributes for
TensorFlow ops. For example, tf$T: "tfdtype$DT_FLOAT". Type attributes can be derived using the MLIR operand or result MLIR types, attribute names and their mapping. This will also allow constant folding of instructions generated within MLIR (and not imported from TensorFlow) without adding type attributes for the instruction.

Derived attributes are populated while exporting MLIR to TF GraphDef using
auto-generated populators. Populators are only available for the ops that are generated by the TableGen.

Also, fixed Operator::getNumArgs method to exclude derived attributes as they are not
part of the arguments.

TESTED with unit test

PiperOrigin-RevId: 232531561
2019-03-29 16:15:08 -07:00
Alex Zinenko
40d5d09f9d Print parens around the return type of a function if it is also a function type
Existing type syntax contains the following productions:

    function-type ::= type-list-parens `->` type-list
    type-list ::= type | type-list-parens
    type ::= <..> | function-type

Due to these rules, when the parser sees `->` followed by `(`, it cannot
disambiguate if `(` starts a parenthesized list of function result types, or a
parenthesized list of operands of another function type, returned from the
current function.  We would need an unknown amount of lookahead to try to find
the `->` at the right level of function nesting to differentiate between type
lists and singular function types.

Instead, require the result type of the function that is a function type itself
to be always parenthesized, at the syntax level.  Update the spec and the
parser to correspond to the production rule names used in the spec (although it
would have worked without modifications).  Fix the function type parsing bug in
the process, as it used to accept the non-parenthesized list of types for
arguments, disallowed by the spec.

PiperOrigin-RevId: 232528361
2019-03-29 16:14:50 -07:00
Jacques Pienaar
1b1f293a5d MLIR graph rewrite using pattern quickstart doc.
Start quickstart guide of how to define ops + specify patterns for rewrite.

PiperOrigin-RevId: 232490287
2019-03-29 16:14:35 -07:00
Sergei Lebedev
d8e5ce0107 Implemented __invert__, __and__ and __or__ in the EDSC Python bindings
This allows to use bitwise operators as logical (accounting for differences
in precedence).

PiperOrigin-RevId: 232489024
2019-03-29 16:14:20 -07:00
Alex Zinenko
3fa22b88de Print non-default attribute types in optional attr dictionary
In optional attribute dictionary used, among others, in the generic form of the
ops, attribute types for integers and floats are omitted.  This could lead to
inconsistencies when round-tripping the IR, in particular the attributes are
created with incorrect types after parsing (integers default to i64, floats
default to f64).  Provide API to emit a trailing type after the attribute for
integers and floats.  Use it while printing the optional attribute dictionary.

Omitting types for i64 and f64 is a pragmatic decision that minimizes changes
in tests.  We may want to reconsider in the future and always print types of
attributes in the generic form.

PiperOrigin-RevId: 232480116
2019-03-29 16:14:05 -07:00
MLIR Team
a78edcda5b Loop fusion improvements:
*) After a private memref buffer is created for a fused loop nest, dependences on the old memref are reduced, which can open up fusion opportunities. In these cases, users of the old memref are added back to the worklist to be reconsidered for fusion.
*) Fixed a bug in fusion insertion point dependence check where the memref being privatized was being skipped from the check.

PiperOrigin-RevId: 232477853
2019-03-29 16:13:50 -07:00
Sergei Lebedev
52ec65c85e Implemented __eq__ and __ne__ in EDSC Python bindings
PiperOrigin-RevId: 232473201
2019-03-29 16:13:34 -07:00
Uday Bondhugula
ed27b40085 Remove stray debug output - NFC
PiperOrigin-RevId: 232390076
2019-03-29 16:13:17 -07:00
River Riddle
bf9c381d1d Remove InstWalker and move all instruction walking to the api facilities on Function/Block/Instruction.
PiperOrigin-RevId: 232388113
2019-03-29 16:12:59 -07:00
River Riddle
c9ad4621ce NFC: Move AffineApplyOp to the AffineOps dialect. This also moves the isValidDim/isValidSymbol methods from Value to the AffineOps dialect.
PiperOrigin-RevId: 232386632
2019-03-29 16:12:40 -07:00
Uday Bondhugula
0f50414fa4 Refactor common code getting memref access in getMemRefRegion - NFC
- use getAccessMap() instead of repeating it
- fold getMemRefRegion into MemRefRegion ctor (more natural, avoid heap
  allocation and unique_ptr where possible)

- change extractForInductionVars - MutableArrayRef -> ArrayRef for the
  arguments. Since the method is just returning copies of 'Value *', the client
  can't mutate the pointers themselves; it's fine to mutate the 'Value''s
  themselves, but that doesn't mutate the pointers to those.

- change the way extractForInductionVars returns (see b/123437690)

PiperOrigin-RevId: 232359277
2019-03-29 16:12:25 -07:00
Uday Bondhugula
99d6ee02b9 Update MemRefAccess::getAccessMap to always canonicalize map + operands
- with this we won't see duplicate / unused operands when getting access maps,
  or when constructing FlatAffineConstraints based on such maps

- we can probably change fullyComposeAffineMapAndOperands to ensure this
  TODO(b/123879896).

PiperOrigin-RevId: 232356600
2019-03-29 16:12:08 -07:00
River Riddle
74adaa5b31 Remove the OwnerTy template parameter of IROperandImpl and ValueUseIterator as it is no longer necessary now that all instructions are operations.
PiperOrigin-RevId: 232356323
2019-03-29 16:11:53 -07:00
Jacques Pienaar
2afd655622 Add option print functions with the generic form.
The generic form may be more desirable even when there is a custom form
specified so add option to enable emitting it. This also exposes a current bug
when round tripping constant with function attribute.

PiperOrigin-RevId: 232350712
2019-03-29 16:11:38 -07:00
Jacques Pienaar
5e88422f1d No need to specify default behavior. NFC.
This avoids overriding the class members + setting the printer/parser hooks only to fall back to generic.

PiperOrigin-RevId: 232348307
2019-03-29 16:11:23 -07:00
River Riddle
2d75501691 Remove the forward definition of OperationInst now that no references remain.
PiperOrigin-RevId: 232325321
2019-03-29 16:11:08 -07:00
River Riddle
b499277fb6 Remove remaining usages of OperationInst in lib/Transforms.
PiperOrigin-RevId: 232323671
2019-03-29 16:10:53 -07:00
River Riddle
44e040dd63 Remove remaining references to OperationInst in all directories except for lib/Transforms.
PiperOrigin-RevId: 232322771
2019-03-29 16:10:38 -07:00
River Riddle
a3d9ccaecb Replace the walkOps/visitOperationInst variants from the InstWalkers with the Instruction variants.
PiperOrigin-RevId: 232322030
2019-03-29 16:10:24 -07:00
Dimitrios Vytiniotis
9ca0691b06 Exposing logical operators in EDSC all the way up to Python.
PiperOrigin-RevId: 232299839
2019-03-29 16:10:08 -07:00
Uday Bondhugula
b26900dce5 Update dma-generate pass to (1) work on blocks of instructions (instead of just
loops), (2) take into account fast memory space capacity and lower 'dmaDepth'
to fit, (3) add location information for debug info / errors

- change dma-generate pass to work on blocks of instructions (start/end
  iterators) instead of 'for' loops; complete TODOs - allows DMA generation for
  straightline blocks of operation instructions interspersed b/w loops
- take into account fast memory capacity: check whether memory footprint fits
  in fastMemoryCapacity parameter, and recurse/lower the depth at which DMA
  generation is performed until it does fit in the provided memory
- add location information to MemRefRegion; any insufficient fast memory
  capacity errors or debug info w.r.t dma generation shows location information
- allow DMA generation pass to be instantiated with a fast memory capacity
  option (besides command line flag)

- change getMemRefRegion to return unique_ptr's
- change getMemRefFootprintBytes to work on a 'Block' instead of 'ForInst'
- other helper methods; add postDomInstFilter option for
  replaceAllMemRefUsesWith; drop forInst->walkOps, add Block::walkOps methods

Eg. output

$ mlir-opt  -dma-generate -dma-fast-mem-capacity=1 /tmp/single.mlir
/tmp/single.mlir:9:13: error: Total size of all DMA buffers' for this block exceeds fast memory capacity

        for %i3 = (d0) -> (d0)(%i1) to (d0) -> (d0 + 32)(%i1) {
            ^

$ mlir-opt -debug-only=dma-generate  -dma-generate -dma-fast-mem-capacity=400 /tmp/single.mlir
/tmp/single.mlir:9:13: note: 8 KiB of DMA buffers in fast memory space for this block

        for %i3 = (d0) -> (d0)(%i1) to (d0) -> (d0 + 32)(%i1) {

PiperOrigin-RevId: 232297044
2019-03-29 16:09:52 -07:00
River Riddle
870d778350 Begin the process of fully removing OperationInst. This patch cleans up references to OperationInst in the /include, /AffineOps, and lib/Analysis.
PiperOrigin-RevId: 232199262
2019-03-29 16:09:36 -07:00
River Riddle
de2d0dfbca Fold the functionality of OperationInst into Instruction. OperationInst still exists as a forward declaration and will be removed incrementally in a set of followup cleanup patches.
PiperOrigin-RevId: 232198540
2019-03-29 16:09:19 -07:00
Lei Zhang
b2dbbdb704 Merge OpProperty and Traits into OpTrait
They are essentially both modelling MLIR OpTrait; the former achieves the
purpose via introducing corresponding symbols in TableGen, while the latter
just uses plain strings.

Unify them to provide a single mechanism to avoid confusion and to better
reflect the definitions on MLIR C++ side.

Ideally we should be able to deduce lots of these traits automatically via
other bits of op definitions instead of manually specifying them; but not
for now though.

PiperOrigin-RevId: 232191401
2019-03-29 16:09:03 -07:00
Lei Zhang
8b75cc5741 Define NumericAttr as the base class for BoolAttr, IntegerAttr, FloatAttr, and ElementsAttr
These attribute kinds are different from the rest in the sense that their types are defined
in MLIR's type hierarchy and we can build constant op out of them.

By defining this middle-level base class, we have a unified way to test and query the type
of these attributes, which will be useful when constructing constant ops of various dialects.

This CL also added asserts to reject non-NumericAttr in constant op's build() method.

PiperOrigin-RevId: 232188178
2019-03-29 16:08:43 -07:00
River Riddle
126ec14e2d Fix the handling of the resizable operands bit of OperationState in a few places.
PiperOrigin-RevId: 232163738
2019-03-29 16:08:28 -07:00
River Riddle
dae0263e0b Fold IROperandOwner into Instruction.
PiperOrigin-RevId: 232159334
2019-03-29 16:08:11 -07:00
River Riddle
38f8dc67be When parsing, treat an IntegerSet with no constraints as a degenerate true case. Also update the spec to note that affine constraints are optional.
PiperOrigin-RevId: 232158673
2019-03-29 16:07:56 -07:00
River Riddle
d54e3dd358 Emit an error when parsing an affine structure if '->' or ':' is not found
after the dim/symbol id list.

PiperOrigin-RevId: 232094789
2019-03-29 16:07:40 -07:00
Uday Bondhugula
8be2627436 Promote local buffers created post fusion to higher memory space
- fusion already includes the necessary analysis to create small/local buffers
  post fusion; allocate these buffers in a higher memory space if the necessary
  pass parameters are provided (threshold size, memory space id)

- although there will be a separate utility at some point to directly detect
  and promote small local buffers to higher memory spaces, doing it while fusion
  when possible is much less expensive, comes free with fusion analysis, and covers
  a key common case.

PiperOrigin-RevId: 232063894
2019-03-29 16:07:23 -07:00
Stella Laurenzo
db04019f3a Minor fix to the lexer whitespace loop.
Nothing in the loop can (legally) cause curPtr -> nullptr. And if it did, we
    would null dereference right below anyway.

    This loop still reads funny to me but doesn't make me stare at it and wonder
    what I am missing anymore.

--

PiperOrigin-RevId: 232062076
2019-03-29 16:07:07 -07:00
River Riddle
5052bd8582 Define the AffineForOp and replace ForInst with it. This patch is largely mechanical, i.e. changing usages of ForInst to OpPointer<AffineForOp>. An important difference is that upon construction an AffineForOp no longer automatically creates the body and induction variable. To generate the body/iv, 'createBody' can be called on an AffineForOp with no body.
PiperOrigin-RevId: 232060516
2019-03-29 16:06:49 -07:00
Lei Zhang
e0774c008f [TableGen] Use tblgen::DagLeaf to model DAG arguments
This CL added a tblgen::DagLeaf wrapper class with several helper methods for handling
DAG arguments. It helps to refactor the rewriter generation logic to be more higher
level.

This CL also added a tblgen::ConstantAttr wrapper class for constant attributes.

PiperOrigin-RevId: 232050683
2019-03-29 16:06:31 -07:00
Jacques Pienaar
70e3873e86 Update link
PiperOrigin-RevId: 232049075
2019-03-29 16:06:14 -07:00
Uday Bondhugula
f0d4e70f26 Fix Block::getNumSuccessors()
- getTerminator() on a block can return nullptr; moreover, blocks that are improperly
  constructed/transformed by utilities/passes may not have terminators even for the
  top-level blocks

PiperOrigin-RevId: 232025963
2019-03-29 16:05:55 -07:00