Commit Graph

498 Commits

Author SHA1 Message Date
Chris Lattner 721a30d6a0 Tidy up the replaceOp hooks in PatternMatch, generalizing them to support any
number of result ops.  Among other things, this results in shorter names

PiperOrigin-RevId: 222685039
2019-03-29 14:09:28 -07:00
Chris Lattner 1427d0f01b Minimal patch to allow patterns to rewrite multi-result instructions, related to b/119877155
PiperOrigin-RevId: 222597798
2019-03-29 14:09:14 -07:00
Alex Zinenko 68e9721aa8 Rename Deaffinator to LowerAffineApply and patch it.
Several things were suggested in post-submission reviews.  In particular, use
pointers in function interfaces instead of references (still use references
internally).  Clarify the behavior of the pass in presence of MLFunctions.

PiperOrigin-RevId: 222556851
2019-03-29 14:08:59 -07:00
Nicolas Vasilache 63bc6d2f6a [MLIR] Fix opt build
PiperOrigin-RevId: 222491353
2019-03-29 14:08:45 -07:00
Nicolas Vasilache a5782f0d40 [MLIR][MaterializeVectors] Add a MaterializeVector pass via unrolling.
This CL adds an MLIR-MLIR pass which materializes super-vectors to
hardware-dependent sized vectors.

While the physical vector size is target-dependent, the pass is written in
a target-independent way: the target vector size is specified as a parameter
to the pass. This pass is thus a partial lowering that opens the "greybox"
that is the super-vector abstraction.

This first CL adds a first materilization pass iterates over vector_transfer_write operations and:
1. computes the program slice including the current vector_transfer_write;
2. computes the multi-dimensional ratio of super-vector shape to hardware
vector shape;
3. for each possible multi-dimensional value within the bounds of ratio, a new slice is
instantiated (i.e. cloned and rewritten) so that all operations in this instance operate on
the hardware vector type.

As a simple example, given:
```mlir
mlfunc @vector_add_2d(%M : index, %N : index) -> memref<?x?xf32> {
  %A = alloc (%M, %N) : memref<?x?xf32>
  %B = alloc (%M, %N) : memref<?x?xf32>
  %C = alloc (%M, %N) : memref<?x?xf32>
  for %i0 = 0 to %M {
    for %i1 = 0 to %N {
      %a1 = load %A[%i0, %i1] : memref<?x?xf32>
      %b1 = load %B[%i0, %i1] : memref<?x?xf32>
      %s1 = addf %a1, %b1 : f32
      store %s1, %C[%i0, %i1] : memref<?x?xf32>
    }
  }
  return %C : memref<?x?xf32>
}
```

and the following options:
```
-vectorize -virtual-vector-size 32 --test-fastest-varying=0 -materialize-vectors -vector-size=8
```

