Commit Graph

251 Commits

Author SHA1 Message Date
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
Alex Zinenko 8a5f88191b Decouple region argument parsing from their type assignment
The parser currently expects region arguments to have a fixed, known type when
    the %-name of the region argument is parsed.  This may not necessarily be the
    case, for example, if the region argument types are the same as the operand
    types, located at the end of the operation.  Furthermore, the parser currently
    stores the values for region arguments internally and attaches them to the next
    parsed region implicitly.  This makes it impossible to attach some of the
    arguments to one region and some other arguments to another region if the
    regions are not textually interleaved with operation arguments.

    Provide `OpAsmParser::parseRegionArgument` that parses an SSA identifier and
    delays its type assignment until the region is parsed, similarly to operands.
    Update `OpAsmParser::parseRegion` to accept a list of pre-parsed SSA
    identifiers and a list of types instead of using SSA identifiers stored in the
    parser.

--

PiperOrigin-RevId: 245491133
2019-05-06 08:18:14 -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
Chris Lattner 09c053bfd0 Expand the pretty dialect type system to support arbitrary punctuation and
other characters within the <>'s now that we can.  This will allow quantized
    types to use the pretty syntax (among others) after a few changes.

--

PiperOrigin-RevId: 243521268
2019-04-18 11:48:09 -07:00
Chris Lattner 72441fcbf2 Change the asmprinter to use pretty syntax for dialect types when it can,
making the IR dumps much nicer.

    This is part 2/3 of the path to making dialect types more nice.  Part 3/3 will
    slightly generalize the set of characters allowed in pretty types and make it
    more principled.

--

PiperOrigin-RevId: 242249955
2019-04-07 18:21:13 -07:00
Chris Lattner 3f93d93367 Introduce support for parsing pretty dialect types, currently with a very
restricted grammar.  This will make certain common types much easier to read.

    This is part tensorflow/mlir#1 of 2, which allows us to accept the new syntax.  Part 2 will
    change the asmprinter to automatically use it when appropriate, which will
    require updating a bunch of tests.

    This is motivated by the EuroLLVM tutorial and cleaning up the LLVM dialect aesthetics a bit more.

--

PiperOrigin-RevId: 242234821
2019-04-07 18:21:02 -07:00
Mehdi Amini 3a2955fa1f Rename UnknownType to OpaqueType (NFC)
This came up in a review of the tutorial, it was suggested that "opaque" is more
    descriptive than "unknown" here.

--

PiperOrigin-RevId: 241832927
2019-04-03 19:21:47 -07:00
Alex Zinenko 736bef7386 Introduce custom format for the LLVM IR Dialect
Historically, the LLVM IR dialect has been using the generic form of MLIR
    operation syntax.  It is verbose and often redundant.  Introduce the custom
    printing and parsing for all existing operations in the LLVM IR dialect.
    Update the relevant documentation and tests.

--

PiperOrigin-RevId: 241617393
2019-04-02 16:31:58 -07:00
River Riddle 0be6369176 Update the Function and Module verifiers to return LogicalResult instead of bool.
--

PiperOrigin-RevId: 241553930
2019-04-02 13:40:20 -07:00
Feng Liu 191aaa82ef Support 0-d tensor type attributes
This CL fixes the parser and printer to support the 0-d tensor type attributes.

--

PiperOrigin-RevId: 241345329
2019-04-01 10:59:59 -07:00
Chris Lattner 0fb905c070 Implement basic IR support for a builtin complex<> type. As with tuples, we
have no standard ops for working with these yet, this is simply enough to
    represent and round trip them in the printer and parser.

--

PiperOrigin-RevId: 241102728
2019-03-30 11:23:39 -07:00
River Riddle 0ae68a3ccf Remove the MLIRContext parameter from Dialect::parseType. Dialects already have access to the context via Dialect::getContext.
--

