Jacques Pienaar [Tue, 15 Jan 2019 13:14:18 +0000 (05:14 -0800)]
Move tests and add missing BUILD file.
Updated the extracted base classes here. The test wasn't updated post the move.
PiperOrigin-RevId:
229353434
Uday Bondhugula [Tue, 15 Jan 2019 04:50:47 +0000 (20:50 -0800)]
Update LangRef - integer sets should have at least one constraint
- this change is already consistent with the current code
- having no constraints made the integer set spec look odd - as nothing appears
between ':' and the closing parenthesis
- there is no loss in representational power - an unconstrained set can always
be represented by a trivially true constraint
PiperOrigin-RevId:
229307353
Uday Bondhugula [Tue, 15 Jan 2019 03:28:04 +0000 (19:28 -0800)]
Fix outdated comments
PiperOrigin-RevId:
229300301
River Riddle [Tue, 15 Jan 2019 01:51:47 +0000 (17:51 -0800)]
Don't allocate a buffer for an empty ArrayRef in TypeStorageAllocator.
PiperOrigin-RevId:
229290802
River Riddle [Tue, 15 Jan 2019 00:29:30 +0000 (16:29 -0800)]
Change derived type storage objects to be constructed with an instance of the
KeyTy. This will simplify the cases where a type can be constructed, and need to be verified, in multiple ways.
PiperOrigin-RevId:
229279000
River Riddle [Tue, 15 Jan 2019 00:27:32 +0000 (16:27 -0800)]
If an instruction contains blocks, IfInst/ForInst, make sure to drop references held by those blocks when dropping references for the instruction.
PiperOrigin-RevId:
229278667
River Riddle [Mon, 14 Jan 2019 21:56:59 +0000 (13:56 -0800)]
Check that at least one constraint is parsed when parsing an IntegerSet.
PiperOrigin-RevId:
229248638
Lei Zhang [Mon, 14 Jan 2019 21:36:02 +0000 (13:36 -0800)]
Swap the type and attribute parameter in ConstantOp::build()
This is to keep consistent with other TableGen generated builders
so that we can also use this builder in TableGen rules.
PiperOrigin-RevId:
229244630
River Riddle [Mon, 14 Jan 2019 21:23:18 +0000 (13:23 -0800)]
Add a canonicalization pattern for conditional branch to fold constant branch conditions.
PiperOrigin-RevId:
229242007
River Riddle [Mon, 14 Jan 2019 21:18:34 +0000 (13:18 -0800)]
Emit unsupported error when parsing a DenseElementAttr with an integer type of greater than 64 bits.
DenseElementAttr currently does not support value bitwidths of > 64. This can result in asan failures and crashes when trying to invoke DenseElementsAttr::writeBits/DenseElementsAttr::readBits.
PiperOrigin-RevId:
229241125
River Riddle [Mon, 14 Jan 2019 20:23:38 +0000 (12:23 -0800)]
Add missing return post parse failure for the indices of a sparse attribute.
PiperOrigin-RevId:
229231462
MLIR Team [Mon, 14 Jan 2019 19:26:25 +0000 (11:26 -0800)]
LoopFusion: automate selection of source loop nest slice depth and destination loop nest insertion depth based on a simple cost model (cost model can be extended/replaced at a later time).
*) LoopFusion: Adds fusion cost function which compares the cost of the fused loop nest, with the cost of the two unfused loop nests to determine if it is profitable to fuse the candidate loop nests. The fusion cost function is run for various combinations for src/dst loop depths attempting find the minimum cost setting for src/dst loop depths which does not increase the computational cost when the loop nests are fused. Combinations of src/dst loop depth are evaluated attempting to maximize loop depth (i.e. take a bigger computation slice from the source loop nest, and insert it deeper in the destination loop nest for better locality).
*) LoopFusion: Adds utility to compute op instance count for loop nests, sliced loop nests, and to compute the cost of a loop nest fused with another sliced loop nest.
*) LoopFusion: canonicalizes slice bound AffineMaps (and updates related tests).
*) Analysis::Utils: Splits getBackwardComputationSlice into two functions: one which calculates and returns the slice loop bounds for analysis by LoopFusion, and the other for insertion of the computation slice (ones fusion has calculated the min-cost src/dst loop depths).
*) Test: Adds multiple unit tests to test the new functionality.
PiperOrigin-RevId:
229219757
River Riddle [Mon, 14 Jan 2019 18:30:20 +0000 (10:30 -0800)]
Add a Block::dropAllReferences to drop all references from held instructions and call it when clearing the block. This fixes a bug where ForInst/IfInst instructions may still have references to values while being destroyed.
PiperOrigin-RevId:
229207798
River Riddle [Mon, 14 Jan 2019 17:45:09 +0000 (09:45 -0800)]
Return an empty IntegerSet if the '(' is not parsed.
PiperOrigin-RevId:
229198934
River Riddle [Mon, 14 Jan 2019 13:37:14 +0000 (05:37 -0800)]
Add a FloatAttr::getChecked, and invoke it during Attribute parsing.
PiperOrigin-RevId:
229167099
Nicolas Vasilache [Sun, 13 Jan 2019 21:37:39 +0000 (13:37 -0800)]
Add EDSC support for operator*
PiperOrigin-RevId:
229097351
Nicolas Vasilache [Sat, 12 Jan 2019 12:28:45 +0000 (04:28 -0800)]
Fix typo in lower_vector_transfers.mlir
PiperOrigin-RevId:
229010160
Nicolas Vasilache [Sat, 12 Jan 2019 03:08:09 +0000 (19:08 -0800)]
[MLIR] Clip all access dimensions during LowerVectorTransfers
This CL adds a short term remedy to an issue that was found during execution
tests.
Lowering of vector transfer ops uses the permutation map to determine which
ForInst have been super-vectorized. During materialization to HW vector sizes
however, some of those dimensions may be fully unrolled and do not appear in
the permutation map.
Such dimensions were then not clipped and may have accessed out of bounds.
This CL conservatively clips all dimensions to ensure no out of bounds access.
The longer term solution is still up for debate but will probably require
either passing more information between Materialization and lowering, or just
merging the 2 passes.
PiperOrigin-RevId:
228980787
Nicolas Vasilache [Sat, 12 Jan 2019 00:45:26 +0000 (16:45 -0800)]
[MLIR] Make MLIREmitter emit composed single-result AffineMap by construction
Arguably the dependence of EDSCs on Analysis is not great but on the other
hand this is a strict improvement in the emitted IR and since EDSCs are an
alternative to builders it makes sense that they have as much access to
Analysis as Transforms.
PiperOrigin-RevId:
228967624
Nicolas Vasilache [Sat, 12 Jan 2019 00:08:16 +0000 (16:08 -0800)]
Simplify compositions of AffineApply
This CL is the 6th and last on the path to simplifying AffineMap composition.
This removes `AffineValueMap::forwardSubstitutions` and replaces it by simple
calls to `fullyComposeAffineMapAndOperands`.
PiperOrigin-RevId:
228962580
River Riddle [Fri, 11 Jan 2019 20:33:12 +0000 (12:33 -0800)]
Simplify Attribute constructor definitions.
PiperOrigin-RevId:
228926113
Uday Bondhugula [Fri, 11 Jan 2019 19:29:58 +0000 (11:29 -0800)]
Drop -canonicalize from -dma-generate test case cmd
- should be testing on the output of -dma-generate and not '-dma-generate
-canonicalize'; save trouble for those updating -canonicalize in the future!
PiperOrigin-RevId:
228915192
River Riddle [Fri, 11 Jan 2019 19:23:15 +0000 (11:23 -0800)]
Add check for '[' when parsing a tensor literal list.
PiperOrigin-RevId:
228913908
River Riddle [Fri, 11 Jan 2019 19:03:34 +0000 (11:03 -0800)]
Make sure that type construction arguments are forwarded.
PiperOrigin-RevId:
228910216
Jacques Pienaar [Fri, 11 Jan 2019 18:31:07 +0000 (10:31 -0800)]
Follow up from previous change to avoid setting tokStart 2x.
PiperOrigin-RevId:
228903980
Jacques Pienaar [Fri, 11 Jan 2019 18:30:40 +0000 (10:30 -0800)]
Fix omitted return post failed parse
PiperOrigin-RevId:
228903905
Jacques Pienaar [Fri, 11 Jan 2019 17:24:02 +0000 (09:24 -0800)]
Skip over whitespace using loop. NFC.
Else we can stack overflow on a long sequence of whitespace.
PiperOrigin-RevId:
228893517
Lei Zhang [Fri, 11 Jan 2019 17:12:11 +0000 (09:12 -0800)]
Const fold splat vectors/tensors in standard add, sub, and mul ops
The const folding logic is structurally similar, so use a template
to abstract the common part.
Moved mul(x, 0) to a legalization pattern to be consistent with
mul(x, 1).
Also promoted getZeroAttr() to be a method on Builder since it is
expected to be frequently used.
PiperOrigin-RevId:
228891989
Jacques Pienaar [Fri, 11 Jan 2019 17:03:34 +0000 (09:03 -0800)]
Verify string type token before attempting to get string value.
Add repro that would have resulted in crash previously.
PiperOrigin-RevId:
228890749
Jacques Pienaar [Fri, 11 Jan 2019 15:41:12 +0000 (07:41 -0800)]
Avoid redundant predicate checking in type matching.
Expand type matcher template generator to consider a set of predicates that are known to
hold. This avoids inserting redundant checking for trivially true predicates
(for example predicate that hold according to the op definition). This only targets predicates that trivially holds and does not attempt any logic equivalence proof.
PiperOrigin-RevId:
228880468
Lei Zhang [Fri, 11 Jan 2019 15:22:57 +0000 (07:22 -0800)]
Extract openInputFile() into Support/FileUtilities
Multiple binaries have the needs to open input files. Use this function
to de-duplicate the code.
Also changed openOutputFile() to return errors using std::string since
it is a library call and accessing I/O in library call is not friendly.
PiperOrigin-RevId:
228878221
River Riddle [Fri, 11 Jan 2019 06:08:39 +0000 (22:08 -0800)]
Provide dialect hooks for defining named aliases for AffineMap/IntegerSet/Type.
The AsmPrinter will then query registered dialects for aliases of symbols used within the module and use them in place.
PiperOrigin-RevId:
228831678
Nicolas Vasilache [Fri, 11 Jan 2019 05:54:34 +0000 (21:54 -0800)]
Uniformize composition of AffineApplyOp by construction
This CL is the 5th on the path to simplifying AffineMap composition.
This removes the distinction between normalized single-result AffineMap and
more general composed multi-result map.
One nice byproduct of making the implementation driven by single-result is
that the multi-result extension is a trivial change: the implementation is
still single-result and we just use:
```
unsigned idx = getIndexOf(...);
map.getResult(idx);
```
This CL also fixes an AffineNormalizer implementation issue related to symbols.
Namely it stops performing substitutions on symbols in AffineNormalizer and
instead concatenates them all to be consistent with the call to
`AffineMap::compose(AffineMap)`. This latter call to `compose` cannot perform
simplifications of symbols coming from different maps based on positions only:
i.e. dims are applied and renumbered but symbols must be concatenated.
The only way to determine whether symbols from different AffineApply are the
same is to look at the concrete values. The canonicalizeMapAndOperands is thus
extended with behavior to support replacing operands that appear multiple
times.
Lastly, this CL demonstrates that the implementation is correct by rewriting
ComposeAffineMaps using only `makeComposedAffineApply`. The implementation
uses a matcher because AffineApplyOp are introduced as composed operations on
the fly instead of iteratively forwardSubstituting. For this purpose, a walker
would revisit freshly introduced AffineApplyOp. Regardless, ComposeAffineMaps
is scheduled to disappear, this CL replaces the implementation based on
iterative `forwardSubstitute` by a composed-by-construction
`makeComposedAffineApply`.
Remaining calls to `forwardSubstitute` will be removed in the next CL.
PiperOrigin-RevId:
228830443
Jacques Pienaar [Fri, 11 Jan 2019 05:11:04 +0000 (21:11 -0800)]
Remove unary, binary, ternary ops from op_base
Previously these were all defined as operating on Tensors which is not true in general. These don't serve much now so just inline it and we can extract it out again.
PiperOrigin-RevId:
228827011
Jacques Pienaar [Thu, 10 Jan 2019 21:49:05 +0000 (13:49 -0800)]
Fix error in checking logic and update tests.
* Check was returning success instead of failure when reporting illegal type;
* TFL ops only support tensor types so update tests with corrected logic.
- Removed some checks in broadcasting that don't work with tensor input requirement;
PiperOrigin-RevId:
228770184
Uday Bondhugula [Thu, 10 Jan 2019 20:13:18 +0000 (12:13 -0800)]
Add safeguard against FM explosion
- FM has a worst case exponential complexity. For our purposes, this worst case
is rarely expected, but could still appear due to improperly constructed
constraints (a logical/memory error in other methods for eg.) or artificially
created arbitrarily complex integer sets (adversarial / fuzz tests).
Add a check to detect such an explosion in the number of constraints and
conservatively return false from isEmpty() (instead of running out of memory
or running for too long).
- Add an artifical virus test case.
PiperOrigin-RevId:
228753496
Alex Zinenko [Thu, 10 Jan 2019 09:44:32 +0000 (01:44 -0800)]
Implement branch-free single-division lowering of affine division/remainder
This implements the lowering of `floordiv`, `ceildiv` and `mod` operators from
affine expressions to the arithmetic primitive operations. Integer division
rules in affine expressions explicitly require rounding towards either negative
or positive infinity unlike machine implementations that round towards zero.
In the general case, implementing `floordiv` and `ceildiv` using machine signed
division requires computing both the quotient and the remainder. When the
divisor is positive, this can be simplified by adjusting the dividend and the
quotient by one and switching signs.
In the current use cases, we are unlikely to encounter affine expressions with
negative divisors (affine divisions appear in loop transformations such as
tiling that guarantee that divisors are positive by construction). Therefore,
it is reasonable to use branch-free single-division implementation. In case of
affine maps, divisors can only be literals so we can check the sign and
implement the case for negative divisors when the need arises.
The affine lowering pass can still fail when applied to semi-affine maps
(division or modulo by a symbol).
PiperOrigin-RevId:
228668181
River Riddle [Thu, 10 Jan 2019 08:52:40 +0000 (00:52 -0800)]
Add a few utilities for terminator management:
* Get a specific successor operand.
* Iterator support for non successor operands.
* Fix bug when removing the last operand from the operand list of an Instruction.
* Get the argument number for a BlockArgument.
PiperOrigin-RevId:
228660898
Uday Bondhugula [Thu, 10 Jan 2019 04:00:19 +0000 (20:00 -0800)]
Fix DMA overlap pass buffer mapping
- the double buffer should be indexed (iv floordiv step) % 2 and NOT (iv % 2);
step wasn't being accounted for.
- fix test cases, enable failing test cases
PiperOrigin-RevId:
228635726
Lei Zhang [Wed, 9 Jan 2019 21:50:35 +0000 (13:50 -0800)]
Replace getAttributeName() with .getName()
PiperOrigin-RevId:
228581178
Lei Zhang [Wed, 9 Jan 2019 21:50:20 +0000 (13:50 -0800)]
Add tblgen::Attribute to wrap around TableGen Attr defs
This CL added a tblgen::Attribute class to wrap around raw TableGen
Record getValue*() calls on Attr defs, which will provide a nicer
API for handling TableGen Record.
PiperOrigin-RevId:
228581107
Alex Zinenko [Wed, 9 Jan 2019 20:28:30 +0000 (12:28 -0800)]
Support verbose parsing and printing of terminator operations
Originally, terminators were special kinds of operation and could not be
extended by dialects. Only builtin terminators were supported and they had
custom parsers and printers. Currently, "terminator" is a property of an
operation, making it possible for dialects to define custom terminators.
However, verbose forms of operation syntax were not designed to support
terminators that may have a list of successors (each successor contains a block
name and an optional operand list). Calling printDefaultOp on a terminator
drops all successor information. Dialects are thus required to provide custom
parsers and printers for their terminators.
Introduce the syntax for the list of successors in the verbose from of the
operation. Add support for printing and parsing verbose operations with
successors.
Note that this does not yet add support for unregistered terminators since
"terminator" is a property stored in AsbtractOperation and therefore is only
available for registered operations that have an instance of AbstractOperation.
Add tests for verbose parsing. It is currently impossible to test round-trip
for verbose terminators because none of the known dialects use verbose syntax
for printing terminators by default, however the printer was exercised on the
LLVM IR dialect prototype.
PiperOrigin-RevId:
228566453
Uday Bondhugula [Wed, 9 Jan 2019 18:17:05 +0000 (10:17 -0800)]
Fix affine expr flattener bug + improve simplification in a particular scenario
- fix visitDivExpr: constraints constructed for localVarCst used the original
divisor instead of the simplified divisor; fix this. Add a simple test case
in memref-bound-check that reproduces this bug - although this was encountered in the
context of slicing for fusion.
- improve mod expr flattening: when flattening mod expressions,
cancel out the GCD of the numerator and denominator so that we can get a
simpler flattened form along with a simpler floordiv local var for it
PiperOrigin-RevId:
228539928
Nicolas Vasilache [Wed, 9 Jan 2019 08:41:54 +0000 (00:41 -0800)]
[MLIR] Make SuperVectorization use normalized AffineApplyOp
Supervectorization does not plan on handling multi-result AffineMaps and
non-canonical chains of > 1 AffineApplyOp.
This CL uses the simpler single-result unbounded AffineApplyOp in the
MaterializeVectors pass.
PiperOrigin-RevId:
228469085
Lei Zhang [Wed, 9 Jan 2019 01:19:37 +0000 (17:19 -0800)]
Put Operator and PredCNF into the tblgen namespace
PiperOrigin-RevId:
228429130
Lei Zhang [Wed, 9 Jan 2019 01:19:22 +0000 (17:19 -0800)]
Add tblgen::Type to wrap around TableGen Type defs
This CL added a tblgen::Type class to wrap around raw TableGen
Record getValue*() calls on Type defs, which will provide a
nicer API for handling TableGen Record.
The PredCNF class is also updated to work together with
tblgen::Type.
PiperOrigin-RevId:
228429090
Chris Lattner [Tue, 8 Jan 2019 06:12:30 +0000 (22:12 -0800)]
Delete FuncBuilder::createChecked. It is perhaps still a good idea, but has no
clients. Let's re-add it in the future if there is ever a reason to. NFC.
Unrelatedly, add a use of a variable to unbreak the non-assert build.
PiperOrigin-RevId:
228284026
Nicolas Vasilache [Tue, 8 Jan 2019 04:28:18 +0000 (20:28 -0800)]
Extract BuiltinOps::canonicalizeMapAndOperands
This CL is the 4th on the path to simplifying AffineMap composition.
This CL extract canonicalizeMapAndOperands so it can be reused by other
functions; in particular, this will be used in
`makeNormalizedAffineApply`.
PiperOrigin-RevId:
228277890
Nicolas Vasilache [Tue, 8 Jan 2019 04:14:30 +0000 (20:14 -0800)]
Move makeNormalizedAffineApply
This CL is the 3rd on the path to simplifying AffineMap composition.
This CL just moves `makeNormalizedAffineApply` from VectorAnalysis to
AffineAnalysis where it more naturally belongs.
PiperOrigin-RevId:
228277182
Nicolas Vasilache [Tue, 8 Jan 2019 04:05:14 +0000 (20:05 -0800)]
Introduce AffineMap::compose(AffineMap)
This CL is the 2nd on the path to simplifying AffineMap composition.
This CL uses the now accepted `AffineExpr::compose(AffineMap)` to
implement `AffineMap::compose(AffineMap)`.
Implications of keeping the simplification function in
Analysis are documented where relevant.
PiperOrigin-RevId:
228276646
River Riddle [Tue, 8 Jan 2019 02:42:04 +0000 (18:42 -0800)]
Add parser support for named type aliases.
Alias identifiers can be used in the place of the types that they alias, and are defined as:
type-alias-def ::= '!' alias-name '=' 'type' type
type-alias ::= '!' alias-name
Example:
!avx.m128 = type vector<4 x f32>
...
"foo"(%x) : vector<4 x f32> -> ()
// becomes:
"foo"(%x) : !avx.m128 -> ()
PiperOrigin-RevId:
228271372
Uday Bondhugula [Tue, 8 Jan 2019 02:07:28 +0000 (18:07 -0800)]
Fix 0-d memref corner case for getMemRefRegion()
- fix crash on test/Transforms/canonicalize.mlir with
-memref-bound-check
PiperOrigin-RevId:
228268486
Nicolas Vasilache [Tue, 8 Jan 2019 01:40:31 +0000 (17:40 -0800)]
Introduce AffineExpr::compose(AffineMap)
This CL is the 1st on the path to simplifying AffineMap composition.
This CL uses the now accepted AffineExpr.replaceDimsAndSymbols to
implement `AffineExpr::compose(AffineMap)`.
Arguably, `simplifyAffineExpr` should be part of IR and not Analysis but
this CL does not yet pull the trigger on that.
PiperOrigin-RevId:
228265845
Uday Bondhugula [Tue, 8 Jan 2019 01:34:26 +0000 (17:34 -0800)]
Extend loop-fusion's slicing utility + other fixes / updates
- refactor toAffineFromEq and the code surrounding it; refactor code into
FlatAffineConstraints::getSliceBounds
- add FlatAffineConstraints methods to detect identifiers as mod's and div's of other
identifiers
- add FlatAffineConstraints::getConstantLower/UpperBound
- Address b/
122118218 (don't assert on invalid fusion depths cmdline flags -
instead, don't do anything; change cmdline flags
src-loop-depth -> fusion-src-loop-depth
- AffineExpr/Map print method update: don't fail on null instances (since we have
a wrapper around a pointer, it's avoidable); rationale: dump/print methods should
never fail if possible.
- Update memref-dataflow-opt to add an optimization to avoid a unnecessary call to
IsRangeOneToOne when it's trivially going to be true.
- Add additional test cases to exercise the new support
- update a few existing test cases since the maps are now generated uniformly with
all destination loop operands appearing for the backward slice
- Fix projectOut - fix wrong range for getBestElimCandidate.
- Fix for getConstantBoundOnDimSize() - didn't show up in any test cases since
we didn't have any non-hyperrectangular ones.
PiperOrigin-RevId:
228265152
Uday Bondhugula [Tue, 8 Jan 2019 00:35:06 +0000 (16:35 -0800)]
Convert expr - c * (expr floordiv c) to expr mod c in AffineExpr
- Detect 'mod' to replace the combination of floordiv, mul, and subtract when
possible at construction time; when 'c' is a power of two, this reduces the number of
operations; also more compact and readable. Update simplifyAdd for this.
On a side note:
- with the affine expr flattening we have, a mod expression like d0 mod c
would be flattened into d0 - c * q, c * q <= d0 <= c*q + c - 1, with 'q'
being added as the local variable (q = d0 floordiv c); as a result, a mod
was turned into a floordiv whenever the expression was reconstructed back,
i.e., as d0 - c * (d0 floordiv c); as a result of this change, we recover
the mod back.
- rename SimplifyAffineExpr -> SimplifyAffineStructures (pass had been renamed but
the file hadn't been).
PiperOrigin-RevId:
228258120
Uday Bondhugula [Mon, 7 Jan 2019 23:06:32 +0000 (15:06 -0800)]
Misc readability and doc / code comment related improvements - NFC
- when SSAValue/MLValue existed, code at several places was forced to create additional
aggregate temporaries of SmallVector<SSAValue/MLValue> to handle the conversion; get
rid of such redundant code
- use filling ctors instead of explicit loops
- for smallvectors, change insert(list.end(), ...) -> append(...
- improve comments at various places
- turn getMemRefAccess into MemRefAccess ctor and drop duplicated
getMemRefAccess. In the next CL, provide getAccess() accessors for load,
store, DMA op's to return a MemRefAccess.
PiperOrigin-RevId:
228243638
MLIR Team [Mon, 7 Jan 2019 22:04:02 +0000 (14:04 -0800)]
Spelling: bugpone -> bug-prone
PiperOrigin-RevId:
228231744
Jacques Pienaar [Mon, 7 Jan 2019 18:56:33 +0000 (10:56 -0800)]
Verify the size of the vector in generated op verify.
PiperOrigin-RevId:
228195756
Lei Zhang [Mon, 7 Jan 2019 18:09:34 +0000 (10:09 -0800)]
Various tiny refinements over TableGen Operator class
Use "native" vs "derived" to differentiate attributes on ops: native ones
are specified when creating the op as a part of defining the op, while
derived ones are computed from properties of the op.
PiperOrigin-RevId:
228186962
Jacques Pienaar [Mon, 7 Jan 2019 18:03:34 +0000 (10:03 -0800)]
Addresing follow up comments from cl/
227991412.
PiperOrigin-RevId:
228185819
River Riddle [Mon, 7 Jan 2019 17:59:55 +0000 (09:59 -0800)]
Update the langref to include the rationale and specification of the dialect extended type system.
PiperOrigin-RevId:
228184876
River Riddle [Mon, 7 Jan 2019 17:58:34 +0000 (09:58 -0800)]
Add support for types belonging to unknown dialects. This allows for types to be round tripped even if the dialect that defines them is not linked in. These types will be represented by a new "UnknownType" that uniques them based upon the dialect namespace and raw string type data.
PiperOrigin-RevId:
228184629
Jacques Pienaar [Mon, 7 Jan 2019 17:52:26 +0000 (09:52 -0800)]
Match attributes in input pattern.
Bind attributes similar to operands. Use to rewrite leakyreulo and const rewrite pattern. The attribute type/attributes are not currently checked so should only be used where the attributes match due to the construction of the op.
To support current attribute namespacing, convert __ in attribute name to "$" for matching purposes ('$' is not valid character in variable in TableGen).
Some simplification to make it simpler to specify indented ostream and avoid so many spaces. The goal is not to have perfectly formatted code generated but good enough so that its still easy to read for a user.
PiperOrigin-RevId:
228183639
Jacques Pienaar [Mon, 7 Jan 2019 16:31:24 +0000 (08:31 -0800)]
Add static shape tensor type and rewrite squeeze and reshape rewrites as patterns.
This also moves the predicate declaration in op_base into one section.
PiperOrigin-RevId:
228170793
Alex Zinenko [Mon, 7 Jan 2019 16:16:49 +0000 (08:16 -0800)]
Drop all uses of the ForInst induction variable before deleting ForInst
The `for` instruction defines the loop induction variable it uses. In the
well-formed IR, the induction variable can only be used by the body of the
`for` loop. Existing implementation was explicitly cleaning the body of the
for loop to remove all uses of the induction variable before removing its
definition. However, in ill-formed IR that may appear in some stages of
parsing, there may be (invalid) users of the loop induction variable outside
the loop body. In case of unsuccessful parsing, destructor of the
ForInst-defined Value would assert because there are remaining though invalid
users of this Value. Explicitly drop all uses of the loop induction Value when
destroying a ForInst. It is no longer necessary to explicitly clean the body
of the loop, destructor of the block will take care of this.
PiperOrigin-RevId:
228168880
Alex Zinenko [Mon, 7 Jan 2019 16:16:32 +0000 (08:16 -0800)]
FunctionParser::~FunctionParser: avoid iterator invalidation
When destroying a FunctionParser in case of parsing failure, we clean up all
uses of undefined forward-declared references. This has been implemented as
iteration over the list of uses. However, deleting one use from the list
invalidates the iterator (`IROperand::drop` sets `nextUse` to `nullptr` while
the iterator reads `nextUse` to advance; therefore only the first use was
deleted from the list). Get a new iterator before calling drop to avoid
invalidation.
PiperOrigin-RevId:
228168849
Uday Bondhugula [Mon, 7 Jan 2019 15:51:23 +0000 (07:51 -0800)]
Rename getAffineBinaryExpr -> getAffineBinaryOpExpr, getBinaryAffineOpExpr ->
getAffineBinaryOpExpr for consistency (NFC)
- this is consistent with the name of the class and getAffineDimExpr/ConstantExpr, etc.
PiperOrigin-RevId:
228164959
Nicolas Vasilache [Mon, 7 Jan 2019 15:15:13 +0000 (07:15 -0800)]
Iterate on vector rather than DenseMap during AffineMap normalization
This CL removes a flakyness associated to a spurious iteration on DenseMap
iterators when normalizing AffineMap.
PiperOrigin-RevId:
228160074
Alex Zinenko [Sun, 6 Jan 2019 22:09:15 +0000 (14:09 -0800)]
Add simple constant folding hook for CmpIOp
Integer comparisons can be constant folded if both of their arguments are known
constants, which we can compare in the compiler. This requires implementing
all comparison predicates, but thanks to consistency between LLVM and MLIR
comparison predicates, we have a one-to-one correspondence between predicates
and llvm::APInt comparison functions. Constant folding of comparsions with
maximum/minimum values of the integer type are left for future work.
This will be used to test the lowering of mod/floordiv/ceildiv in affine
expressions at compile time.
PiperOrigin-RevId:
228077580
Alex Zinenko [Sun, 6 Jan 2019 22:09:00 +0000 (14:09 -0800)]
LLVM IR lowering: support integer division and remainder operations
These operations trivially map to LLVM IR counterparts for operands of scalar
and (one-dimensional) vector type. Multi-dimensional vector and tensor type
operands would fail type conversion before the operation conversion takes
place. Add tests for scalar and vector cases. Also add a test for vector
`select` instruction for consistency with other tests.
PiperOrigin-RevId:
228077564
Alex Zinenko [Sun, 6 Jan 2019 22:08:42 +0000 (14:08 -0800)]
Introduce integer division and remainder operations
This adds signed/unsigned integer division and remainder operations to the
StandardOps dialect. Two versions are required because MLIR integers are
signless, but the meaning of the leading bit is important in division and
affects the results. LLVM IR made a similar choice. Define the operations in
the tablegen file and add simple constant folding hooks in the C++
implementation. Handle signed division overflow and division by zero errors in
constant folding. Canonicalization is left for future work.
These operations are necessary to lower affine_apply's down to LLVM IR.
PiperOrigin-RevId:
228077549
Nicolas Vasilache [Sun, 6 Jan 2019 15:55:48 +0000 (07:55 -0800)]
Cleanup spurious DenseMap include
PiperOrigin-RevId:
228059305
Jacques Pienaar [Sat, 5 Jan 2019 16:11:29 +0000 (08:11 -0800)]
Verify type of operands match those specifed in op registry.
Expand type to include matcher predicates. Use CNF form to allow specifying combinations of constraints for type. The matching call for the type is used to verify the construction of the operation as well as in rewrite pattern generation.
The matching initially includes redundant checks (e.g., even if the operand of the op is guaranteed to satisfy some requirement, it is still checked during matcher generation for now). As well as some of the traits specified now check what the generated code already checks. Some of the traits can be removed in future as the verify method will include the relevant checks based on the op definition already.
More work is needed for variadic operands.
CNF form is used so that in the follow up redundant checks in the rewrite patterns could be omitted (e.g., when matching a F32Tensor, one does not need to verify that op X's operand 0 is a Tensor if that is guaranteed by op X's definition). The alternative was to have single matcher function specified, but this would not allow for reasoning about what attributes already hold (at the level of PredAtoms).
Use this new operand type restrictions to rewrite BiasAdd with floating point operands as declarative pattern.
PiperOrigin-RevId:
227991412
Nicolas Vasilache [Sat, 5 Jan 2019 01:21:14 +0000 (17:21 -0800)]
Fix opt build failure
PiperOrigin-RevId:
227938032
Uday Bondhugula [Fri, 4 Jan 2019 22:52:21 +0000 (14:52 -0800)]
Complete TODOs / cleanup for loop-fusion utility
- this is CL 1/2 that does a clean up and gets rid of one limitation in an
underlying method - as a result, fusion works for more cases.
- fix bugs/incomplete impl. in toAffineMapFromEq
- fusing across rank changing reshapes for example now just works
For eg. given a rank 1 memref to rank 2 memref reshape (64 -> 8 x 8) like this,
-loop-fusion -memref-dataflow-opt now completely fuses and inlines/store-forward
to get rid of the temporary:
INPUT
// Rank 1 -> Rank 2 reshape
for %i0 = 0 to 64 {
%v = load %A[%i0]
store %v, %B[%i0 floordiv 8, i0 mod 8]
}
for %i1 = 0 to 8
for %i2 = 0 to 8
%w = load %B[%i1, i2]
"foo"(%w) : (f32) -> ()
OUTPUT
$ mlir-opt -loop-fusion -memref-dataflow-opt fuse_reshape.mlir
#map0 = (d0, d1) -> (d0 * 8 + d1)
mlfunc @fuse_reshape(%arg0: memref<64xf32>) {
for %i0 = 0 to 8 {
for %i1 = 0 to 8 {
%0 = affine_apply #map0(%i0, %i1)
%1 = load %arg0[%0] : memref<64xf32>
"foo"(%1) : (f32) -> ()
}
}
}
AFAIK, there is no polyhedral tool / compiler that can perform such fusion -
because it's not really standard loop fusion, but possible through a
generalized slicing-based approach such as ours.
PiperOrigin-RevId:
227918338
Smit Hinsu [Fri, 4 Jan 2019 19:32:10 +0000 (11:32 -0800)]
Add an example of rank zero tensor in go/mlir-spec
TESTED with preview
PiperOrigin-RevId:
227887054
Smit Hinsu [Fri, 4 Jan 2019 19:27:58 +0000 (11:27 -0800)]
Handle parsing failure for splat elements attribute
Currently, it emits the error but does not terminate parsing.
TESTED with unit test
PiperOrigin-RevId:
227886274
Nicolas Vasilache [Fri, 4 Jan 2019 18:45:58 +0000 (10:45 -0800)]
[MLIR] Introduce normalized single-result unbounded AffineApplyOp
Supervectorization does not plan on handling multi-result AffineMaps and
non-canonical chains of > 1 AffineApplyOp.
This CL introduces a simpler abstraction and composition of single-result
unbounded AffineApplyOp by using the existing unbound AffineMap composition.
This CL adds a simple API call and relevant tests:
```c++
OpPointer<AffineApplyOp> makeNormalizedAffineApply(
FuncBuilder *b, Location loc, AffineMap map, ArrayRef<Value*> operands);
```
which creates a single-result unbounded AffineApplyOp.
The operands of AffineApplyOp are not themselves results of AffineApplyOp by
consrtuction.
This represent the simplest possible interface to complement the composition
of (mathematical) AffineMap, for the cases when we are interested in applying
it to Value*.
In this CL the composed AffineMap is not compressed (i.e. there exist operands
that are not part of the result). A followup commit will compress to normal
form.
The single-result unbounded AffineApplyOp abstraction will be used in a
followup CL to support the MaterializeVectors pass.
PiperOrigin-RevId:
227879021
River Riddle [Fri, 4 Jan 2019 17:55:48 +0000 (09:55 -0800)]
Introduce CRTP TypeBase class to simplify type construction and validation.
This impl class currently provides the following:
* auto definition of the 'ImplType = StorageClass'
* get/getChecked wrappers around TypeUniquer
* 'verifyConstructionInvariants' hook
- This hook verifies that the arguments passed into get/getChecked are valid
to construct a type instance with.
With this, all non-generic type uniquing has been moved out of MLIRContext.cpp
PiperOrigin-RevId:
227871108
Chris Lattner [Fri, 4 Jan 2019 15:23:28 +0000 (07:23 -0800)]
Introduce a simple canonicalization of affine_apply that drops unused dims and
symbols.
Included with this is some other infra:
- Testcases for other canonicalizations that I will implement next.
- Some helpers in AffineMap/Expr for doing simple walks without defining whole
visitor classes.
- A 'replaceDimsAndSymbols' facility that I'll be using to simplify maps and
exprs, e.g. to fold one constant into a mapping and to drop/renumber unused dims.
- Allow index (and everything else) to work in memref's, as we previously
discussed, to make the testcase easier to write.
- A "getAffineBinaryExpr" helper to produce a binop when you know the kind as
an enum.
This line of work will eventually subsume the ComposeAffineApply pass, but it is no where close to that yet :-)
PiperOrigin-RevId:
227852951
Lei Zhang [Fri, 4 Jan 2019 13:05:43 +0000 (05:05 -0800)]
Fix format for empty method definition
PiperOrigin-RevId:
227840511
Alex Zinenko [Fri, 4 Jan 2019 09:34:16 +0000 (01:34 -0800)]
TableGen standard arithmetic ops
Use tablegen to generate definitions of the standard binary arithmetic
operations. These operations share a lot of boilerplate that is better off
generated by a tool.
Using tablegen for standard binary arithmetic operations requires the following
modifications.
1. Add a bit field `hasConstantFolder` to the base Op tablegen class; generate
the `constantFold` method signature if the bit is set. Differentiate between
single-result and zero/multi-result functions that use different signatures.
The implementation of the method remains in C++, similarly to canonicalization
patterns, since it may be large and non-trivial.
2. Define the `AnyType` record of class `Type` since `BinaryOp` currently
provided in op_base.td is supposed to operate on tensors and other tablegen
users may rely on this behavior.
Note that this drops the inline documentation on the operation classes that was
copy-pasted around anyway. Since we don't generate g3doc from tablegen yet,
keep LangRef.md as it is. Eventually, the user documentation can move to the
tablegen definition file as well.
PiperOrigin-RevId:
227820815
Jacques Pienaar [Thu, 3 Jan 2019 23:53:54 +0000 (15:53 -0800)]
Use Operator class in OpDefinitionsGen. Cleanup NFC.
PiperOrigin-RevId:
227764826
Nicolas Vasilache [Thu, 3 Jan 2019 23:52:34 +0000 (15:52 -0800)]
[MLIR] More graceful failure in MaterializeVectors
Even though it is unexpected except in pathological cases, a nullptr clone may
be returned. This CL handles the nullptr return gracefuly.
PiperOrigin-RevId:
227764615
Nicolas Vasilache [Thu, 3 Jan 2019 23:48:18 +0000 (15:48 -0800)]
[MLIR] Drop strict super-vector requirement in MaterializeVector
The strict requirement (i.e. at least 2 HW vectors in a super-vector) was a
premature optimization to avoid interfering with other vector code potentially
introduced via other means.
This CL avoids this premature optimization and the spurious errors it causes
when super-vector size == HW vector size (which is a possible corner case).
This may be revisited in the future.
PiperOrigin-RevId:
227763966
Nicolas Vasilache [Thu, 3 Jan 2019 23:34:37 +0000 (15:34 -0800)]
[MLIR] Fix uninitialized value found with msan
The omission of an early exit created opportunities for unitialized memory
reads. This CL fixes the issue.
PiperOrigin-RevId:
227761814
Nicolas Vasilache [Thu, 3 Jan 2019 23:30:45 +0000 (15:30 -0800)]
[MLIR] Handle corner case in MaterializeVectors
This corner was found when stress testing with a functional end-to-end CPU
path. In the case where the hardware vector size is 1x...x1 the `keep` vector
is empty and would result a crash.
While there is no reason to expect a 1x...x1 HW vector in practice, this case
can just gracefully degrade to scalar, which is what this CL allows.
PiperOrigin-RevId:
227761097
River Riddle [Thu, 3 Jan 2019 22:29:52 +0000 (14:29 -0800)]
Split the standard types from builtin types and move them into separate source files(StandardTypes.cpp/h). After this cl only FunctionType and IndexType are builtin types, but IndexType will likely become a standard type when the ml/cfgfunc merger is done. Mechanical NFC.
PiperOrigin-RevId:
227750918
Jacques Pienaar [Thu, 3 Jan 2019 16:23:35 +0000 (08:23 -0800)]
Include both TF and TFL ops.td in legalize patterns.
Need to do some ifdef jumps with TableGen to avoid errors due to including the base multiple times. The way TableGen flags repeated includes is by way of checking the include directive this necessitates that the guards are on the includes as well as around the classes/defines.
PiperOrigin-RevId:
227692030
Jacques Pienaar [Thu, 3 Jan 2019 00:11:42 +0000 (16:11 -0800)]
Match the op via isa instead of string compare.
* Match using isa
- This limits the rewrite pattern to ops defined in op registry but that is probably better end state (esp. for additional verification).
PiperOrigin-RevId:
227598946
Jacques Pienaar [Wed, 2 Jan 2019 23:21:52 +0000 (15:21 -0800)]
Add tf.Add op
Add ops.td for TF dialect and start by adding tf.Add (op used in legalizer pattern). This CL does not add TensorOp trait (that's not part of OpTrait namespace).
Remove OpCode emission that is not currently used and can be added back later if needed.
PiperOrigin-RevId:
227590973
River Riddle [Wed, 2 Jan 2019 22:16:40 +0000 (14:16 -0800)]
Implement initial support for dialect specific types.
Dialect specific types are registered similarly to operations, i.e. registerType<...> within the dialect. Unlike operations, there is no notion of a "verbose" type, that is *all* types must be registered to a dialect. Casting support(isa/dyn_cast/etc.) is implemented by reserving a range of type kinds in the top level Type class as opposed to string comparison like operations.
To support derived types a few hooks need to be implemented:
In the concrete type class:
- static char typeID;
* A unique identifier for the type used during registration.
In the Dialect:
- typeParseHook and typePrintHook must be implemented to provide parser support.
The syntax for dialect extended types is as follows:
dialect-type: '!' dialect-namespace '<' '"' type-specific-data '"' '>'
The 'type-specific-data' is information used to identify different types within the dialect, e.g:
- !tf<"variant"> // Tensor Flow Variant Type
- !tf<"string"> // Tensor Flow String Type
TensorFlow/TensorFlowControl types are now implemented as dialect specific types as a proof
of concept.
PiperOrigin-RevId:
227580052
Alex Zinenko [Wed, 2 Jan 2019 20:52:41 +0000 (12:52 -0800)]
Merge LowerAffineApplyPass into LowerIfAndForPass, rename to LowerAffinePass
This change is mechanical and merges the LowerAffineApplyPass and
LowerIfAndForPass into a single LowerAffinePass. It makes a step towards
defining an "affine dialect" that would contain all polyhedral-related
constructs. The motivation for merging these two passes is based on retiring
MLFunctions and, eventually, transforming If and For statements into regular
operations. After that happens, LowerAffinePass becomes yet another
legalization.
PiperOrigin-RevId:
227566113
Jacques Pienaar [Wed, 2 Jan 2019 20:43:52 +0000 (12:43 -0800)]
Add builderCall to Type and add constant attr class.
With the builder to construct the type on the Type, the appropriate mlir::Type can be constructed where needed. Also add a constant attr class that has the attribute and value as members.
PiperOrigin-RevId:
227564789
Alex Zinenko [Wed, 2 Jan 2019 20:36:58 +0000 (12:36 -0800)]
LowerForAndIf: expand affine_apply's inplace
Existing implementation was created before ML/CFG unification refactoring and
did not concern itself with further lowering to separate concerns. As a
result, it emitted `affine_apply` instructions to implement `for` loop bounds
and `if` conditions and required a follow-up function pass to lower those
`affine_apply` to arithmetic primitives. In the unified function world,
LowerForAndIf is mostly a lowering pass with low complexity. As we move
towards a dialect for affine operations (including `for` and `if`), it makes
sense to lower `for` and `if` conditions directly to arithmetic primitives
instead of relying on `affine_apply`.
Expose `expandAffineExpr` function in LoweringUtils. Use this function
together with `expandAffineMaps` to emit primitives that implement loop and
branch conditions directly.
Also remove tests that become unnecessary after transforming LowerForAndIf into
a function pass.
PiperOrigin-RevId:
227563608
Alex Zinenko [Wed, 2 Jan 2019 20:35:57 +0000 (12:35 -0800)]
Refactor LowerAffineApply
In LoweringUtils, extract out `expandAffineMap`. This function takes an affine
map and a list of values the map should be applied to and emits a sequence of
arithmetic instructions that implement the affine map. It is independent of
the AffineApplyOp and can be used in places where we need to insert an
evaluation of an affine map without relying on a (temporary) `affine_apply`
instruction. This prepares for a merge between LowerAffineApply and
LowerForAndIf passes.
Move the `expandAffineApply` function to the LowerAffineApply pass since it is
the only place that must be aware of the `affine_apply` instructions.
PiperOrigin-RevId:
227563439
Chris Lattner [Wed, 2 Jan 2019 20:32:30 +0000 (12:32 -0800)]
Update the g3docs to reflect the merging of CFG and ML functions.
PiperOrigin-RevId:
227562943
Chris Lattner [Wed, 2 Jan 2019 18:20:00 +0000 (10:20 -0800)]
Eliminate extfunc/cfgfunc/mlfunc as a concept, and just use 'func' instead.
The entire compiler now looks at structural properties of the function (e.g.
does it have one block, does it contain an if/for stmt, etc) so the only thing
holding up this difference is round tripping through the parser/printer syntax.
Removing this shrinks the compile by ~140LOC.
This is step 31/n towards merging instructions and statements. The last step
is updating the docs, which I will do as a separate patch in order to split it
from this mostly mechanical patch.
PiperOrigin-RevId:
227540453
River Riddle [Wed, 2 Jan 2019 17:26:35 +0000 (09:26 -0800)]
Rename OperationPrefix to Namespace in Dialect. This is important as dialects will soon be able to define more than just operations.
Moving forward dialect namespaces cannot contain '.' characters.
This cl also standardizes that operation names must begin with the dialect namespace followed by a '.'.
PiperOrigin-RevId:
227532193
Alex Zinenko [Wed, 2 Jan 2019 16:52:19 +0000 (08:52 -0800)]
LLVM IR Lowering: support "select"
This commit adds support for the "select" operation that lowers directly into
its LLVM IR counterpart. A simple test is included.
PiperOrigin-RevId:
227527893