materialization emits:
```mlir
#map0 = (d0, d1) -> (d0, d1)
#map1 = (d0, d1) -> (d0, d1 + 8)
#map2 = (d0, d1) -> (d0, d1 + 16)
#map3 = (d0, d1) -> (d0, d1 + 24)
mlfunc @vector_add_2d(%arg0 : index, %arg1 : index) -> memref<?x?xf32> {
  %0 = alloc(%arg0, %arg1) : memref<?x?xf32>
  %1 = alloc(%arg0, %arg1) : memref<?x?xf32>
  %2 = alloc(%arg0, %arg1) : memref<?x?xf32>
  for %i0 = 0 to %arg0 {
    for %i1 = 0 to %arg1 step 32 {
      %3 = affine_apply #map0(%i0, %i1)
      %4 = "vector_transfer_read"(%0, %3tensorflow/mlir#0, %3tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %5 = affine_apply #map1(%i0, %i1)
      %6 = "vector_transfer_read"(%0, %5tensorflow/mlir#0, %5tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %7 = affine_apply #map2(%i0, %i1)
      %8 = "vector_transfer_read"(%0, %7tensorflow/mlir#0, %7tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %9 = affine_apply #map3(%i0, %i1)
      %10 = "vector_transfer_read"(%0, %9tensorflow/mlir#0, %9tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %11 = affine_apply #map0(%i0, %i1)
      %12 = "vector_transfer_read"(%1, %11tensorflow/mlir#0, %11tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %13 = affine_apply #map1(%i0, %i1)
      %14 = "vector_transfer_read"(%1, %13tensorflow/mlir#0, %13tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %15 = affine_apply #map2(%i0, %i1)
      %16 = "vector_transfer_read"(%1, %15tensorflow/mlir#0, %15tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %17 = affine_apply #map3(%i0, %i1)
      %18 = "vector_transfer_read"(%1, %17tensorflow/mlir#0, %17tensorflow/mlir#1) : (memref<?x?xf32>, index, index) -> vector<8xf32>
      %19 = addf %4, %12 : vector<8xf32>
      %20 = addf %6, %14 : vector<8xf32>
      %21 = addf %8, %16 : vector<8xf32>
      %22 = addf %10, %18 : vector<8xf32>
      %23 = affine_apply #map0(%i0, %i1)
      "vector_transfer_write"(%19, %2, %23tensorflow/mlir#0, %23tensorflow/mlir#1) : (vector<8xf32>, memref<?x?xf32>, index, index) -> ()
      %24 = affine_apply #map1(%i0, %i1)
      "vector_transfer_write"(%20, %2, %24tensorflow/mlir#0, %24tensorflow/mlir#1) : (vector<8xf32>, memref<?x?xf32>, index, index) -> ()
      %25 = affine_apply #map2(%i0, %i1)
      "vector_transfer_write"(%21, %2, %25tensorflow/mlir#0, %25tensorflow/mlir#1) : (vector<8xf32>, memref<?x?xf32>, index, index) -> ()
      %26 = affine_apply #map3(%i0, %i1)
      "vector_transfer_write"(%22, %2, %26tensorflow/mlir#0, %26tensorflow/mlir#1) : (vector<8xf32>, memref<?x?xf32>, index, index) -> ()
    }
  }
  return %2 : memref<?x?xf32>
}
```

PiperOrigin-RevId: 222455351
2019-03-29 14:08:31 -07:00
Nicolas Vasilache 258dae5d73 [MLIR][Slicing] Apply cleanups
This CL applies a few last cleanups from a previous CL that have been
missed during the previous submit.

PiperOrigin-RevId: 222454774
2019-03-29 14:08:17 -07:00
Nicolas Vasilache 5c16564bca [MLIR][Slicing] Add utils for computing slices.
This CL adds tooling for computing slices as an independent CL.
The first consumer of this analysis will be super-vector materialization in a
followup CL.

In particular, this adds:
1. a getForwardStaticSlice function with documentation, example and a
standalone unit test;
2. a getBackwardStaticSlice function with documentation, example and a
standalone unit test;
3. a getStaticSlice function with documentation, example and a standalone unit
test;
4. a topologicalSort function that is exercised through the getStaticSlice
unit test.

The getXXXStaticSlice functions take an additional root (resp. terminators)
parameter which acts as a boundary that the transitive propagation algorithm
is not allowed to cross.

PiperOrigin-RevId: 222446208
2019-03-29 14:08:02 -07:00
MLIR Team cff7789a49 Clean up parse_headers in mlir
Not having self-contained headers in LLVM is a constant pain. Don't make the
same mistake in mlir. The only interesting change here is moving setSuccessor
to Instructions.cpp, which breaks the cycle between Instructions.h and
BasicBlock.h.

PiperOrigin-RevId: 222440816
2019-03-29 14:07:46 -07:00
Uday Bondhugula 2631b155a9 Fix bugs in DMA generation and FlatAffineConstraints; add more test
cases.

- fix bug in calculating index expressions for DMA buffers in certain cases
  (affected tiled loop nests); add more test cases for better coverage.
- introduce an additional optional argument to replaceAllMemRefUsesWith;
  additional operands to the index remap AffineMap can now be supplied by the
  client.
- FlatAffineConstraints::addBoundsForStmt - fix off by one upper bound,
  ::composeMap - fix position bug.
- Some clean up and more comments

PiperOrigin-RevId: 222434628
2019-03-29 14:07:31 -07:00
Alex Zinenko 615c41c788 Introduce Deaffinator pass.
This function pass replaces affine_apply operations in CFG functions with
sequences of primitive arithmetic instructions that form the affine map.

