summaryrefslogtreecommitdiffstats
path: root/mlir/tools
Commit message (Collapse)AuthorAgeFilesLines
...
* Adds a dependence check to test whether two accesses to the same memref ↵MLIR Team2019-03-291-0/+5
| | | | | | | | | | | | access the same element. - Builds access functions and iterations domains for each access. - Builds dependence polyhedron constraint system which has equality constraints for equated access functions and inequality constraints for iteration domain loop bounds. - Runs elimination on the dependence polyhedron to test if no dependence exists between the accesses. - Adds a trivial LoopFusion transformation pass with a simple test policy to test dependence between accesses to the same memref in adjacent loops. - The LoopFusion pass will be extended in subsequent CLs. PiperOrigin-RevId: 219630898
* Introduce memref bound checking.Uday Bondhugula2019-03-291-6/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Introduce analysis to check memref accesses (in MLFunctions) for out of bound ones. It works as follows: $ mlir-opt -memref-bound-check test/Transforms/memref-bound-check.mlir /tmp/single.mlir:10:12: error: 'load' op memref out of upper bound access along dimension tensorflow/mlir#1 %x = load %A[%idxtensorflow/mlir#0, %idxtensorflow/mlir#1] : memref<9 x 9 x i32> ^ /tmp/single.mlir:10:12: error: 'load' op memref out of lower bound access along dimension tensorflow/mlir#1 %x = load %A[%idxtensorflow/mlir#0, %idxtensorflow/mlir#1] : memref<9 x 9 x i32> ^ /tmp/single.mlir:10:12: error: 'load' op memref out of upper bound access along dimension tensorflow/mlir#2 %x = load %A[%idxtensorflow/mlir#0, %idxtensorflow/mlir#1] : memref<9 x 9 x i32> ^ /tmp/single.mlir:10:12: error: 'load' op memref out of lower bound access along dimension tensorflow/mlir#2 %x = load %A[%idxtensorflow/mlir#0, %idxtensorflow/mlir#1] : memref<9 x 9 x i32> ^ /tmp/single.mlir:12:12: error: 'load' op memref out of upper bound access along dimension tensorflow/mlir#1 %y = load %B[%idy] : memref<128 x i32> ^ /tmp/single.mlir:12:12: error: 'load' op memref out of lower bound access along dimension tensorflow/mlir#1 %y = load %B[%idy] : memref<128 x i32> ^ #map0 = (d0, d1) -> (d0, d1) #map1 = (d0, d1) -> (d0 * 128 - d1) mlfunc @test() { %0 = alloc() : memref<9x9xi32> %1 = alloc() : memref<128xi32> for %i0 = -1 to 9 { for %i1 = -1 to 9 { %2 = affine_apply #map0(%i0, %i1) %3 = load %0[%2tensorflow/mlir#0, %2tensorflow/mlir#1] : memref<9x9xi32> %4 = affine_apply #map1(%i0, %i1) %5 = load %1[%4] : memref<128xi32> } } return } - Improves productivity while manually / semi-automatically developing MLIR for testing / prototyping; also provides an indirect way to catch errors in transformations. - This pass is an easy way to test the underlying affine analysis machinery including low level routines. Some code (in getMemoryRegion()) borrowed from @andydavis cl/218263256. While on this: - create mlir/Analysis/Passes.h; move Pass.h up from mlir/Transforms/ to mlir/ - fix a bug in AffineAnalysis.cpp::toAffineExpr TODO: extend to non-constant loop bounds (straightforward). Will transparently work for all accesses once floordiv, mod, ceildiv are supported in the AffineMap -> FlatAffineConstraints conversion. PiperOrigin-RevId: 219397961
* Change Attr to have a storage and return type.Jacques Pienaar2019-03-291-10/+24
| | | | | | Separate the storage and return type more explicitly. This is in preparation for, among others, allowing supporting enum attributes where the return type is a enum class. NFC. PiperOrigin-RevId: 219368487
* Implement value type abstraction for attributes.River Riddle2019-03-291-4/+4
| | | | | | This is done by changing Attribute to be a POD interface around an underlying pointer storage and adding in-class support for isa/dyn_cast/cast. PiperOrigin-RevId: 218764173
* Introduce Fourier-Motzkin variable elimination + other cleanup/supportUday Bondhugula2019-03-291-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Introduce Fourier-Motzkin variable elimination to eliminate a dimension from a system of linear equalities/inequalities. Update isEmpty to use this. Since FM is only exact on rational/real spaces, an emptiness check based on this is guaranteed to be exact whenever it says the underlying set is empty; if it says, it's not empty, there may still be no integer points in it. Also, supports a version that computes "dark shadows". - Test this by checking for "always false" conditionals in if statements. - Unique IntegerSet's that are small (few constraints, few variables). This basically means the canonical empty set and other small sets that are likely commonly used get uniqued; allows checking for the canonical empty set by pointer. IntegerSet::kUniquingThreshold gives the threshold constraint size for uniqui'ing. - rename simplify-affine-expr -> simplify-affine-structures Other cleanup - IntegerSet::numConstraints, AffineMap::numResults are no longer needed; remove them. - add copy assignment operators for AffineMap, IntegerSet. - rename Invalid() -> Null() on AffineExpr, AffineMap, IntegerSet - Misc cleanup for FlatAffineConstraints API PiperOrigin-RevId: 218690456
* [MLIR] Basic infrastructure for vectorization testNicolas Vasilache2019-03-291-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This CL implements a very simple loop vectorization **test** and the basic infrastructure to support it. The test simply consists in: 1. matching the loops in the MLFunction and all the Load/Store operations nested under the loop; 2. testing whether all the Load/Store are contiguous along the innermost memory dimension along that particular loop. If any reference is non-contiguous (i.e. the ForStmt SSAValue appears in the expression), then the loop is not-vectorizable. The simple test above can gradually be extended with more interesting behaviors to account for the fact that a layout permutation may exist that enables contiguity etc. All these will come in due time but it is worthwhile noting that the test already supports detection of outer-vetorizable loops. In implementing this test, I also added a recursive MLFunctionMatcher and some sugar that can capture patterns such as `auto gemmLike = Doall(Doall(Red(LoadStore())))` and allows iterating on the matched IR structures. For now it just uses in order traversal but post-order DFS will be useful in the future once IR rewrites start occuring. One may note that the memory management design decision follows a different pattern from MLIR. After evaluating different designs and how they quickly increase cognitive overhead, I decided to opt for the simplest solution in my view: a class-wide (threadsafe) RAII context. This way, a pass that needs MLFunctionMatcher can just have its own locally scoped BumpPtrAllocator and everything is cleaned up when the pass is destroyed. If passes are expected to have a longer lifetime, then the contexts can easily be scoped inside the runOnMLFunction call and storage lifetime reduced. Lastly, whatever the scope of threading (module, function, pass), this is expected to also be future-proof wrt concurrency (but this is a detail atm). PiperOrigin-RevId: 217622889
* [opgen] Change Attr to be more intuitive to insertJacques Pienaar2019-03-291-14/+22
| | | | | | Change how attributes can be added to an Op to make the syntax in the td file a bit cleaner. Also avoid unnecessarily emitting verify method (trivial return false one that's already in base) and use custom syntax in test. PiperOrigin-RevId: 217330036
* Make the op specification more declarative wrt properties.Jacques Pienaar2019-03-291-73/+30
| | | | | | Also remove the builder generator as it isn't useful until there are output constraints. PiperOrigin-RevId: 217322623
* Add op gen tool to generate C++ classes for Operations.Jacques Pienaar2019-03-291-0/+382
| | | | | | | | Create tblgen based tool to generate the C++ Op definitions. The modelling is currently simple (ops, attributes, properties) with the printer/parser/verifier the bodies of those functions and builders being very explicit. PiperOrigin-RevId: 217150213
* Implement a super sketched out pattern match/rewrite framework and a sketchedChris Lattner2019-03-291-19/+24
| | | | | | | | | | | out canonicalization pass to drive it, and a simple (x-x) === 0 pattern match as a test case. There is a tremendous number of improvements that need to land, and the matcher/rewriter and patterns will be split out of this file, but this is a starting point. PiperOrigin-RevId: 216788604
* Add target independent standard DMA ops: dma.start, dma.waitUday Bondhugula2019-03-291-1/+2
| | | | | | | | | | | Add target independent standard DMA ops: dma.start, dma.wait. Update pipeline data transfer to use these to detect DMA ops. While on this - return failure from mlir-opt::performActions if a pass generates invalid output - improve error message for verify 'n' operand traits PiperOrigin-RevId: 216429885
* Affine map composition.MLIR Team2019-03-291-1/+7
| | | | | | | | *) Implements AffineValueMap forward substitution for AffineApplyOps. *) Adds ComposeAffineMaps transformation pass, which composes affine maps for all loads/stores in an MLFunction. *) Adds multiple affine map composition tests. PiperOrigin-RevId: 216216446
* Introduce loop body skewing / loop pipelining / loop shifting utility.Uday Bondhugula2019-03-291-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - loopBodySkew shifts statements of a loop body by stmt-wise delays, and is typically meant to be used to: - allow overlap of non-blocking start/wait until completion operations with other computation - allow shifting of statements (for better register reuse/locality/parallelism) - software pipelining (when applied to the innermost loop) - an additional argument specifies whether to unroll the prologue and epilogue. - add method to check SSA dominance preservation. - add a fake loop pipeline pass to test this utility. Sample input/output are below. While on this, fix/add following: - fix minor bug in getAddMulPureAffineExpr - add additional builder methods for common affine map cases - fix const_operand_iterator's for ForStmt, etc. When there is no such thing as 'const MLValue', the iterator shouldn't be returning const MLValue's. Returning MLValue is const correct. Sample input/output examples: 1) Simplest case: shift second statement by one. Input: for %i = 0 to 7 { %y = "foo"(%i) : (affineint) -> affineint %x = "bar"(%i) : (affineint) -> affineint } Output: #map0 = (d0) -> (d0 - 1) mlfunc @loop_nest_simple1() { %c8 = constant 8 : affineint %c0 = constant 0 : affineint %0 = "foo"(%c0) : (affineint) -> affineint for %i0 = 1 to 7 { %1 = "foo"(%i0) : (affineint) -> affineint %2 = affine_apply #map0(%i0) %3 = "bar"(%2) : (affineint) -> affineint } %4 = affine_apply #map0(%c8) %5 = "bar"(%4) : (affineint) -> affineint return } 2) DMA overlap: shift dma.wait and compute by one. Input for %i = 0 to 7 { %pingpong = affine_apply (d0) -> (d0 mod 2) (%i) "dma.enqueue"(%pingpong) : (affineint) -> affineint %pongping = affine_apply (d0) -> (d0 mod 2) (%i) "dma.wait"(%pongping) : (affineint) -> affineint "compute1"(%pongping) : (affineint) -> affineint } Output #map0 = (d0) -> (d0 mod 2) #map1 = (d0) -> (d0 - 1) #map2 = ()[s0] -> (s0 + 7) mlfunc @loop_nest_dma() { %c8 = constant 8 : affineint %c0 = constant 0 : affineint %0 = affine_apply #map0(%c0) %1 = "dma.enqueue"(%0) : (affineint) -> affineint for %i0 = 1 to 7 { %2 = affine_apply #map0(%i0) %3 = "dma.enqueue"(%2) : (affineint) -> affineint %4 = affine_apply #map1(%i0) %5 = affine_apply #map0(%4) %6 = "dma.wait"(%5) : (affineint) -> affineint %7 = "compute1"(%5) : (affineint) -> affineint } %8 = affine_apply #map1(%c8) %9 = affine_apply #map0(%8) %10 = "dma.wait"(%9) : (affineint) -> affineint %11 = "compute1"(%9) : (affineint) -> affineint return } 3) With arbitrary affine bound maps: Shift last two statements by two. Input: for %i = %N to ()[s0] -> (s0 + 7)()[%N] { %y = "foo"(%i) : (affineint) -> affineint %x = "bar"(%i) : (affineint) -> affineint %z = "foo_bar"(%i) : (affineint) -> (affineint) "bar_foo"(%i) : (affineint) -> (affineint) } Output #map0 = ()[s0] -> (s0 + 1) #map1 = ()[s0] -> (s0 + 2) #map2 = ()[s0] -> (s0 + 7) #map3 = (d0) -> (d0 - 2) #map4 = ()[s0] -> (s0 + 8) #map5 = ()[s0] -> (s0 + 9) for %i0 = %arg0 to #map0()[%arg0] { %0 = "foo"(%i0) : (affineint) -> affineint %1 = "bar"(%i0) : (affineint) -> affineint } for %i1 = #map1()[%arg0] to #map2()[%arg0] { %2 = "foo"(%i1) : (affineint) -> affineint %3 = "bar"(%i1) : (affineint) -> affineint %4 = affine_apply #map3(%i1) %5 = "foo_bar"(%4) : (affineint) -> affineint %6 = "bar_foo"(%4) : (affineint) -> affineint } for %i2 = #map4()[%arg0] to #map5()[%arg0] { %7 = affine_apply #map3(%i2) %8 = "foo_bar"(%7) : (affineint) -> affineint %9 = "bar_foo"(%7) : (affineint) -> affineint } 4) Shift one by zero, second by one, third by two for %i = 0 to 7 { %y = "foo"(%i) : (affineint) -> affineint %x = "bar"(%i) : (affineint) -> affineint %z = "foobar"(%i) : (affineint) -> affineint } #map0 = (d0) -> (d0 - 1) #map1 = (d0) -> (d0 - 2) #map2 = ()[s0] -> (s0 + 7) %c9 = constant 9 : affineint %c8 = constant 8 : affineint %c1 = constant 1 : affineint %c0 = constant 0 : affineint %0 = "foo"(%c0) : (affineint) -> affineint %1 = "foo"(%c1) : (affineint) -> affineint %2 = affine_apply #map0(%c1) %3 = "bar"(%2) : (affineint) -> affineint for %i0 = 2 to 7 { %4 = "foo"(%i0) : (affineint) -> affineint %5 = affine_apply #map0(%i0) %6 = "bar"(%5) : (affineint) -> affineint %7 = affine_apply #map1(%i0) %8 = "foobar"(%7) : (affineint) -> affineint } %9 = affine_apply #map0(%c8) %10 = "bar"(%9) : (affineint) -> affineint %11 = affine_apply #map1(%c8) %12 = "foobar"(%11) : (affineint) -> affineint %13 = affine_apply #map1(%c9) %14 = "foobar"(%13) : (affineint) -> affineint 5) SSA dominance violated; no shifting if a shift is specified for the second statement. for %i = 0 to 7 { %x = "foo"(%i) : (affineint) -> affineint "bar"(%x) : (affineint) -> affineint } PiperOrigin-RevId: 214975731
* Add support for expected-warning and expected-note markers in mlir-opt -verifyChris Lattner2019-03-291-18/+65
| | | | | | | | | | | mode. We even diagnose mistakes nicely (aside from the a/an vowel confusion which isn't worth worrying about): test/IR/invalid.mlir split at line tensorflow/mlir#399:8:34: error: 'note' diagnostic emitted when expecting a 'error' %x = "bar"() : () -> i32 // expected-error {{operand defined here}} ^ PiperOrigin-RevId: 214773208
* Add MLIR (addf) -> MLIR HLO thin slice.Jacques Pienaar2019-03-292-4/+7
| | | | | | 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
* Add op registry for registering MLIR ops.Jacques Pienaar2019-03-293-41/+0
| | | | | | 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
* Implement support for constant folding operations and a simple constant foldingChris Lattner2019-03-291-1/+7
| | | | | | | | | | | | | | | | | | 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
* Switch from positional argument to explicit flags for mlir-translateJacques Pienaar2019-03-292-45/+43
| | | | | | This results in uniform behavior with mlir-opt. Exactly one transformation is allowed. PiperOrigin-RevId: 213493415
* Tool for translating from/to MLIR.Jacques Pienaar2019-03-292-0/+198
| | | | | | | | 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 PassResult and have passes return PassResult to indicate failure/success.Jacques Pienaar2019-03-291-1/+3
| | | | | | For FunctionPass's for passes that want to stop upon error encountered. PiperOrigin-RevId: 213058651
* Add location specifier to MLIR Functions, and:Chris Lattner2019-03-291-14/+1
| | | | | | | | | | | - 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
* Improve location reporting in the verifier for return instructions and otherChris Lattner2019-03-291-2/+7
| | | | | | | | | | | | | | | | | | | | | | | 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
* Teach RaiseControlFlow to handle IfOp's with partially infered shapes,Chris Lattner2019-03-291-1/+6
| | | | | | | | | | | | 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
* Several minor infra improvements:Chris Lattner2019-03-291-1/+12
| | | | | | | | | | | | | | | - 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
* Add GraphTraits and DOTGraphTraits for CFGFunction in debug builds.Jacques Pienaar2019-03-291-0/+8
| | | | | | 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
* Continue revising diagnostic handling to simplify and generalize it, and ↵Chris Lattner2019-03-291-107/+198
| | | | | | | | | | | | | | | | | | | improve related infra. - 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
* Affine expression analysis and simplification.Uday Bondhugula2019-03-291-0/+7
| | | | | | | | | | | | | | | | | | | | | | | Outside of IR/ - simplify a MutableAffineMap by flattening the affine expressions - add a simplify affine expression pass that uses this analysis - update the FlatAffineConstraints API (to be used in the next CL) In IR: - add isMultipleOf and getKnownGCD for AffineExpr, and make the in-IR simplication of simplifyMod simpler and more powerful. - rename the AffineExpr visitor methods to distinguish b/w visiting and walking, and to simplify API names based on context. The next CL will use some of these for the loop unrolling/unroll-jam to make the detection for the need of cleanup loop powerful/non-trivial. A future CL will finally move this simplification to FlatAffineConstraints to make it more powerful. For eg., currently, even if a mod expr appearing in a part of the expression tree can't be simplified, the whole thing won't be simplified. PiperOrigin-RevId: 211012256
* Introduce loop unroll jam transformation.Uday Bondhugula2019-03-291-1/+7
| | | | | | | | | | - for test purposes, the unroll-jam pass unroll jams the first outermost loop. While on this: - fix StmtVisitor to allow overriding of function to iterate walk over children of a stmt. PiperOrigin-RevId: 210644813
* First steps towards TF/XLA control flow lowering: functional if lowering.Chris Lattner2019-03-291-1/+24
| | | | | | | | | | - Implement support for the TensorFlow 'If' op, the first TF op definition. - Fill in some missing basic infra, including the ability to split a basic block, the ability to create a branch with operands, etc. - Implement basic lowering for some simple forms of If, where the condition is a zero-D bool tensor and when all the types line up. Future patches will generalize this. There is still much to be done here. I'd like to get some example graphs coming from the converter to play with to direct this work. PiperOrigin-RevId: 210198760
* Extend loop unrolling to unroll by a given factor; add builder for affineUday Bondhugula2019-03-291-11/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | apply op. - add builder for AffineApplyOp (first one for an operation that has non-zero operands) - add support for loop unrolling by a given factor; uses the affine apply op builder. While on this, change 'step' of ForStmt to be 'unsigned' instead of AffineConstantExpr *. Add setters for ForStmt lb, ub, step. Sample Input: // CHECK-LABEL: mlfunc @loop_nest_unroll_cleanup() { mlfunc @loop_nest_unroll_cleanup() { for %i = 1 to 100 { for %j = 0 to 17 { %x = "addi32"(%j, %j) : (affineint, affineint) -> i32 %y = "addi32"(%x, %x) : (i32, i32) -> i32 } } return } Output: $ mlir-opt -loop-unroll -unroll-factor=4 /tmp/single2.mlir #map0 = (d0) -> (d0 + 1) #map1 = (d0) -> (d0 + 2) #map2 = (d0) -> (d0 + 3) mlfunc @loop_nest_unroll_cleanup() { for %i0 = 1 to 100 { for %i1 = 0 to 17 step 4 { %0 = "addi32"(%i1, %i1) : (affineint, affineint) -> i32 %1 = "addi32"(%0, %0) : (i32, i32) -> i32 %2 = affine_apply #map0(%i1) %3 = "addi32"(%2, %2) : (affineint, affineint) -> i32 %4 = affine_apply #map1(%i1) %5 = "addi32"(%4, %4) : (affineint, affineint) -> i32 %6 = affine_apply #map2(%i1) %7 = "addi32"(%6, %6) : (affineint, affineint) -> i32 } for %i2 = 16 to 17 { %8 = "addi32"(%i2, %i2) : (affineint, affineint) -> i32 %9 = "addi32"(%8, %8) : (i32, i32) -> i32 } } return } PiperOrigin-RevId: 209676220
* Finish support for function attributes, and improve lots of things:Chris Lattner2019-03-291-27/+3
| | | | | | | | | | | | | | | | | | | | | | | - Have the parser rewrite forward references to their resolved values at the end of parsing. - Implement verifier support for detecting malformed function attrs. - Add efficient query for (in general, recursive) attributes to tell if they contain a function. As part of this, improve other general infrastructure: - Implement support for verifying OperationStmt's in ml functions, refactoring and generalizing support for operations in the verifier. - Refactor location handling code in mlir-opt to have the non-error expecting form of mlir-opt invocations to report error locations precisely. - Fix parser to detect verifier failures and report them through errorReporter instead of printing the error and crashing. This regresses the location info for verifier errors in the parser that were previously ascribed to the function. This will get resolved in future patches by adding support for function attributes, which we can use to manage location information. PiperOrigin-RevId: 209600980
* [mlir-opt] Enable defining which operations are defined at link time.Jacques Pienaar2019-03-292-5/+15
| | | | | | Previously mlir-opt had initializeMLIRContext function that added certain ops to the OperationSet of the context. But for different tests we'd want to register different ops. Make initializeMLIRContext an extern function so that the context initialization/set of ops to register can be determined at link time. This allows out-of-tree operations to easily expand the custom parsing/printing while still using mlir-opt. PiperOrigin-RevId: 209078315
* Move Pass.{h,cpp} from lib/IR/ to lib/Transforms/.Uday Bondhugula2019-03-291-1/+1
| | | | PiperOrigin-RevId: 208571437
* Loop unrolling pass updateUday Bondhugula2019-03-291-0/+6
| | | | | | | | | | | | - fix/complete forStmt cloning for unrolling to work for outer loops - create IV const's only when needed - test outer loop unrolling by creating a short trip count unroll pass for loops with trip counts <= <parameter> - add unrolling test cases for multiple op results, outer loop unrolling - fix/clean up StmtWalker class while on this - switch unroll loop iterator values from i32 to affineint PiperOrigin-RevId: 207645967
* Continue wiring up diagnostic reporting infrastructure, still WIP.Chris Lattner2019-03-291-4/+31
| | | | | | | | | | | | - Implement a diagnostic hook in one of the paths in mlir-opt which captures and reports the diagnostics nicely. - Have the parser capture simple location information from the parser indicating where each op came from in the source .mlir file. - Add a verifyDominance() method to MLFuncVerifier to demo this, resolving b/112086163 - Add some PrettyStackTrace handlers to make crashes in the testsuite easier to track down. PiperOrigin-RevId: 207488548
* Internal changeMLIR Team2019-03-291-2/+2
| | | | PiperOrigin-RevId: 206652744
* Change mlir-opt.cpp to take a list of passes to run, simplifying the driverChris Lattner2019-03-291-28/+28
| | | | | | | code. Change printing of affine map's to not print a space between the dim and symbol list. PiperOrigin-RevId: 206505419
* Prepare for implementation of TensorFlow passes:Chris Lattner2019-03-291-7/+32
| | | | | | | | | | - Sketch out a TensorFlow/IR directory that will hold op definitions and common TF support logic. We will eventually have TensorFlow/TF2HLO, TensorFlow/Grappler, TensorFlow/TFLite, etc. - Add sketches of a Switch/Merge op definition, including some missing stuff like the TwoResults trait. Add a skeleton of a pass to raise this form. - Beef up the Pass/FunctionPass definitions slightly, moving the common code out of LoopUnroll.cpp into a new IR/Pass.cpp file. - Switch ConvertToCFG.cpp to be a ModulePass. - Allow _ to start bare identifiers, since this is important for TF attributes. PiperOrigin-RevId: 206502517
* Sketch out loop unrolling transformation.Uday Bondhugula2019-03-291-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Implement a full loop unroll for innermost loops. - Use it to implement a pass that unroll all the innermost loops of all mlfunction's in a module. ForStmt's parsed currently have constant trip counts (and constant loop bounds). - Implement StmtVisitor based (Visitor pattern) Loop IVs aren't currently parsed and represented as SSA values. Replacing uses of loop IVs in unrolled bodies is thus a TODO. Class comments are sparse at some places - will add them after one round of comments. A cmd-line flag triggers this for now. Original: mlfunc @loops() { for x = 1 to 100 step 2 { for x = 1 to 4 { "Const"(){value: 1} : () -> () } } return } After unrolling: mlfunc @loops() { for x = 1 to 100 step 2 { "Const"(){value: 1} : () -> () "Const"(){value: 1} : () -> () "Const"(){value: 1} : () -> () "Const"(){value: 1} : () -> () } return } PiperOrigin-RevId: 205933235
* Scaffolding for convertToCFG pass that replaces all instances of ML ↵Tatiana Shpeisman2019-03-291-1/+11
| | | | | | functions with equivalent CFG functions. Traverses module MLIR, generates CFG functions (empty for now) and removes ML functions. Adds Transforms library and tests. PiperOrigin-RevId: 205848367
* [mlir] Add basic block argumentsJames Molloy2019-03-291-1/+1
| | | | | | | | This patch adds support for basic block arguments including parsing and printing. In doing so noticed that `ssa-id-and-type` is undefined in the MLIR spec; suggested an implementation in the spec doc. PiperOrigin-RevId: 205593369
* Expand check-parser-errors to match multiple errrors per line.Jacques Pienaar2019-03-291-65/+65
| | | | | | | * check-parser-errors can match multiple errors per line; * Add offset notation to expected-error; PiperOrigin-RevId: 203625348
* Add default error reporter for parser.Jacques Pienaar2019-03-291-27/+23
| | | | | | Add a default error reporter for the parser that uses the SourceManager to print the error. Also and OptResult enum (mirroring ParseResult) to make the behavior self-documenting. PiperOrigin-RevId: 203173647
* Report parsing error check failures wrt file being parsed.Jacques Pienaar2019-03-291-12/+58
| | | | | | | | For checking parse errors, the input file is split and failures reported per memory buffer. Simply reporting the errors loses the mapping back to the original file. Change the reporting to instead relate the error reported back to the original file. Use SourceMgr's PrintMessage consistently for errors and relates back to file being parsed. PiperOrigin-RevId: 202136152
* Change error verification of parser error checking.Jacques Pienaar2019-03-291-11/+61
| | | | | | Change from using FileCheck to directly verifying the message (simple substring checking) and line number of the error. PiperOrigin-RevId: 201955181
* Change Lexer and Parser to take diagnostic reporter function.Jacques Pienaar2019-03-291-2/+7
| | | | | | Add diagnostic reporter function to lexer/parser and use that from mlir-opt to report errors instead of having the lexer/parser print the errors. PiperOrigin-RevId: 201892004
* Add negative parsing tests using mlir-opt.Jacques Pienaar2019-03-291-17/+40
| | | | | | | | Add parsing tests with errors. Follows direct path of splitting file into test groups (using a marker) and parsing each section individually. The expected errors are checked using FileCheck and parser error does not result in terminating parsing the rest of the file if check-parser-error. This is an interim approach until refactoring lexer/parser. PiperOrigin-RevId: 201867941
* Introduce IR support for MLIRContext, primitive types, function types, andChris Lattner2019-03-291-1/+4
| | | | | | | | | vector types. tensors and memref types are still TODO, and would be a good starter project for someone. PiperOrigin-RevId: 201782748
* Implement enough of a lexer and parser for MLIR to parse extfunc's withoutChris Lattner2019-03-291-5/+21
| | | | | | arguments. PiperOrigin-RevId: 201706570
* Continue sketching out basic infrastructure, including an input and outputChris Lattner2019-03-291-6/+36
| | | | | | | filename, and printing of trivial stuff. There is no parser yet, so the input file is ignored. PiperOrigin-RevId: 201596916
OpenPOWER on IntegriCloud