Commit Graph

147 Commits

Author SHA1 Message Date
Sean Silva
c31ee83abb Add Builder::get{I32,I64}TensorAttr.
Builder::get{I32,I64}VectorAttr are actually of limited applicability since
vector types can't have zero elements, whereas many uses of this kind of
attribute (such as dimension lists for "transpose"-like and other tensor
ops) often can result in empty lists.

Differential Revision: https://reviews.llvm.org/D76403
2020-03-19 11:37:59 -07:00
Sean Silva
94f848d7b5 Add Builder::getI64VectorAttr.
This matches Builder::getI32VectorAttr.

Differential Revision: https://reviews.llvm.org/D75883
2020-03-13 15:03:22 -07:00
River Riddle
907403f342 [mlir] Add a new ConstantLike trait to better identify operations that represent a "constant".
The current mechanism for identifying is a bit hacky and extremely adhoc, i.e. we explicit check 1-result, 0-operand, no side-effect, and always foldable and then assume that this is a constant. Adding a trait adds structure to this, and makes checking for a constant much more efficient as we can guarantee that all of these things have already been verified.

Differential Revision: https://reviews.llvm.org/D76020
2020-03-12 14:26:15 -07:00
Alexandre Ganea
5125803d34 [mlir] Silence error: call to constructor of 'llvm::APInt' is ambiguous
I was getting this error when using Clang 9.0.1 for compiling.

F:\llvm-project\mlir\lib\IR\Builders.cpp(119,27): error: call to constructor of 'llvm::APInt' is ambiguous
                          APInt(32, value, /*isSigned=*/false));
                          ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
F:\llvm-project\llvm\include\llvm/ADT/APInt.h(277,3): note: candidate constructor
  APInt(unsigned numBits, uint64_t val, bool isSigned = false)
  ^
F:\llvm-project\llvm\include\llvm/ADT/APInt.h(304,3): note: candidate constructor
  APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
  ^
1 error generated.
2020-02-21 10:06:04 -05:00
Lei Zhang
35b685270b [mlir] Add a signedness semantics bit to IntegerType
Thus far IntegerType has been signless: a value of IntegerType does
not have a sign intrinsically and it's up to the specific operation
to decide how to interpret those bits. For example, std.addi does
two's complement arithmetic, and std.divis/std.diviu treats the first
bit as a sign.

This design choice was made some time ago when we did't have lots
of dialects and dialects were more rigid. Today we have much more
extensible infrastructure and different dialect may want different
modelling over integer signedness. So while we can say we want
signless integers in the standard dialect, we cannot dictate for
others. Requiring each dialect to model the signedness semantics
with another set of custom types is duplicating the functionality
everywhere, considering the fundamental role integer types play.

This CL extends the IntegerType with a signedness semantics bit.
This gives each dialect an option to opt in signedness semantics
if that's what they want and helps code sharing. The parser is
modified to recognize `si[1-9][0-9]*` and `ui[1-9][0-9]*` as
signed and unsigned integer types, respectively, leaving the
original `i[1-9][0-9]*` to continue to mean no indication over
signedness semantics. All existing dialects are not affected (yet)
as this is a feature to opt in.

More discussions can be found at:

https://groups.google.com/a/tensorflow.org/d/msg/mlir/XmkV8HOPWpo/7O4X0Nb_AQAJ

Differential Revision: https://reviews.llvm.org/D72533
2020-02-21 09:16:54 -05:00
Mehdi Amini
308571074c Mass update the MLIR license header to mention "Part of the LLVM project"
This is an artifact from merging MLIR into LLVM, the file headers are
now aligned with the rest of the project.
2020-01-26 03:58:30 +00:00
Lorenzo Chelini
81e7922e83 [mlir] m_Constant()
Summary: Introduce m_Constant() which allows matching a constant operation without forcing the user also to capture the attribute value.

Differential Revision: https://reviews.llvm.org/D72397
2020-01-13 17:22:01 +01:00
River Riddle
2bdf33cc4c [mlir] NFC: Remove Value::operator* and Value::operator-> now that Value is properly value-typed.
Summary: These were temporary methods used to simplify the transition.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D72548
2020-01-11 08:54:39 -08:00
River Riddle
e62a69561f NFC: Replace ValuePtr with Value and remove it now that Value is value-typed.
ValuePtr was a temporary typedef during the transition to a value-typed Value.