The actual replacement functionality is located in LoweringUtils as a
standalone function operating on an individual affine_apply operation and
inserting the result at the location of the original operation.  It is expected
to be useful for other, target-specific lowering passes that may start at
MLFunction level that Deaffinator does not support.

PiperOrigin-RevId: 222406692
2019-03-29 14:07:16 -07:00
Alex Zinenko ac6bfa6780 Lower scalar parts of CFG functions to LLVM IR
Initial restricted implementaiton of the MLIR to LLVM IR translation.
Introduce a new flow into the mlir-translate tool taking an MLIR module
containing CFG functions only and producing and LLVM IR module.  The MLIR
features supported by the translator are as follows:
- primitive and function types;
- integer constants;
- cfg and ext functions with 0 or 1 return values;
- calls to these functions;
- basic block conversion translation of arguments to phi nodes;
- conversion between arguments of the first basic block and function arguments;
- (conditional) branches;
- integer addition and comparison operations.

Are NOT supported:
- vector and tensor types and operations on them;
- memrefs and operations on them;
- allocations;
- functions returning multiple values;
- LLVM Module triple and data layout (index type is hardcoded to i64).

Create a new MLIR library and place it under lib/Target/LLVMIR.  The "Target"
library group is similar to the one present in LLVM and is intended to contain
all future public MLIR translation targets.

The general flow of MLIR to LLVM IR convresion will include several lowering
and simplification passes on the MLIR itself in order to make the translation
as simple as possible.  In particular, ML functions should be transformed to
CFG functions by the recently introduced pass, operations on structured types
will be converted to sequences of operations on primitive types, complex
operations such as affine_apply will be converted into sequence of primitive
operations, primitive operations themselves may eventually be converted to an
LLVM dialect that uses LLVM-like operations.

Introduce the first translation test so that further changes make sure the
basic translation functionality is not broken.