PiperOrigin-RevId: 241047077
2019-03-29 17:57:27 -07:00
River Riddle 909a63d8bf Tidy up a few comments and error messages related to parsing multi-result operations.
PiperOrigin-RevId: 240876306
2019-03-29 17:52:51 -07:00
River Riddle 01140bd137 Change the muli-return syntax for operations. The name of the operation result now contains the number of results that it refers to if the number of results is greater than 1.
Example:
    %call:2 = call @multi_return() : () -> (f32, i32)
    use(%calltensorflow/mlir#0, %calltensorflow/mlir#1)

This cl also adds parser support for uniquely named result values. This means that a test writer can now write something like:
    %foo, %bar = call @multi_return() : () -> (f32, i32)
    use(%foo, %bar)

Note: The printer will still print the collapsed form.
PiperOrigin-RevId: 240860058
2019-03-29 17:51:32 -07:00
River Riddle af9760fe18 Replace remaining usages of the Instruction class with Operation.
PiperOrigin-RevId: 240777521
2019-03-29 17:50:04 -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
Mehdi Amini 9a0aa4ff17 At missing mlir:: namespace qualifier in front of function definition
This was defining a function in the global namespace instead of the mlir one.

PiperOrigin-RevId: 239918509
2019-03-29 17:32:59 -07:00
Mehdi Amini 0f5602ae3d Add a parserSourceFile function that takes a file path directly
This avoids adding boilerplate around the SourceMgr on the client.

PiperOrigin-RevId: 239918122
2019-03-29 17:32:43 -07:00
River Riddle 30e68230bd Add support for a standard TupleType. Though this is a standard type, it merely provides a common mechanism for representing tuples in MLIR. It is up to dialect authors to provides operations for manipulating them, e.g. extract_tuple_element.
TupleType has the following form:
   tuple-type ::= `tuple` `<` (type (`,` type)*)? `>`

Example:

// Empty tuple.
tuple<>

// Single element.
tuple<i32>

// Multi element.
tuple<i32, tuple<f32>, i16>

PiperOrigin-RevId: 239226021
2019-03-29 17:25:09 -07:00
River Riddle 6d6ff7298a Add support for parsing true/false inside of a splat tensor literal.
PiperOrigin-RevId: 239052061
2019-03-29 17:24:09 -07:00
River Riddle 9942d41e3b Add an 'Instruction::create' overload that accepts an existing NamedAttributeList. This avoids the need to unique an attribute list if one already exists, e.g. when cloning an existing instruction.
PiperOrigin-RevId: 238512499
2019-03-29 17:18:38 -07:00
Alex Zinenko 276fae1b0d Rename BlockList into Region
NFC.  This is step 1/n to specifying regions as parts of any operation.

PiperOrigin-RevId: 238472370
2019-03-29 17:18:04 -07:00
River Riddle a495f960e0 Introduce the notion of dialect attributes and dependent attributes. A dialect attribute derives its context from a specific dialect, whereas a dependent attribute derives context from what it is attached to. Following this, we now enforce that functions and function arguments may only contain dialect specific attributes. These are generic entities and cannot provide any specific context for a dependent attribute.
Dialect attributes are defined as:

        dialect-namespace `.` attr-name `:` attribute-value

Dialects can override any of the following hooks to verify the validity of a given attribute:
  * verifyFunctionAttribute
  * verifyFunctionArgAttribute
  * verifyInstructionAttribute

PiperOrigin-RevId: 236507970
2019-03-29 16:55:05 -07:00
River Riddle eeeef090ef Set the namespace of the StandardOps dialect to "std", but add a special case to the parser to allow parsing standard operations without the "std" prefix. This will now allow for the standard dialect to be looked up dynamically by name.
PiperOrigin-RevId: 236493865
2019-03-29 16:54:20 -07:00
River Riddle f37651c708 NFC. Move all of the remaining operations left in BuiltinOps to StandardOps. The only thing left in BuiltinOps are the core MLIR types. The standard types can't be moved because they are referenced within the IR directory, e.g. in things like Builder.
PiperOrigin-RevId: 236403665
2019-03-29 16:53:35 -07:00
River Riddle 269c872ee8 Add support for parsing and printing affine.if and affine.for attributes. The attribute dictionaries are printed after the final block list for both operations:
for %i = 0 to 10 {
     ...
  } {some_attr: true}

  if () : () () {
    ...
  } {some_attr: true}

  if () : () () {
    ...
  } else {
    ...
  } {some_attr: true}

PiperOrigin-RevId: 236346983
2019-03-29 16:52:19 -07:00
River Riddle ddc6788cc7 Provide a Builder::getNamedAttr and (Instruction|Function)::setAttr(StringRef, Attribute) to simplify attribute manipulation.
PiperOrigin-RevId: 236222504
2019-03-29 16:50:59 -07:00
River Riddle db1757f858 Add support for named function argument attributes. The attribute dictionary is printed after the argument type:
func @arg_attrs(i32 {arg_attr: 10})

func @arg_attrs(%arg0: i32 {arg_attr: 10})

PiperOrigin-RevId: 236136830
2019-03-29 16:50:15 -07:00
River Riddle 0f8c3f4071 When parsing, check that a region operation is not referencing any of the entry arguments to its block lists.
PiperOrigin-RevId: 236030438
2019-03-29 16:49:29 -07:00
River Riddle 3b3e11da93 Validate the names of attribute, dialect, and functions during verification. This essentially enforces the parsing rules upon their names.
PiperOrigin-RevId: 235818842
2019-03-29 16:44:53 -07:00
River Riddle 2d4b0e2c00 Add parser support for internal named attributes. These are attributes with names starting with ':'.
PiperOrigin-RevId: 235774810
2019-03-29 16:44:22 -07:00
River Riddle b4f033f6c6 Convert the dialect type parse/print hooks into virtual functions on the Dialect class.
PiperOrigin-RevId: 235589945
2019-03-29 16:42:05 -07:00
River Riddle 2f11f86846 Add langref descriptions for the attribute values supported in MLIR.
PiperOrigin-RevId: 233661338
2019-03-29 16:26:08 -07:00
Tatiana Shpeisman 2e6cd60d3b Add dialect-specific decoding for opaque constants.
Associates opaque constants with a particular dialect. Adds general mechanism to register dialect-specific hooks defined in external components. Adds hooks to decode opaque tensor constant and extract an element of an opaque tensor constant.

This CL does not change the existing mechanism for registering constant folding hook yet. One thing at a time.

PiperOrigin-RevId: 233544757
2019-03-29 16:24:38 -07:00
River Riddle 366ebcf6aa Remove the restriction that only registered terminator operations may terminate a block and have block operands. This allows for any operation to hold block operands. It also introduces the notion that unregistered operations may terminate a block. As such, the 'isTerminator' api on Instruction has been split into 'isKnownTerminator' and 'isKnownNonTerminator'.
PiperOrigin-RevId: 233076831
2019-03-29 16:22:23 -07:00
Alex Zinenko 36c0516c78 Disallow zero dimensions in vectors and memrefs
Aggregate types where at least one dimension is zero do not fully make sense as
they cannot contain any values (their total size is zero).  However, TensorFlow
and XLA support tensors with zero sizes, so we must support those too.  This is
relatively safe since, unlike vectors and memrefs, we don't have first-class
element accessors for MLIR tensors.

To support sparse element attributes of vector types that have no non-zero
elements, make sure that index and value element attributes have tensor type so
that we never need to create a zero vector type internally.  Note that this is
already consistent with the inline documentation of the sparse elements
attribute.  Users of the sparse elements attribute should not rely on the
storage schema anyway.

PiperOrigin-RevId: 232896707
2019-03-29 16:20:38 -07:00
Alex Zinenko 99b19c1d20 Disallow hexadecimal literals in type declarations
Existing IR syntax is ambiguous in type declarations in presence of zero sizes.
In particular, `0x1` in the type size can be interpreted as either a
hexadecimal literal corresponding to 1, or as two distinct decimal literals
separated by an `x` for sizes.  Furthermore, the shape `<0xi32>` fails lexing
because it is expected to be an integer literal.

Fix the lexer to treat `0xi32` as an integer literal `0` followed by a bare
identifier `xi32` (look one character ahead and early return instead of
erroring out).

Disallow hexadecimal literals in type declarations and forcibly split the token
into multiple parts while parsing the type.  Note that the splitting trick has
been already present to separate the element type from the preceding `x`
character.

PiperOrigin-RevId: 232880373
2019-03-29 16:20:22 -07:00
Alex Zinenko 40d5d09f9d Print parens around the return type of a function if it is also a function type
Existing type syntax contains the following productions:

    function-type ::= type-list-parens `->` type-list
    type-list ::= type | type-list-parens
    type ::= <..> | function-type

Due to these rules, when the parser sees `->` followed by `(`, it cannot
disambiguate if `(` starts a parenthesized list of function result types, or a
parenthesized list of operands of another function type, returned from the
current function.  We would need an unknown amount of lookahead to try to find
the `->` at the right level of function nesting to differentiate between type
lists and singular function types.

Instead, require the result type of the function that is a function type itself
to be always parenthesized, at the syntax level.  Update the spec and the
parser to correspond to the production rule names used in the spec (although it
would have worked without modifications).  Fix the function type parsing bug in
the process, as it used to accept the non-parenthesized list of types for
arguments, disallowed by the spec.

PiperOrigin-RevId: 232528361
2019-03-29 16:14:50 -07:00
River Riddle bf9c381d1d Remove InstWalker and move all instruction walking to the api facilities on Function/Block/Instruction.
PiperOrigin-RevId: 232388113
2019-03-29 16:12:59 -07:00
River Riddle 44e040dd63 Remove remaining references to OperationInst in all directories except for lib/Transforms.
PiperOrigin-RevId: 232322771
2019-03-29 16:10:38 -07:00
River Riddle 126ec14e2d Fix the handling of the resizable operands bit of OperationState in a few places.
PiperOrigin-RevId: 232163738
2019-03-29 16:08:28 -07:00
River Riddle 38f8dc67be When parsing, treat an IntegerSet with no constraints as a degenerate true case. Also update the spec to note that affine constraints are optional.
PiperOrigin-RevId: 232158673
2019-03-29 16:07:56 -07:00
River Riddle d54e3dd358 Emit an error when parsing an affine structure if '->' or ':' is not found
after the dim/symbol id list.

PiperOrigin-RevId: 232094789
2019-03-29 16:07:40 -07:00
River Riddle 5052bd8582 Define the AffineForOp and replace ForInst with it. This patch is largely mechanical, i.e. changing usages of ForInst to OpPointer<AffineForOp>. An important difference is that upon construction an AffineForOp no longer automatically creates the body and induction variable. To generate the body/iv, 'createBody' can be called on an AffineForOp with no body.
PiperOrigin-RevId: 232060516
2019-03-29 16:06:49 -07:00
River Riddle 9f22a2391b Define an detail::OperandStorage class to handle managing instruction operands. This class stores operands in a similar way to SmallVector except for two key differences. The first is the inline storage, which is a trailing objects array. The second is that being able to dynamically resize the operand list is optional. This means that we can enable the cases where operations need to change the number of operands after construction without losing the spatial locality benefits of the common case (operation instructions / non-control flow instructions with a lifetime fixed number of operands).
PiperOrigin-RevId: 231910497
2019-03-29 16:05:08 -07:00
River Riddle 755538328b Recommit: Define a AffineOps dialect as well as an AffineIfOp operation. Replace all instances of IfInst with AffineIfOp and delete IfInst.
PiperOrigin-RevId: 231342063
2019-03-29 15:59:30 -07:00
Nicolas Vasilache ae772b7965 Automated rollback of changelist 231318632.
PiperOrigin-RevId: 231327161
2019-03-29 15:42:38 -07:00
River Riddle 5ecef2b3f6 Define a AffineOps dialect as well as an AffineIfOp operation. Replace all instances of IfInst with AffineIfOp and delete IfInst.
PiperOrigin-RevId: 231318632
2019-03-29 15:42:08 -07:00
River Riddle 36babbd781 Change the ForInst induction variable to be a block argument of the body instead of the ForInst itself. This is a necessary step in converting ForInst into an operation.
PiperOrigin-RevId: 231064139
2019-03-29 15:40:23 -07:00