PiperOrigin-RevId: 286945714
2019-12-23 16:36:53 -08:00
Mehdi Amini
56222a0694 Adjust License.txt file to use the LLVM license
PiperOrigin-RevId: 286906740
2019-12-23 15:33:37 -08:00
River Riddle
35807bc4c5 NFC: Introduce new ValuePtr/ValueRef typedefs to simplify the transition to Value being value-typed.
This is an initial step to refactoring the representation of OpResult as proposed in: https://groups.google.com/a/tensorflow.org/g/mlir/c/XXzzKhqqF_0/m/v6bKb08WCgAJ

This change will make it much simpler to incrementally transition all of the existing code to use value-typed semantics.

PiperOrigin-RevId: 286844725
2019-12-22 22:00:23 -08:00
River Riddle
b030e4a4ec Try to fold operations in DialectConversion when trying to legalize.
This change allows for DialectConversion to attempt folding as a mechanism to legalize illegal operations. This also expands folding support in OpBuilder::createOrFold to generate new constants when folding, and also enables it to work in the context of a PatternRewriter.

PiperOrigin-RevId: 285448440
2019-12-13 16:47:26 -08:00
River Riddle
851a8516d3 Make OpBuilder::insert virtual instead of OpBuilder::createOperation.
It is sometimes useful to create operations separately from the builder before insertion as it may be easier to erase them in isolation if necessary. One example use case for this is folding, as we will only want to insert newly generated constant operations on success. This has the added benefit of fixing some silent PatternRewriter failures related to cloning, as the OpBuilder 'clone' methods don't call createOperation.

PiperOrigin-RevId: 285086242
2019-12-11 16:26:45 -08:00
Lei Zhang
0d22a3fdc8 NFC: Update std.subview op to use AttrSizedOperandSegments
This turns a few manually written helper methods into auto-generated ones.

PiperOrigin-RevId: 283339617
2019-12-02 07:52:00 -08:00
River Riddle
9b9c647cef Add support for nested symbol references.
This change allows for adding additional nested references to a SymbolRefAttr to allow for further resolving a symbol if that symbol also defines a SymbolTable. If a referenced symbol also defines a symbol table, a nested reference can be used to refer to a symbol within that table. Nested references are printed after the main reference in the following form:

  symbol-ref-attribute ::= symbol-ref-id (`::` symbol-ref-id)*

Example:

  module @reference {
    func @nested_reference()
  }

  my_reference_op @reference::@nested_reference

Given that SymbolRefAttr is now more general, the existing functionality centered around a single reference is moved to a derived class FlatSymbolRefAttr. Followup commits will add support to lookups, rauw, etc. for scoped references.

PiperOrigin-RevId: 279860501
2019-11-11 18:18:31 -08:00
Kazuaki Ishizaki
8bfedb3ca5 Fix minor spelling tweaks (NFC)
Closes tensorflow/mlir#177

PiperOrigin-RevId: 275692653
2019-10-20 00:11:34 -07:00
River Riddle
2acc220f17 NFC: Remove trivial builder get methods.
These don't add any value, and some are even more restrictive than the respective static 'get' method.

PiperOrigin-RevId: 275391240
2019-10-17 20:08:34 -07:00
Jing Pu
38e7226606 Add convenience methods to create i8 and i16 attributes in Builder.
PiperOrigin-RevId: 269120226
2019-09-14 17:02:54 -07:00
Smit Hinsu
da646505c5 Support bf16 in Builder::getZeroAttr
PiperOrigin-RevId: 266863802
2019-09-02 23:44:06 -07:00
Nicolas Vasilache
f55ac5c076 Add support for LLVM lowering of binary ops on n-D vector types
This CL allows binary operations on n-D vector types to be lowered to LLVMIR by performing an (n-1)-D extractvalue, 1-D vector operation and an (n-1)-D insertvalue.

PiperOrigin-RevId: 264339118
2019-08-20 02:00:22 -07:00
Diego Caballero
c6a006d4c7 Fix verification of zero-dim memref in affine.load/affine.store/std.load/std.store
Verification complained when using zero-dimensional memrefs in
affine.load, affine.store, std.load and std.store. This PR extends
verification so that those memrefs can be used.

Closes tensorflow/mlir#58

COPYBARA_INTEGRATE_REVIEW=https://github.com/tensorflow/mlir/pull/58 from dcaballe:dcaballe/zero-dim 49bcdcd45c52c48beca776431328e5ce551dfa9e
PiperOrigin-RevId: 262164916
2019-08-07 10:31:49 -07:00
Nicolas Vasilache
600c47e77b Add a generic Linalg op
This CL introduces a linalg.generic op to represent generic tensor contraction operations on views.