PiperOrigin-RevId: 222400112
2019-03-29 14:07:01 -07:00
Alex Zinenko 6e1a050f7e Create the Support library.
This has been a long-standing TODO in the build system.  Now that we need to
share the non-inlined implementation of file utilities for translators, create
a separate library for support functionality.  Move Support/* headers to the
new library in the build system.

PiperOrigin-RevId: 222398880
2019-03-29 14:06:47 -07:00
Alex Zinenko 6c5317eafa Separate translators into "from MLIR" and "to MLIR".
Translations performed by mlir-translate only have MLIR on one end.
MLIR-to-MLIR conversions (including dialect changes) should be treated as
passes and run by mlir-opt.  Individual translations should not care about
reading or writing MLIR and should work on in-memory representation of MLIR
modules instead.  Split the TranslateFunction interface and the translate
registry into two parts: "from MLIR" and "to MLIR".

Update mlir-translate to handle both registries together by wrapping
translation functions into source-to-source convresions.  Remove MLIR parsing
and writing from individual translations and make them operate on Modules
instead.  This removes the need for individual translators to include
tools/mlir-translate/mlir-translate.h, which can now be safely removed.

Remove mlir-to-mlir translation that only existed as a registration example and
use mlir-opt instead for tests.

PiperOrigin-RevId: 222398707
2019-03-29 14:06:33 -07:00
Alex Zinenko b5756fdaa1 Factor out translation registry.
The mlir-translate tool is expected to discover individual translations at link
time.  These translations must register themselves and may need the utilities
that are currently defined in mlir-translate.cpp for their entry point
functions.  Since mlir-translate is linking against individual translations,
the translations cannot link against mlir-translate themselves.  Extract out
the utilities into a separate "Translation" library to avoid the potential
dependency cycle.  Individual translations link to that library to access
TranslateRegistration. The mlir-translate tool links to individual translations
and to the "Translation" library because it needs the utilities as well.

The main header of the new library is located in include/mlir/Translation.h to
make it easily accessible by translators.  The rationale for putting it to
include/mlir rather than to one of its subdirectories is that its purpose is
similar to that of include/mlir/Pass.h so it makes sense to put them at the
same level.

PiperOrigin-RevId: 222398617
2019-03-29 14:06:19 -07:00
Smit Hinsu 1967325244 Introduce TF WhileOp and lower it to MLIR CFG
Also, added iterators for VariadicResults class.

TESTED with unit tests

TODOs:
- Handle non-bool condition results (similar to the IfOp)
- Use PatternRewriter
PiperOrigin-RevId: 222340376
2019-03-29 14:06:04 -07:00
River Riddle 1cfe508316 Add verifier check for integer constants to check that the value can fit within the type bit width.
PiperOrigin-RevId: 222335526
2019-03-29 14:05:48 -07:00
River Riddle 58cd315a68 Remove unnecessary include from StandardOps.cpp.
PiperOrigin-RevId: 222316745
2019-03-29 14:05:34 -07:00
Uday Bondhugula b6c03917ad Remove allocations for memref's that become dead as a result of double
buffering in the auto DMA overlap pass.

This is done online in the pass.

PiperOrigin-RevId: 222313640
2019-03-29 14:05:19 -07:00
Lei Zhang 431f08ba7f Add iterators and size() helper method in ArrayAttr
PiperOrigin-RevId: 222312276
2019-03-29 14:05:05 -07:00
Alex Zinenko 43a8fffbe7 AffineExprVisitor: fix names of default visitation functions.
Existing default visitation function for dimension and symbols were called
"visitAffineDimExpr" and "visitAffineSymbolExpr".  However, generic CRTP-based
visit and walk methods were calling "visitDimExpr" and "visitSymbolExpr",
respectively, on derived classes.  This has not been discovered before because
all existing affine expression visitors (re)define functions for dimensions and
symbols.  Change the names of the default empty visitation functions to the
latter form.

PiperOrigin-RevId: 222312114
2019-03-29 14:04:49 -07:00
Feng Liu a9d3e5ee38 Adds ConstantFoldHook registry in MLIRContext
This reverts the previous method which needs to create a new dialect with the
constant fold hook from TensorFlow. This new method uses a function object in
dialect to store the constant fold hook. Once a hook is registered to the
dialect, this function object will be assigned when the dialect is added to the
MLIRContext.

For the operations which are not registered, a new method getRegisteredDialects
is added to the MLIRContext to query the dialects which matches their op name
prefixes.

PiperOrigin-RevId: 222310149
2019-03-29 14:04:34 -07:00
River Riddle 5041e13c96 Add functionality for erasing terminator successor operands and basic block arguments.
PiperOrigin-RevId: 222303233
2019-03-29 14:04:19 -07:00
Uday Bondhugula 0328217eb8 Automated rollback of changelist 221863955.
PiperOrigin-RevId: 222299120
2019-03-29 14:04:05 -07:00
Nicolas Vasilache 87d46aaf4b [MLIR][Vectorize] Refactor Vectorize use-def propagation.
This CL refactors a few things in Vectorize.cpp:
1. a clear distinction is made between:
  a. the LoadOp are the roots of vectorization and must be vectorized
  eagerly and propagate their value; and
  b. the StoreOp which are the terminals of vectorization and must be
  vectorized late (i.e. they do not produce values that need to be
  propagated).
2. the StoreOp must be vectorized late because in general it can store a value
that is not reachable from the subset of loads defined in the
current pattern. One trivial such case is storing a constant defined at the
top-level of the MLFunction and that needs to be turned into a splat.
3. a description of the algorithm is given;
4. the implementation matches the algorithm;
5. the last example is made parametric, in practice it will fully rely on the
implementation of vector_transfer_read/write which will handle boundary
conditions and padding. This will happen by lowering to a lower-level
abstraction either:
  a. directly in MLIR (whether DMA or just loops or any async tasks in the
     future) (whiteboxing);
  b. in LLO/LLVM-IR/whatever blackbox library call/ search + swizzle inventor
  one may want to use;
  c. a partial mix of a. and b. (grey-boxing)
5. minor cleanups are applied;
6. mistakenly disabled unit tests are re-enabled (oopsie).

With this CL, this MLIR snippet:
```
mlfunc @vector_add_2d(%M : index, %N : index) -> memref<?x?xf32> {
  %A = alloc (%M, %N) : memref<?x?xf32>
  %B = alloc (%M, %N) : memref<?x?xf32>
  %C = alloc (%M, %N) : memref<?x?xf32>
  %f1 = constant 1.0 : f32
  %f2 = constant 2.0 : f32
  for %i0 = 0 to %M {
    for %i1 = 0 to %N {
      // non-scoped %f1
      store %f1, %A[%i0, %i1] : memref<?x?xf32>
    }
  }
  for %i4 = 0 to %M {
    for %i5 = 0 to %N {
      %a5 = load %A[%i4, %i5] : memref<?x?xf32>
      %b5 = load %B[%i4, %i5] : memref<?x?xf32>
      %s5 = addf %a5, %b5 : f32
      // non-scoped %f1
      %s6 = addf %s5, %f1 : f32
      store %s6, %C[%i4, %i5] : memref<?x?xf32>
    }
  }
  return %C : memref<?x?xf32>
}
```

vectorized with these arguments:
```
-vectorize -virtual-vector-size 256 --test-fastest-varying=0
```

vectorization produces this standard innermost-loop vectorized code:
```
mlfunc @vector_add_2d(%arg0 : index, %arg1 : index) -> memref<?x?xf32> {
  %0 = alloc(%arg0, %arg1) : memref<?x?xf32>
  %1 = alloc(%arg0, %arg1) : memref<?x?xf32>
  %2 = alloc(%arg0, %arg1) : memref<?x?xf32>
  %cst = constant 1.000000e+00 : f32
  %cst_0 = constant 2.000000e+00 : f32
  for %i0 = 0 to %arg0 {
    for %i1 = 0 to %arg1 step 256 {
      %cst_1 = constant splat<vector<256xf32>, 1.000000e+00> : vector<256xf32>
      "vector_transfer_write"(%cst_1, %0, %i0, %i1) : (vector<256xf32>, memref<?x?xf32>, index, index) -> ()
    }
  }
  for %i2 = 0 to %arg0 {
    for %i3 = 0 to %arg1 step 256 {
      %3 = "vector_transfer_read"(%0, %i2, %i3) : (memref<?x?xf32>, index, index) -> vector<256xf32>
      %4 = "vector_transfer_read"(%1, %i2, %i3) : (memref<?x?xf32>, index, index) -> vector<256xf32>
      %5 = addf %3, %4 : vector<256xf32>
      %cst_2 = constant splat<vector<256xf32>, 1.000000e+00> : vector<256xf32>
      %6 = addf %5, %cst_2 : vector<256xf32>
      "vector_transfer_write"(%6, %2, %i2, %i3) : (vector<256xf32>, memref<?x?xf32>, index, index) -> ()
    }
  }
  return %2 : memref<?x?xf32>
}
```

Of course, much more intricate n-D imperfectly-nested patterns can be emitted too in a fully declarative fashion, but this is enough for now.

PiperOrigin-RevId: 222280209
2019-03-29 14:03:50 -07:00
Lei Zhang 19573e2939 Convert TF::Conv2D into TFL::Conv2D
Added TF::Conv2D op and TFL::Conv2D op, and converted TF::Conv2D to
TFL::Conv2D, which need to address the operand numberr mismatch
and attribute conversion.
PiperOrigin-RevId: 222277554
2019-03-29 14:03:35 -07:00
Alex Zinenko f986d5920b ConvertToCFG: handle loop 1D affine loop bounds.
In the general case, loop bounds can be expressed as affine maps of the outer
loop iterators and function arguments.  Relax the check for loop bounds to be
known integer constants and also accept one-dimensional affine bounds in
ConvertToCFG ForStmt lowering.  Emit affine_apply operations for both the upper
and the lower bound.  The semantics of MLFunctions guarantees that both bounds
can be computed before the loop starts iterating.  Constant bounds are merely a
short-hand notation for zero-dimensional affine maps and get supported
transparently.

Multidimensional affine bounds are not yet supported because the target IR
dialect lacks min/max operations necessary to implement the corresponding
semantics.

PiperOrigin-RevId: 222275801
2019-03-29 14:03:20 -07:00
River Riddle 85f86ca203 Add support for getting the operand number from an IROperandImpl(InstOperand, BasicBlockOperand, StmtOperand).
PiperOrigin-RevId: 222274598
2019-03-29 14:03:05 -07:00
Jacques Pienaar d0590caa90 Add op stats pass to mlir-opt.
op-stats pass currently returns the number of occurrences of different operations in a Module. Useful for verifying transformation properties (e.g., 3 ops of specific dialect, 0 of another), but probably not useful outside of that so keeping it local to mlir-opt. This does not consider op attributes when counting.

PiperOrigin-RevId: 222259727
2019-03-29 14:02:46 -07:00
River Riddle d63ab4b47a Add support for Operation::moveBefore(Operation *).
PiperOrigin-RevId: 222252521
2019-03-29 14:02:31 -07:00
Nicolas Vasilache 89d9913a20 [MLIR][VectorAnalysis] Add a VectorAnalysis and standalone tests
This CL adds some vector support in prevision of the upcoming vector
materialization pass. In particular this CL adds 2 functions to:
1. compute the multiplicity of a subvector shape in a supervector shape;
2. help match operations on strict super-vectors. This is defined for a given
subvector shape as an operation that manipulates a vector type that is an
integral multiple of the subtype, with multiplicity at least 2.

This CL also adds a TestUtil pass where we can dump arbitrary testing of
functions and analysis that operate at a much smaller granularity than a pass
(e.g. an analysis for which it is convenient to write a bit of artificial MLIR
and write some custom test). This is in order to keep using Filecheck for
things that essentially look and feel like C++ unit tests.

PiperOrigin-RevId: 222250910
2019-03-29 14:02:17 -07:00
Jacques Pienaar f10f48ee63 Convert MLIR DiagnosticKind to LLVM DiagKind when emitting diagnostic via mlir-opt.
PiperOrigin-RevId: 222147297
2019-03-29 14:02:02 -07:00
River Riddle 1c95796372 Update 'return' statement syntax in LangRef to reflect the actual parsing syntax.
PiperOrigin-RevId: 222107722
2019-03-29 14:01:48 -07:00
River Riddle 21c30304a0 Fix the implementation of PatternRewriter::createChecked. The current implementation has bit rotted and won't compile. This cl updates the implementation to be similar to (CFGFuncBuilder/MLFuncBuilder)::createChecked.
PiperOrigin-RevId: 222014317
2019-03-29 14:01:34 -07:00
Chris Lattner a603b2f5b2 Import the "MLIR: The case for a simplified polyhedral form" proposal doc from
google docs into the codebase as a rationale doc, since this is an important
aspect of our design.

PiperOrigin-RevId: 221957444
2019-03-29 14:01:19 -07:00
Jacques Pienaar 64c6d3946c Change pretty printing of constant so that the attributes precede the value.
This does create an inconsistency between the print formats (e.g., attributes are normally before operands) but fixes an invalid parsing & keeps constant uniform wrt itself (function or int attributes have type at same place). And specifying the specific type for a int/float attribute might get revised shortly.

Also add test to verify that output printed can be parsed again.

PiperOrigin-RevId: 221923893
2019-03-29 14:01:05 -07:00
Uday Bondhugula fff1efbaf5 Updates to transformation/analysis passes/utilities. Update DMA generation pass
and getMemRefRegion() to work with specified loop depths; add support for
outgoing DMAs, store op's.

- add support for getMemRefRegion symbolic in outer loops - hence support for
  DMAs symbolic in outer surrounding loops.

- add DMA generation support for outgoing DMAs (store op's to lower memory
  space); extend getMemoryRegion to store op's. -memref-bound-check now works
  with store op's as well.

- fix dma-generate (references to the old memref in the dma_start op were also
  being replaced with the new buffer); we need replace all memref uses to work
  only on a subset of the uses - add a new optional argument for
  replaceAllMemRefUsesWith. update replaceAllMemRefUsesWith to take an optional
  'operation' argument to serve as a filter - if provided, only those uses that
  are dominated by the filter are replaced.

- Add missing print for attributes for dma_start, dma_wait op's.

- update the FlatAffineConstraints API

PiperOrigin-RevId: 221889223
2019-03-29 14:00:51 -07:00
Uday Bondhugula 6b52ac3aa6 Mark AllocOp as being free of side effects
PiperOrigin-RevId: 221863955
2019-03-29 14:00:37 -07:00
Jacques Pienaar 8c903a3c9d Update LangRef to reflect int/flaot attribute specification changes.
PiperOrigin-RevId: 221802835
2019-03-29 14:00:23 -07:00
River Riddle d34fcce2a7 [MLIR] Rename OperationInst to Instruction.
PiperOrigin-RevId: 221795407
2019-03-29 14:00:09 -07:00
Smit Hinsu 2213afa784 Implement IfOp verification
This would also make the CallOp and ExtractElementOp invocations from eliminateIfOp function always valid and removes the need for error handling.

Also, verify TensorFlowOp trait.

PiperOrigin-RevId: 221737192
2019-03-29 13:59:52 -07:00
River Riddle 8b6bc09f48 Merge OperationInst functionality into Instruction.
We do some limited renaming here but define an alias for OperationInst so that a follow up cl can solely perform the large scale renaming.

PiperOrigin-RevId: 221726963
2019-03-29 13:59:37 -07:00
Jacques Pienaar 711047c0cd Add Type to int/float attributes.
* Optionally attach the type of integer and floating point attributes to the attributes, this allows restricting a int/float to specific width.
  - Currently this allows suffixing int/float constant with type [this might be revised in future].
  - Default to i64 and f32 if not specified.
* For index types the APInt width used is 64.
* Change callers to request a specific attribute type.
* Store iN type with APInt of width N.
* This change does not handle the folding of constants of different types (e.g., doing int type promotions to support constant folding i3 and i32), and instead restricts the constant folding to only operate on the same types.

PiperOrigin-RevId: 221722699
2019-03-29 13:59:23 -07:00
River Riddle c7df0651d3 [MLIR] Merge terminator and uses into BasicBlock operations list handling.
PiperOrigin-RevId: 221700132
2019-03-29 13:59:10 -07:00
River Riddle 503caf0722 Replace TerminatorInst with builtin terminator operations.
Note: Terminators will be merged into the operations list in a follow up patch.
PiperOrigin-RevId: 221670037
2019-03-29 13:58:55 -07:00
River Riddle de828dd259 Fix variables only used in assertions.
PiperOrigin-RevId: 221660580
2019-03-29 13:58:40 -07:00
River Riddle 1807ba3c2c Add functionality for parsing/managing operation terminator successors.
Follow up patches will work to remove TerminatorInst.

PiperOrigin-RevId: 221640621
2019-03-29 13:58:27 -07:00
Tatiana Shpeisman cfb49f2584 Fix hasStaticShape() method on vectors and tensors to work correctly for unranked tensors and remove getShape() method for unranked tensors.
Unranked tensors used to return an empty list of dimensions as their shape. This is confusing since an empty list of dimensions is also returned for 0-D tensors. In particular, hasStaticShape() method used to check if any of the dimensions are -1, which held for unranked tensors even though they don't have static shape.

PiperOrigin-RevId: 221571138
2019-03-29 13:58:13 -07:00
Alex Zinenko d030433443 ConvertToCFG: properly remap nested function attributes.
Array attributes can nested and function attributes can appear anywhere at that
level.  They should be remapped to point to the generated CFGFunction after
ML-to-CFG conversion, similarly to plain function attributes.  Extract the
nested attribute remapping functionality from the Parser to Utils.  Extract out
the remapping function for individual Functions from the module remapping
function.  Use these new functions in the ML-to-CFG conversion pass and in the
parser.

PiperOrigin-RevId: 221510997
2019-03-29 13:57:58 -07:00
Alex Zinenko cb40633969 Move definitions of lopoUnroll* functions to LoopUtils.cpp.
These functions are declared in Transforms/LoopUtils.h (included to the
Transforms/Utils library) but were defined in the loop unrolling pass in
Transforms/LoopUnroll.cpp.  As a result, targets depending only on
TransformUtils library but not on Transforms could get link errors.  Move the
definitions to Transforms/Utils/LoopUtils.cpp where they should actually live.
This does not modify any code.

PiperOrigin-RevId: 221508882
2019-03-29 13:57:44 -07:00
Chris Lattner a30f7ec74f Fix some minor typos pointed out by rxwei
PiperOrigin-RevId: 221474217
2019-03-29 13:57:31 -07:00