- makes the code compact (gets rid of MLFunction walking logic)
- makes it natural to extend to fold affine map loop bounds
and if conditions (upcoming CL)
PiperOrigin-RevId: 214668957
ResultIsFloatLike/ResultIsIntegerLike, move some code out of templates into
shared code, keep the ops in StandardOps.cpp/h sorted.
This significantly reduces the boilerplate for Add/Mul sorts of ops. In a subsequent patch, I plan to rename OpBase to Op, but didn't want to clutter this diff.
PiperOrigin-RevId: 214622871
This CL retricts shorthand notation printing to only the bounds that can
be roundtripped unambiguously; i.e.:
1. ()[]->(%some_cst) ()[]
2. ()[s0]->(s0) ()[%some_symbol]
Upon inspection it turns out that the constant case was lossy so this CL also
updates it.
Note however that fixing this issue exhibits a potential issues in unroll.mlir.
L488 exhibits a map ()[s0] -> (1)()[%arg0] which could be simplified down to
()[]->(1)()[].
This does not seem like a bug but maybe an undesired complexity in the maps
generated by unrolling.
bondhugula@, care to take a look?
PiperOrigin-RevId: 214531410
This CL adds support for `mulf` which is necessary to write/emit a simple scalar
matmul in MLIR. This CL does not consider automation of generation of ops but
mulf is important and useful enough to be added on its own atm.
PiperOrigin-RevId: 214496098
Super thin slice that can convert a MLIR program (with addfs) to MLIR HLO dialect. Add this as translations to mlir-translate. Also add hlo::AddOp op and HLO op registration.
PiperOrigin-RevId: 214480409
The AsmPrinter wrongly assumes that all single ssa-id AffineMap
are the identity map for the purpose of printing.
This CL adds the missing level of indirection as well as a test.
This bug was originally shaken off by the experimental TC->MLIR path.
Before this CL, the test would print:
```
mlfunc @mlfuncsimplemap(%arg0 : affineint, %arg1 : affineint, %arg2 : affineint) {
for %i0 = 0 to %arg0 {
for %i1 = 0 to %i0 {
~~~ should be %arg1
%c42_i32 = constant 42 : i32
}
}
return
}
```
PiperOrigin-RevId: 214120817
Instead of linking in different initializeMLIRContext functions, add a registry mechanism and function to initialize all registered ops in a given MLIRContext. Initialize all registered ops along with the StandardOps when constructing a MLIRContext.
PiperOrigin-RevId: 214073842
consolidate the implementations in CFGFunctionViewGraph.cpp into it, and
implement the missing const specializations for functions. NFC.
PiperOrigin-RevId: 214048649
verifier. We get most of this infrastructure directly from LLVM, we just
need to adapt it to our CFG abstraction.
This has a few unrelated changes engangled in it:
- getFunction() in various classes was const incorrect, fix it.
- This moves Verifier.cpp to the analysis library, since Verifier depends on
dominance and these are both really analyses.
- IndexedAccessorIterator::reference was defined wrong, leading to really
exciting template errors that were fun to diagnose.
- This flips the boolean sense of the foldOperation() function in constant
folding pass in response to previous patch feedback.
PiperOrigin-RevId: 214046593
Alternatively, we can defined a TFComplexType with a width parameter in the
mlir, then both types can be converted to the same mlir type with different width (like IntegerType).
We chose to use a direct mapping because there are only two TF Complex types.
PiperOrigin-RevId: 213856651
optimization pass:
- Give the ability for operations to implement a constantFold hook (a simple
one for single-result ops as well as general support for multi-result ops).
- Implement folding support for constant and addf.
- Implement support in AbstractOperation and Operation to make this usable by
clients.
- Implement a very simple constant folding pass that does top down folding on
CFG and ML functions, with a testcase that exercises all the above stuff.
Random cleanups:
- Improve the build APIs for ConstantOp.
- Stop passing "-o -" to mlir-opt in the testsuite, since that is the default.
PiperOrigin-RevId: 213749809
- extend loop unroll-jam similar to loop unroll for affine bounds
- extend both loop unroll/unroll-jam to deal with cleanup loop for non multiple
of unroll factor.
- extend promotion of single iteration loops to work with affine bounds
- fix typo bugs in loop unroll
- refactor common code b/w loop unroll and loop unroll-jam
- move prototypes of non-pass transforms to LoopUtils.h
- add additional builder methods.
- introduce loopUnrollUpTo(factor) to unroll by either factor or trip count,
whichever is less.
- remove Statement::isInnermost (not used for now - will come back at the right
place/in right form later)
PiperOrigin-RevId: 213471227
mlir-translate is a tool to translate from/to MLIR. The translations are registered at link time and intended for use in tests. An identity transformation (mlir-to-mlir) is registered by default as example and used in the parser test where simply parsing & printing required.
The TranslateFunctions take filenames (instead of MemoryBuffer) to allow translations special write behavior (e.g., writing to uncommon filesystems).
PiperOrigin-RevId: 213370448
- add builder method for ReturnOp
- expose API from Transforms/ to work on specific ML statements (do this for
LoopUnroll, LoopUnrollAndJam)
- add MLFuncBuilder::getForStmtBodyBuilder, ::getBlock
PiperOrigin-RevId: 213074178
Use these methods to simplify existing code. Rename getConstantMap
getConstantAffineMap. Move declarations to group similar ones together.
PiperOrigin-RevId: 212814829
unroll/unroll-and-jam more powerful; add additional affine expr builder methods
- use previously added analysis/simplification to infer multiple of unroll
factor trip counts, making loop unroll/unroll-and-jam more general.
- for loop unroll, support bounds that are single result affine map's with the
same set of operands. For unknown loop bounds, loop unroll will now work as
long as trip count can be determined to be a multiple of unroll factor.
- extend getConstantTripCount to deal with single result affine map's with the
same operands. move it to mlir/Analysis/LoopAnalysis.cpp
- add additional builder utility methods for affine expr arithmetic
(difference, mod/floordiv/ceildiv w.r.t postitive constant). simplify code to
use the utility methods.
- move affine analysis routines to AffineAnalysis.cpp/.h from
AffineStructures.cpp/.h.
- Rename LoopUnrollJam to LoopUnrollAndJam to match class name.
- add an additional simplification for simplifyFloorDiv, simplifyCeilDiv
- Rename AffineMap::getNumOperands() getNumInputs: an affine map by itself does
not have operands. Operands are passed to it through affine_apply, from loop
bounds/if condition's, etc., operands are stored in the latter.
This should be sufficiently powerful for now as far as unroll/unroll-and-jam go for TPU
code generation, and can move to other analyses/transformations.
Loop nests like these are now unrolled without any cleanup loop being generated.
for %i = 1 to 100 {
// unroll factor 4: no cleanup loop will be generated.
for %j = (d0) -> (d0) (%i) to (d0) -> (5*d0 + 3) (%i) {
%x = "foo"(%j) : (affineint) -> i32
}
}
for %i = 1 to 100 {
// unroll factor 4: no cleanup loop will be generated.
for %j = (d0) -> (d0) (%i) to (d0) -> (d0 - d mod 4 - 1) (%i) {
%y = "foo"(%j) : (affineint) -> i32
}
}
for %i = 1 to 100 {
for %j = (d0) -> (d0) (%i) to (d0) -> (d0 + 128) (%i) {
%x = "foo"() : () -> i32
}
}
TODO(bondhugula): extend this to LoopUnrollAndJam as well in the next CL (with minor
changes).
PiperOrigin-RevId: 212661212
Previously the error could mislead into thinking it was a parser bug instead of the input being erroneous. Update to make it clearer.
PiperOrigin-RevId: 212271145
infrastructure, instead of returning a const char*. This allows custom
formatting and more interesting diagnostics.
This patch regresses the error message quality from the control flow
lowering pass, I'll address this in a subsequent patch.
PiperOrigin-RevId: 212210681
Ensure delimiters are absent where not expected. This is only checked in the case where operand count is known. This allows for the currently accepted case where there is a operand list with no delimiter and variable number of operands (which could be empty), followed by a delimited operand list.
PiperOrigin-RevId: 212202064
loop counts. Improve / refactor loop unroll / loop unroll and jam.
- add utility to remove single iteration loops.
- use this utility to promote single iteration loops after unroll/unroll-and-jam
- use loopUnrollByFactor for loopUnrollFull and remove most of the latter.
- add methods for getting constant loop trip count
PiperOrigin-RevId: 212039569
- Compress the identifier/kind of a Function into a single word.
- Eliminate otherFailure from verifier now that we always have a location
- Eliminate the error string from the verifier now that we always have
locations.
- Simplify the parser's handling of fn forward references, using the location
tracked by the function.
PiperOrigin-RevId: 211985101
terminators. Improve mlir-opt to print better location info in the split-files
case.
Before:
error: unexpected error: branch has 2 operands, but target block has 1
br bb1(%0tensorflow/mlir#1, %0tensorflow/mlir#0 : i17, i1)
^
after:
invalid.mlir split at line tensorflow/mlir#305:6:3: error: unexpected error: branch has 2 operands, but target block has 1
br bb1(%0tensorflow/mlir#1, %0tensorflow/mlir#0 : i17, i1)
^
It still isn't optimal (it would be better to have just the original file and
line number but is a step forward, and doing the optimal thing would be a lot
more complicated.
PiperOrigin-RevId: 211917067
inserting shape_casts as necessary.
Along the way:
- Add some missing accessors to the AtLeastNOperands trait.
- Implement shape_cast / ShapeCastOp standard op.
- Improve handling of errors in mlir-opt, making it easier to understand
errors when invalid IR is rejected by the verifier.
PiperOrigin-RevId: 211897877
- Make the tf-lower-control flow handle error cases better. Add a testcase
that (currently) fails due to type mismatches.
- Factor more code in the verifier for basic block argument checking, and
check more invariants.
- Fix a crasher in the asmprinter on null instructions (which only occurs on
invalid code).
- Fix a bug handling conditional branches with no block operands, it would
access &operands[0] instead of using operands.data().
- Enhance the mlir-opt driver to use the verifier() in a non-crashing mode,
allowing issues to be reported as diagnostics.
PiperOrigin-RevId: 211818291
Enable using GraphWriter to dump graphviz in debug mode (kept to debug builds completely as this is only for debugging). Add option to mlir-opt to print CFGFunction after every transform in debug mode.
PiperOrigin-RevId: 211578699
- handle floordiv/ceildiv in AffineExprFlattener; update the simplification to
work even if mod/floordiv/ceildiv expressions appearing in the tree can't be eliminated.
- refactor the flattening / analysis to move it out of lib/Transforms/
- fix MutableAffineMap::isMultipleOf
- add AffineBinaryOpExpr:getAdd/getMul/... utility methods
PiperOrigin-RevId: 211540536
- Add a new -verify mode to the mlir-opt tool that allows writing test cases
for optimization and other passes that produce diagnostics.
- Refactor existing the -check-parser-errors flag to mlir-opt into a new
-split-input-file option which is orthogonal to -verify.
- Eliminate the special error hook the parser maintained and use the standard
MLIRContext's one instead.
- Enhance the default MLIRContext error reporter to print file/line/col of
errors when it is available.
- Add new createChecked() methods to the builder that create ops and invoke
the verify hook on them, use this to detected unhandled code in the
RaiseControlFlow pass.
- Teach mlir-opt about expected-error @+, it previously only worked with @-
PiperOrigin-RevId: 211305770