A linalg.generic operation requires a numbers of attributes that are sufficient to emit the computation in scalar form as well as compute the appropriate subviews to enable tiling and fusion.

These attributes are very similar to the attributes for existing operations such as linalg.matmul etc and existing operations can be implemented with the generic form.

In the future, most existing operations can be implemented using the generic form.

This CL starts by splitting out most of the functionality of the linalg::NInputsAndOutputs trait into a ViewTrait that queries the per-instance properties of the op. This allows using the attribute informations.

This exposes an ordering of verifiers issue where ViewTrait::verify uses attributes but the verifiers for those attributes have not been run. The desired behavior would be for the verifiers of the attributes specified in the builder to execute first but it is not the case atm. As a consequence, to emit proper error messages and avoid crashing, some of the
linalg.generic methods are defensive as such:
```
    unsigned getNumInputs() {
      // This is redundant with the `n_views` attribute verifier but ordering of verifiers
      // may exhibit cases where we crash instead of emitting an error message.
      if (!getAttr("n_views") || n_views().getValue().size() != 2)
        return 0;
```

In pretty-printed form, the specific attributes required for linalg.generic are factored out in an independent dictionary named "_". When parsing its content is flattened and the "_name" is dropped. This allows using aliasing for reducing boilerplate at each linalg.generic invocation while benefiting from the Tablegen'd verifier form for each named attribute in the dictionary.

For instance, implementing linalg.matmul in terms of linalg.generic resembles:

```
func @mac(%a: f32, %b: f32, %c: f32) -> f32 {
  %d = mulf %a, %b: f32
  %e = addf %c, %d: f32
  return %e: f32
}
#matmul_accesses = [
  (m, n, k) -> (m, k),
  (m, n, k) -> (k, n),
  (m, n, k) -> (m, n)
]
#matmul_trait = {
  doc = "C(m, n) += A(m, k) * B(k, n)",
  fun = @mac,
  indexing_maps = #matmul_accesses,
  library_call = "linalg_matmul",
  n_views = [2, 1],
  n_loop_types = [2, 1, 0]
}
```

And can be used in multiple places as:
```
  linalg.generic #matmul_trait %A, %B, %C [other-attributes] :
    !linalg.view<?x?xf32>, !linalg.view<?x?xf32>, !linalg.view<?x?xf32>
```

In the future it would be great to have a mechanism to alias / register a new
linalg.op as a pair of linalg.generic, #trait.

Also, note that with one could theoretically only specify the `doc` string and parse all the attributes from it.

PiperOrigin-RevId: 261338740
2019-08-02 09:53:41 -07:00
River Riddle
8e349a48b6 Remove the 'region' field from OpBuilder.
This field wasn't updated as the insertion point changed, making it potentially dangerous given the multi-level of MLIR(e.g. 'createBlock' would always insert the new block in 'region'). This also allows for building an OpBuilder with just a context.

PiperOrigin-RevId: 257829135
2019-07-12 17:42:41 -07:00
River Riddle
9dbef0bf96 Rename FunctionAttr to SymbolRefAttr.
This allows for the attribute to hold symbolic references to other operations than FuncOp. This also allows for removing the dependence on FuncOp from the base Builder.

PiperOrigin-RevId: 257650017
2019-07-12 08:43:42 -07:00
River Riddle
fec20e590f NFC: Rename Module to ModuleOp.
Module is a legacy name that only exists as a typedef of ModuleOp.

PiperOrigin-RevId: 257427248
2019-07-10 10:11:21 -07:00
River Riddle
6b6dc59f30 Update ModuleOp::create(...) to take a Location instead of a context.
This allows for giving a Module a more interesting location than 'Unknown'.

PiperOrigin-RevId: 257310117
2019-07-10 10:11:00 -07:00
River Riddle
8c44367891 NFC: Rename Function to FuncOp.
PiperOrigin-RevId: 257293379
2019-07-10 10:10:53 -07:00
River Riddle
206e55cc16 NFC: Refactor Module to be value typed.
As with Functions, Module will soon become an operation, which are value-typed. This eases the transition from Module to ModuleOp. A new class, OwningModuleRef is provided to allow for owning a reference to a Module, and will auto-delete the held module on destruction.

PiperOrigin-RevId: 256196193
2019-07-02 16:43:36 -07:00
River Riddle
54cd6a7e97 NFC: Refactor Function to be value typed.
Move the data members out of Function and into a new impl storage class 'FunctionStorage'. This allows for Function to become value typed, which will greatly simplify the transition of Function to FuncOp(given that FuncOp is also value typed).

PiperOrigin-RevId: 255983022
2019-07-01 11:39:00 -07:00
River Riddle
bda669beea Allow attaching a type to StringAttr.
Some dialects allow for string types, and this allows for reusing StringAttr for constants of these types.

PiperOrigin-RevId: 255413948
2019-06-27 09:13:44 -07:00
River Riddle
49162524d8 NFC: Uniformize the return of the LocationAttr 'get' methods to 'Location'.
PiperOrigin-RevId: 255078768
2019-06-25 16:57:56 -07:00
River Riddle
30bbd91056 Simplify usages of SplatElementsAttr now that it inherits from DenseElementsAttr.
PiperOrigin-RevId: 253910543
2019-06-19 23:07:34 -07:00
River Riddle
dee282c7da Replace usages of 'UniquedFilename' with 'Identifier' and remove it. Identifier already contains all of the necessary functionality/verification, so having a separate class for filenames is unnecessary.
PiperOrigin-RevId: 253855505
2019-06-19 23:07:05 -07:00
River Riddle
0cadec8ae6 Remove the ability to directly construct a DenseElementsAttr with a raw character buffer. This made assumptions about how DenseElementsAttr structured its internal storage, which may change in the future. To replace the existing use cases, a few utility methods have been added:
* 'get' methods that allow constructing from an ArrayRef of integer or floating point values.
* A 'reshape' method to allow for changing the shape without changing the underlying data.

PiperOrigin-RevId: 252067898
2019-06-09 16:23:34 -07:00
MLIR Team
f55f7dc769 Support FP16 in getZeroAttr.
PiperOrigin-RevId: 251783931
2019-06-09 16:20:47 -07:00
River Riddle
6f5f5a9178 Add new 'createOrFold' methods to FuncBuilder to immediately try to fold an operation after creating it. This can be used to remove operations that are likely to be trivially folded later. Note, these functions only fold operations if all of the folded results are existing values.
PiperOrigin-RevId: 251674299
2019-06-09 16:18:55 -07:00
River Riddle
f1b848e470 NFC: Rename FuncBuilder to OpBuilder and refactor to take a top level region instead of a function.
PiperOrigin-RevId: 251563898
2019-06-09 16:17:59 -07:00
River Riddle
94541563dc Abstract the internal storage of the NamedAttributeList into a new attribute, DictionaryAttr. This attribute maintains a sorted list of NamedAttributes. This will allow for operations/functions to maintain sub dictionaries of attributes.
The syntax is the same as top level attribute dictionaries:
       {sub_dictionary: {fn: @someFn, boolAttr: true}}

--

PiperOrigin-RevId: 250898950
2019-06-01 20:12:01 -07:00
MLIR Team
5a91b9896c Remove "size" property of affine maps.
--

PiperOrigin-RevId: 250572818
2019-06-01 20:09:02 -07:00
River Riddle
c33862b0ed Refactor FunctionAttr to hold the internal function reference by name instead of pointer. The one downside to this is that the function reference held by a FunctionAttr needs to be explicitly looked up from the parent module. This provides several benefits though:
* There is no longer a need to explicitly remap function attrs.
      - This removes a potentially expensive call from the destructor of Function.
      - This will enable some interprocedural transformations to now run intraprocedurally.
      - This wasn't scalable and forces dialect defined attributes to override
        a virtual function.
    * Replacing a function is now a trivial operation.
    * This is a necessary first step to representing functions as operations.

--

PiperOrigin-RevId: 249510802
2019-06-01 19:56:54 -07:00
River Riddle
eb5ec03960 Refactor PatternRewriter to inherit from FuncBuilder instead of Builder. This is necessary for allowing more complicated rewrites in the future that may do things like update the insertion point (e.g. for rewrites involving regions).
--

PiperOrigin-RevId: 248803153
2019-05-20 13:46:26 -07:00
Geoffrey Martin-Noble
090662c5f3 Rename VectorOrTensorType to ShapedType
This is in preparation for making it also support/be a parent class of MemRefType. MemRefs have similar shape/rank/element semantics and it would be useful to be able to use these same utilities for them.

    This CL should not change any semantics and only change variables, types, string literals, and comments. In follow-up CLs I will prepare all callers to handle MemRef types or remove their dependence on ShapedType.

    Discussion/Rationale in https://groups.google.com/a/tensorflow.org/forum/#!topic/mlir/cHLoyfGu8y8

--

PiperOrigin-RevId: 248476449
2019-05-20 13:43:58 -07:00
River Riddle
983e0eea95 Simplify several usages of attributes now that they always have a type and, transitively, access to the context.
This also fixes a bug where FunctionAttrs were not being remapped for function and function argument attributes.

--

PiperOrigin-RevId: 246876924
2019-05-10 19:22:41 -07:00
River Riddle
1316db3baa Add support for a NoneType.
none-type ::= `none`

    The `none` type is a unit type, i.e. a type with exactly one possible value, where its value does not have a defined dynamic representation.

--

PiperOrigin-RevId: 245599248
2019-05-06 08:19:20 -07:00
River Riddle
22ad45a7aa Add support for Unit Attributes.
A unit attribute is an attribute that represents a value of `unit` type. The
    `unit` type allows only one value forming a singleton set. This attribute value
    is used to represent attributes that only have meaning from their existence.

    One example of such an attribute could be the `swift.self` attribute. This attribute indicates that a function parameter is the self/context
    parameter. It could be represented as a boolean attribute(true or false), but a
    value of false doesn't really bring any value. The parameter either is the
    self/context or it isn't.

    ```mlir {.mlir}
    // A unit attribute defined with the `unit` value specifier.
    func @verbose_form(i1 {unitAttr : unit})

    // A unit attribute can also be defined without the `unit` value specifier.
    func @simple_form(i1 {unitAttr})
    ```

--

PiperOrigin-RevId: 245254045
2019-05-06 08:16:39 -07:00
Lei Zhang
4cda344e7b Add methods for building array attributes in Builder
I32/I64/F32/F64/Str array attributes are commonly used in ops. It helps
    to have handy methods for them.

--

PiperOrigin-RevId: 242170569
2019-04-07 18:19:56 -07:00
Alex Zinenko
5a5bba0279 Introduce affine terminator
Due to legacy reasons (ML/CFG function separation), regions in affine control
flow operations require contained blocks not to have terminators.  This is
inconsistent with the notion of the block and may complicate code motion
between regions of affine control operations and other regions.

Introduce `affine.terminator`, a special terminator operation that must be used
to terminate blocks inside affine operations and transfers the control back to
he region enclosing the affine operation.  For brevity and readability reasons,
allow `affine.for` and `affine.if` to omit the `affine.terminator` in their
regions when using custom printing and parsing format.  The custom parser
injects the `affine.terminator` if it is missing so as to always have it
present in constructed operations.

Update transformations to account for the presence of terminator.  In
particular, most code motion transformation between loops should leave the
terminator in place, and code motion between loops and non-affine blocks should
drop the terminator.

PiperOrigin-RevId: 240536998
2019-03-29 17:44:24 -07:00
River Riddle
f9d91531df Replace usages of Instruction with Operation in the /IR directory.
This is step 2/N to renaming Instruction to Operation.

PiperOrigin-RevId: 240459216
2019-03-29 17:43:37 -07:00
Alex Zinenko
a7215a9032 Allow creating standalone Regions
Currently, regions can only be constructed by passing in a `Function` or an
`Instruction` pointer referencing the parent object, unlike `Function`s or
`Instruction`s themselves that can be created without a parent.  It leads to a
rather complex flow in operation construction where one has to create the
operation first before being able to work with its regions.  It may be
necessary to work with the regions before the operation is created.  In
particular, in `build` and `parse` functions that are executed _before_ the
operation is created in cases where boilerplate region manipulation is required
(for example, inserting the hypothetical default terminator in affine regions).
Allow creating standalone regions.  Such regions are meant to own a list of
blocks and transfer them to other regions on demand.

Each instruction stores a fixed number of regions as trailing objects and has
ownership of them.  This decreases the size of the Instruction object for the
common case of instructions without regions.  Keep this behavior intact.  To
allow some flexibility in construction, make OperationState store an owning
vector of regions.  When the Builder creates an Instruction from
OperationState, the bodies of the regions are transferred into the
instruction-owned regions to minimize copying.  Thus, it becomes possible to
fill standalone regions with blocks and move them to an operation when it is
constructed, or move blocks from a region to an operation region, e.g., for
inlining.

PiperOrigin-RevId: 240368183
2019-03-29 17:40:59 -07:00
Chris Lattner
88e9f418f5 Continue pushing const out of the core IR types - in this case, remove const
from Function.

PiperOrigin-RevId: 239638635
2019-03-29 17:29:58 -07:00