Commit Graph

201 Commits

Author SHA1 Message Date
Alex Zinenko 5c285f228c LLVM IR Conversion: keep LLVM dialect types as is during conversion
When converting to the LLVM IR Dialect, it is possible for the input IR to
contain LLVM IR Dialect operation and/or types, for example, some functions may
have been coverted to the LLVM IR Dialect already, or may have been created
using this dialect directly.  Make sure that type conversion keeps LLVM IR
Dialect types unmodified and does not error out.  Operations are already kept
as is.

PiperOrigin-RevId: 240574972
2019-03-29 17:45:11 -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 832567b379 NFC: Rename the 'for' operation in the AffineOps dialect to 'affine.for' and set the namespace of the AffineOps dialect to 'affine'.
PiperOrigin-RevId: 240165792
2019-03-29 17:39:03 -07:00
River Riddle 9c6e92360c NFC: Rename the 'if' operation in the AffineOps dialect to 'affine.if'.
PiperOrigin-RevId: 240071154
2019-03-29 17:36:53 -07:00
Chris Lattner 5246bceee0 Now that ConstOpPointer is gone, we can change the various methods generated by
tblgen be non-const.  This requires introducing some const_cast's at the
moment, but those (and lots more stuff) will disappear in subsequent patches.

This significantly simplifies those patches because the various tblgen op emitters
get adjusted.

PiperOrigin-RevId: 239954566
2019-03-29 17:33:45 -07:00
Chris Lattner 589df37142 Move to new `const` model, part 1: remove ConstOpPointer.
This eliminate ConstOpPointer (but keeps OpPointer for now) by making OpPointer
implicitly launder const in a const incorrect way.  It will eventually go away
entirely, this is a progressive step towards the new const model.

PiperOrigin-RevId: 239512640
2019-03-29 17:26:56 -07:00
Chris Lattner ee1c726bfa Add a nice quote from Bjarke to summarize the const situation.
PiperOrigin-RevId: 239510578
2019-03-29 17:26:41 -07:00
Chris Lattner 3f1a5e4cf4 Add a "Usage of Const in MLIR" doc, explaining the rationale for the design
point we're moving the compiler to.

PiperOrigin-RevId: 239462779
2019-03-29 17:26:10 -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 6e983ae8df Give PassInstrumentor a SmartMutex to lock access to the held instrumentations.
PiperOrigin-RevId: 239031524
2019-03-29 17:23:53 -07:00
River Riddle 8e7b683d1f Replace the usages of llvm::Timer in PassTiming in favor of a simple nested Timer. The output view is simplified to just display the Wall Time. This new infrastructure will greatly simplify the amount of work needed to support multi-threaded execution timing.
PiperOrigin-RevId: 238819218
2019-03-29 17:21:34 -07:00
River Riddle 076a7350e2 Add an instrumentation for conditionally printing the IR before and after pass execution. This instrumentation can be added directly to the PassManager via 'enableIRPrinting'. mlir-opt exposes access to this instrumentation via the following flags:
* print-ir-before=(comma-separated-pass-list)
  - Print the IR before each of the passes provided within the pass list.
* print-ir-before-all
  - Print the IR before every pass in the pipeline.
* print-ir-after=(comma-separated-pass-list)
  - Print the IR after each of the passes provided within the pass list.
* print-ir-after-all
  - Print the IR after every pass in the pipeline.
* print-ir-module-scope
  - Always print the Module IR, even for non module passes.

PiperOrigin-RevId: 238523649
2019-03-29 17:19:57 -07:00
River Riddle 6558f80c8d Refactor pass timing so that it is toggled on the passmanager via 'enableTiming'. This also makes the pipeline view the default display mode.
PiperOrigin-RevId: 238079916
2019-03-29 17:15:42 -07:00
River Riddle fde5bcdae7 Add documentation for the pass instrumentation framework to the WritingAPass document.
PiperOrigin-RevId: 237919897
2019-03-29 17:13:11 -07:00
River Riddle dc141c307b Tidy up some of the pass infrastructure g3doc.
* Separate MyAnalysis into MyFunctionAnalysis/MyModuleAnalysis to avoid potential confusion.
* Add an example of an inline lambda builder for PassPipelineRegistration.
* Clarify the wording on a few of the pass restrictions.

PiperOrigin-RevId: 237840325
2019-03-29 17:11:41 -07:00
River Riddle f427bddd06 Update the PassManager infrastructure to return Status instead of bool.
PiperOrigin-RevId: 237261205
2019-03-29 17:05:51 -07:00
Alex Zinenko b9724e98c2 Cleanups in the LLVM IR Dialect
These cleanups reflects some recent changes to the LLVM IR Dialect and the
infrastructure that affects it.  In particular, add documentation on direct and
indirect function calls as well as remove the `call` and `call0` separation.
Change the prefix of custom types from `!llvm.type` to `!llvm` so that it
matches the IR.  Remove the verifier check disallowing conditional branches to
the same block with arguments: identical arguments are now supported, and
different arguments will be caught later.

PiperOrigin-RevId: 237203452
2019-03-29 17:05:05 -07:00
River Riddle 157e3cdb19 Add documentation for the new pass infrastructure.
PiperOrigin-RevId: 237153501
2019-03-29 17:04:03 -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 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 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
Dimitrios Vytiniotis 41c37c6246 Unboxing for static memrefs.
When lowering to MLIR(LLVMDialect) we unbox the structs that result
from converting static memrefs, that is, singleton structs
that just contain a raw pointer. This allows us to get rid of all
"extractvalue" instructions in the common case where shapes are fully
known.

PiperOrigin-RevId: 235706021
2019-03-29 16:43:20 -07:00
Alex Zinenko 1da1b4c321 LLVM IR dialect and translation: support conditional branches with arguments
Since the goal of the LLVM IR dialect is to reflect LLVM IR in MLIR, the
dialect and the conversion procedure must account for the differences betweeen
block arguments and LLVM IR PHI nodes. In particular, LLVM IR disallows PHI
nodes with different values coming from the same source. Therefore, the LLVM IR
dialect now disallows `cond_br` operations that have identical successors
accepting arguments, which would lead to invalid PHI nodes. The conversion
process resolves the potential PHI source ambiguity by injecting dummy blocks
if the same block is used more than once as a successor in an instruction.
These dummy blocks branch unconditionally to the original successors, pass them
the original operands (available in the dummy block because it is dominated by
the original block) and are used instead of them in the original terminator
operation.

PiperOrigin-RevId: 235682798
2019-03-29 16:43:05 -07:00
Alex Zinenko 970715be9c Update LLVM Dialect documentation
Addressing post-submit comments.  The `getelementptr` operation now supports
non-constant indexes, similarly to LLVM, and this functionality is exercised by
the lowering to the dialect.  Update the documentation accordingly.

List the values of integer comparison predicates, which currently correspond to
those of CmpIOp in MLIR.  Ideally, we would use strings instead, but it
requires additional support for argument conversion in both the dialect
lowering pass and the LLVM translator.

PiperOrigin-RevId: 235678877
2019-03-29 16:42:50 -07:00
Alex Zinenko 51835e73e0 Document the conversion into the LLVM IR dialect
Add a documentation page on the key points of the conversion to LLVM IR.  This
focuses on the aspects of conversion that are relevant for integration of the
LLVM IR dialect (and produced LLVM IR that is mostly a one-to-one translation)
into other projects.  In particular, it describes the type conversion rules and
the memref model supporting dynamic sizes.

PiperOrigin-RevId: 235190772
2019-03-29 16:38:04 -07:00
Alex Zinenko f0597cbf9f Add documentation for the LLVM IR dialect
The LLVM IR pass was bootstrapped without user documentation, following LLVM's
language reference and existing conversions between MLIR standard operations
and LLVM IR instructions.  Provide concise documentation of the LLVM IR dialect
operations.  This documentation does not describe the semantics of the
operations, which should match that of LLVM IR, but highlights the structural
differences in operation definitions, in particular using attributes instead of
constant-only values.  It also describes pseudo-operations that exist only to
make the LLVM IR dialect self-contained within MLIR.

While it could have been possible to generate operation description from
TableGen, this opts for a more concise format where groups of related
operations are described together.

PiperOrigin-RevId: 235149136
2019-03-29 16:37:26 -07:00
River Riddle 3e656599f1 Define a PassID class to use when defining a pass. This allows for the type used for the ID field to be self documenting. It also allows for the compiler to know the set alignment of the ID object, which is useful for storing pointer identifiers within llvm data structures.
PiperOrigin-RevId: 235107957
2019-03-29 16:37:12 -07:00
Uday Bondhugula 4056b98e22 Update / cleanup pass documentation + Langref alloc examples
PiperOrigin-RevId: 234866323
2019-03-29 16:36:10 -07:00
Uday Bondhugula 4ca6219099 Update pass documentation + improve/fix some comments
- add documentation for passes
- improve / fix outdated doc comments

PiperOrigin-RevId: 234627076
2019-03-29 16:32:11 -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
River Riddle 4755774d16 Make IndexType a standard type instead of a builtin. This also cleans up some unnecessary factory methods on the Type class.
PiperOrigin-RevId: 233640730
2019-03-29 16:25:38 -07:00
Uday Bondhugula c419accea3 Automated rollback of changelist 232728977.
PiperOrigin-RevId: 232944889
2019-03-29 16:21:38 -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
Uday Bondhugula 4ba8c9147d Automated rollback of changelist 232717775.
PiperOrigin-RevId: 232807986
2019-03-29 16:19:33 -07:00
River Riddle fd2d7c857b Rename the 'if' operation in the AffineOps dialect to 'affine.if' and namespace
the AffineOps dialect with 'affine'.

PiperOrigin-RevId: 232728977
2019-03-29 16:18:59 -07:00
River Riddle 90d10b4e00 NFC: Rename the 'for' operation in the AffineOps dialect to 'affine.for'. The is the second step to adding a namespace to the AffineOps dialect.
PiperOrigin-RevId: 232717775
2019-03-29 16:17:59 -07:00
River Riddle 3227dee15d NFC: Rename affine_apply to affine.apply. This is the first step to adding a namespace to the affine dialect.
PiperOrigin-RevId: 232707862
2019-03-29 16:17:29 -07:00
Jacques Pienaar 31f2b3ffa1 Address follow on comments for quickstart doc.
PiperOrigin-RevId: 232705423
2019-03-29 16:16:58 -07:00
River Riddle 6f7470a56a Define the initial g3doc for the Affine dialect.
PiperOrigin-RevId: 232581506
2019-03-29 16:15:26 -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
Jacques Pienaar 1b1f293a5d MLIR graph rewrite using pattern quickstart doc.
Start quickstart guide of how to define ops + specify patterns for rewrite.

PiperOrigin-RevId: 232490287
2019-03-29 16:14:35 -07:00
Lei Zhang b2dbbdb704 Merge OpProperty and Traits into OpTrait
They are essentially both modelling MLIR OpTrait; the former achieves the
purpose via introducing corresponding symbols in TableGen, while the latter
just uses plain strings.

Unify them to provide a single mechanism to avoid confusion and to better
reflect the definitions on MLIR C++ side.

Ideally we should be able to deduce lots of these traits automatically via
other bits of op definitions instead of manually specifying them; but not
for now though.

PiperOrigin-RevId: 232191401
2019-03-29 16:09:03 -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
Jacques Pienaar 70e3873e86 Update link
PiperOrigin-RevId: 232049075
2019-03-29 16:06:14 -07:00
Chris Lattner b42bea215a Change AffineApplyOp to produce a single result, simplifying the code that
works with it, and updating the g3docs.

PiperOrigin-RevId: 231120927
2019-03-29 15:40:38 -07:00
Alex Zinenko 6d37a255e2 Generic dialect conversion pass exercised by LLVM IR lowering
This commit introduces a generic dialect conversion/lowering/legalization pass
and illustrates it on StandardOps->LLVMIR conversion.

It partially reuses the PatternRewriter infrastructure and adds the following
functionality:
- an actual pass;
- non-default pattern constructors;
- one-to-many rewrites;
- rewriting terminators with successors;
- not applying patterns iteratively (unlike the existing greedy rewrite driver);
- ability to change function signature;
- ability to change basic block argument types.

The latter two things required, given the existing API, to create new functions
in the same module.  Eventually, this should converge with the rest of
PatternRewriter.  However, we may want to keep two pass versions: "heavy" with
function/block argument conversion and "light" that only touches operations.

This pass creates new functions within a module as a means to change function
signature, then creates new blocks with converted argument types in the new
function.  Then, it traverses the CFG in DFS-preorder to make sure defs are
converted before uses in the dominated blocks.  The generic pass has a minimal
interface with two hooks: one to fill in the set of patterns, and another one
to convert types for functions and blocks.  The patterns are defined as
separate classes that can be table-generated in the future.

The LLVM IR lowering pass partially inherits from the existing LLVM IR
translator, in particular for type conversion.  It defines a conversion pattern
template, instantiated for different operations, and is a good candidate for
tablegen.  The lowering does not yet support loads and stores and is not
connected to the translator as it would have broken the existing flows.  Future
patches will add missing support before switching the translator in a single
patch.

PiperOrigin-RevId: 230951202
2019-03-29 15:37:23 -07:00
Lei Zhang 5654450853 Unify terms regarding assembly form to use generic vs. custom
This CL just changes various docs and comments to use the term "generic" and
"custom" when mentioning assembly forms. To be consist, several methods are
also renamed:

* FunctionParser::parseVerboseOperation() -> parseGenericOperation()
* ModuleState::hasShorthandForm() -> hasCustomForm()
* OpAsmPrinter::printDefaultOp() -> printGenericOp()

PiperOrigin-RevId: 230568819
2019-03-29 15:32:35 -07:00
Nicolas Vasilache 9f3f39d61a Cleanup EDSCs
This CL performs a bunch of cleanups related to EDSCs that are generally
useful in the context of using them with a simple wrapping C API (not in this
CL) and with simple language bindings to Python and Swift.

PiperOrigin-RevId: 230066505
2019-03-29 15:27:58 -07:00
Chris Lattner adc2ab172d Some tweaks to the really great op definition doc.
PiperOrigin-RevId: 229622071
2019-03-29 15:23:58 -07:00
Jacques Pienaar a5827fc91d Add attribute matching and transform to pattern rewrites.
Start simple with single predicate match & transform rules for attributes.
* Its unclear whether modelling Attr predicates will be needed so start with allowing matching attributes with a single predicate.
*  The input and output attr type often differs and so add ability to specify a transform between the input and output format.

PiperOrigin-RevId: 229580879
2019-03-29 15:22:14 -07:00
Lei Zhang 254821d1db Rename hasCanonicalizationPatterns to hasCanonicalizer
The latter is shorter but still conveys the idea clearly. It is also more
consistent with hasConstantFolder.

PiperOrigin-RevId: 229561774
2019-03-29 15:20:44 -07:00
Jacques Pienaar b5b7e61f7a Update to new sugared form in doc
PiperOrigin-RevId: 229544256
2019-03-29 15:20:29 -07:00
Jacques Pienaar ce64d3dbf0 Add OpDefinitions document.
Moving MLIR operation description doc to MarkDown doc.

PiperOrigin-RevId: 229376100
2019-03-29 15:17:08 -07:00
Uday Bondhugula 11ab300ad5 Update LangRef - integer sets should have at least one constraint
- this change is already consistent with the current code
- having no constraints made the integer set spec look odd - as nothing appears
  between ':' and the closing parenthesis
- there is no loss in representational power - an unconstrained set can always
  be represented by a trivially true constraint

PiperOrigin-RevId: 229307353
2019-03-29 15:16:22 -07:00
Alex Zinenko 6ce30becd7 Support verbose parsing and printing of terminator operations
Originally, terminators were special kinds of operation and could not be
extended by dialects.  Only builtin terminators were supported and they had
custom parsers and printers.  Currently, "terminator" is a property of an
operation, making it possible for dialects to define custom terminators.
However, verbose forms of operation syntax were not designed to support
terminators that may have a list of successors (each successor contains a block
name and an optional operand list).  Calling printDefaultOp on a terminator
drops all successor information.  Dialects are thus required to provide custom
parsers and printers for their terminators.

Introduce the syntax for the list of successors in the verbose from of the
operation.  Add support for printing and parsing verbose operations with
successors.

Note that this does not yet add support for unregistered terminators since
"terminator" is a property stored in AsbtractOperation and therefore is only
available for registered operations that have an instance of AbstractOperation.

Add tests for verbose parsing.  It is currently impossible to test round-trip
for verbose terminators because none of the known dialects use verbose syntax
for printing terminators by default, however the printer was exercised on the
LLVM IR dialect prototype.

PiperOrigin-RevId: 228566453
2019-03-29 15:06:26 -07:00
River Riddle 8eccc429b7 Add parser support for named type aliases.
Alias identifiers can be used in the place of the types that they alias, and are defined as:

    type-alias-def ::= '!' alias-name '=' 'type' type
    type-alias ::= '!' alias-name

Example:

    !avx.m128 = type vector<4 x f32>
    ...

    "foo"(%x) : vector<4 x f32> -> ()

    // becomes:

    "foo"(%x) : !avx.m128 -> ()

PiperOrigin-RevId: 228271372
2019-03-29 15:04:05 -07:00
MLIR Team 2cdb59f38d Spelling: bugpone -> bug-prone
PiperOrigin-RevId: 228231744
2019-03-29 15:02:25 -07:00
River Riddle bee0b83cef Update the langref to include the rationale and specification of the dialect extended type system.
PiperOrigin-RevId: 228184876
2019-03-29 15:01:26 -07:00
Alex Zinenko bc04556cf8 Introduce integer division and remainder operations
This adds signed/unsigned integer division and remainder operations to the
StandardOps dialect.  Two versions are required because MLIR integers are
signless, but the meaning of the leading bit is important in division and
affects the results.  LLVM IR made a similar choice.  Define the operations in
the tablegen file and add simple constant folding hooks in the C++
implementation.  Handle signed division overflow and division by zero errors in
constant folding.  Canonicalization is left for future work.

These operations are necessary to lower affine_apply's down to LLVM IR.

PiperOrigin-RevId: 228077549
2019-03-29 14:58:52 -07:00
Smit Hinsu d02b08eaf4 Add an example of rank zero tensor in go/mlir-spec
TESTED with preview

PiperOrigin-RevId: 227887054
2019-03-29 14:57:07 -07:00
Alex Zinenko 0c4ee54198 Merge LowerAffineApplyPass into LowerIfAndForPass, rename to LowerAffinePass
This change is mechanical and merges the LowerAffineApplyPass and
LowerIfAndForPass into a single LowerAffinePass.  It makes a step towards
defining an "affine dialect" that would contain all polyhedral-related
constructs.  The motivation for merging these two passes is based on retiring
MLFunctions and, eventually, transforming If and For statements into regular
operations.  After that happens, LowerAffinePass becomes yet another
legalization.

PiperOrigin-RevId: 227566113
2019-03-29 14:52:52 -07:00
Chris Lattner 8ebd64b32f Update the g3docs to reflect the merging of CFG and ML functions.
PiperOrigin-RevId: 227562943
2019-03-29 14:51:52 -07:00
Chris Lattner 37579ae8c4 Introduce ^ as a basic block sigil, eliminating an ambiguity on the MLIR
syntax.

PiperOrigin-RevId: 227234174
2019-03-29 14:45:59 -07:00
Chris Lattner 5b9c3f7cdb Tidy up references to "basic blocks" that should refer to blocks now. NFC.
PiperOrigin-RevId: 227196077
2019-03-29 14:44:59 -07:00
Chris Lattner 456ad6a8e0 Standardize naming of statements -> instructions, revisting the code base to be
consistent and moving the using declarations over.  Hopefully this is the last
truly massive patch in this refactoring.

This is step 21/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227178245
2019-03-29 14:44:30 -07:00
Chris Lattner 315a466aed Rename BasicBlock and StmtBlock to Block, and make a pass cleaning it up. I did not make an effort to rename all of the 'bb' names in the codebase, since they are still correct and any specific missed once can be fixed up on demand.
The last major renaming is Statement -> Instruction, which is why Statement and
Stmt still appears in various places.

This is step 19/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227163082
2019-03-29 14:43:58 -07:00
Chris Lattner 69d9e990fa Eliminate the using decls for MLFunction and CFGFunction standardizing on
Function.

This is step 18/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227139399
2019-03-29 14:43:13 -07:00
Chris Lattner 5187cfcf03 Merge Operation into OperationInst and standardize nomenclature around
OperationInst.  This is a big mechanical patch.

This is step 16/n towards merging instructions and statements, NFC.

PiperOrigin-RevId: 227093712
2019-03-29 14:42:23 -07:00
Alex Zinenko 51c8a095a3 Materialize vector_type_cast operation in the SuperVector dialect
This operation is produced and used by the super-vectorization passes and has
been emitted as an abstract unregistered operation until now.  For end-to-end
testing purposes, it has to be eventually lowered to LLVM IR.  Matching
abstract operation by name goes into the opposite direction of the generic
lowering approach that is expected to be used for LLVM IR lowering in the
future.  Register vector_type_cast operation as a part of the SuperVector
dialect.

Arguably, this operation is a special case of the `view` operation from the
Standard dialect.  The semantics of `view` is not fully specified at this point
so it is safer to rely on a custom operation.  Additionally, using a custom
operation may help to achieve clear dialect separation.

PiperOrigin-RevId: 225887305
2019-03-29 14:31:13 -07:00
Alex Zinenko df9bd857b1 Type system: replace Type::getBitWidth with getIntOrFloatBitWidth
As MLIR moves towards dialect-specific types, a generic Type::getBitWidth does
not make sense for all of them.  Even with the current type system, the bit
width is not defined (and causes the method in question to abort) for all
TensorFlow types.

This commit restricts the bit width definition to primitive standard types that
have a number of bits appearing verbatim in their type, i.e., integers and
floats.  As a side effect, it delegates the decision on the bit width of the
`index` to the backends.  Existing backends currently hardcode it to 64 bits.

The Type::getBitWidth method is replaced by Type::getIntOrFloatBitWidth that
only applies to integers and floats.  The call sites are updated to use the new
method, where applicable, or rewritten so as not rely on it.  Incidentally,
this fixes a utility method that did not account for memrefs being allowed to
have vectors as element types in the size computation.

As an observation, several places in the code use Type in places where a more
specific type could be used instead.  Some of those are fixed by this commit.

PiperOrigin-RevId: 225844792
2019-03-29 14:30:43 -07:00
Alex Zinenko bc52a639f9 Extract vector_transfer_* Ops into a SuperVectorDialect.
From the beginning, vector_transfer_read and vector_transfer_write opreations
were intended as a mid-level vectorization abstraction.  In particular, they
are lowered to the StandardOps dialect before further processing.  As such, it
does not make sense to keep them at the same level as StandardOps.  Introduce
the new SuperVectorOps dialect and move vector_transfer_* operations there.
This will be used as a testbed for the generic lowering/legalization pass.

PiperOrigin-RevId: 225554492
2019-03-29 14:28:58 -07:00
Alex Zinenko 97d2f3cd3d ConvertToCFG: use affine_apply to implement loop steps
Originally, loop steps were implemented using `addi` and `constant` operations
because `affine_apply` was not handled in the first implementation.  The
support for `affine_apply` has been added, use it to implement the update of
the loop induction variable.  This is more consistent with the lower and upper
bounds of the loop that are also implemented as `affine_apply`, removes the
dependence of the converted function on the StandardOps dialect and makes it
clear from the CFG function that all operations on the loop induction variable
are purely affine.

PiperOrigin-RevId: 225165337
2019-03-29 14:26:22 -07:00
Alex Zinenko 63261aa9a8 Disallow index types as elements of vector, memref and tensor types
An extensive discussion demonstrated that it is difficult to support `index`
types as elements of compound (vector, memref, tensor) types.  In particular,
their size is unknown until the target-specific lowering takes place.  MLIR may
need to store constants of the fixed-shape compound types (e.g.,
vector<4 x index>) internally and must know the size of the element type and
data layout constraints.  The same information is necessary for target-specific
lowering and translation to reliably support compound types with `index`
elements, but MLIR does not have a dedicated target description mechanism yet.

The uses cases for compound types with `index` elements, should they appear,
can be handled via an `index_cast` operation that converts between `index` and
fixed-size integer types at the SSA value level instead of the type level.

PiperOrigin-RevId: 225064373
2019-03-29 14:25:22 -07:00
Nicolas Vasilache 692f6ffdf8 [MLIR] Add LangRef entries for vector_transfer ops
PiperOrigin-RevId: 224535443
2019-03-29 14:22:20 -07:00
Tatiana Shpeisman 8ad72bd6be Make examples semantically meaningful and fix miscellaneous typos. Thanks to @rocky for pointing out the bugs.
PiperOrigin-RevId: 224239160
2019-03-29 14:18:52 -07:00
Alex Zinenko a3fb6d0da3 StandardOps: introduce 'select'.
The semantics of 'select' is conventional: return the second operand if the
first operand is true (1 : i1) and the third operand otherwise.  It is
applicable to vectors and tensors element-wise, similarly to LLVM instruction.
This operation is necessary to implement min/max to lower 'for' loops with
complex bounds to CFG functions and to support ternary operations in ML
functions.  It is preferred to first-class min/max because of its simplicity,
e.g. it is not concered with signedness.

PiperOrigin-RevId: 223160860
2019-03-29 14:11:25 -07:00
Alex Zinenko 67939e8b70 Create Passes.md.
Start the documentation file listing available MLIR passes.  Briefly describe
the `-convert-to-cfg` and the `-lower-affine-apply` passes.  These passes
serve as description templates for other passes.  In particular, they include
the dialect and operation restrictions in the pass input and output.

PiperOrigin-RevId: 223076894
2019-03-29 14:10:27 -07:00
Jacques Pienaar 17b8105761 Fix typo.
Tensor has as element type a tensor-memref-element-type rather than a vector-element-type.

PiperOrigin-RevId: 223062135
2019-03-29 14:10:12 -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
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 8c903a3c9d Update LangRef to reflect int/flaot attribute specification changes.
PiperOrigin-RevId: 221802835
2019-03-29 14:00:23 -07:00
Chris Lattner a30f7ec74f Fix some minor typos pointed out by rxwei
PiperOrigin-RevId: 221474217
2019-03-29 13:57:31 -07:00
Jacques Pienaar fb4b74ccb3 Mark mlir code snippets as being written in mlir
Forgot to add these in previous change :/

PiperOrigin-RevId: 221444322
2019-03-29 13:57:16 -07:00
Jacques Pienaar b1f7e03add Mark mlir code snippets as being written in mlir
Basic MLIR syntax highlighting is supported so use it.

PiperOrigin-RevId: 221443618
2019-03-29 13:57:02 -07:00
Alex Zinenko cab24dc211 Homogenize branch instruction arguments.
Branch instruction arguments were defined and used inconsistently across
different instructions, in both the spec and the implementation.  In
particular, conditional and unconditional branch instructions were using
different syntax in the implementation.  This led to the IR we produce not
being accepted by the parser. Update the printer to use common syntax: `(`
list-of-SSA-uses `:` list-of-types `)`.  The motivation for choosing this
syntax as opposed to the one in the spec, `(` list-of-SSA-uses `)` `:`
list-of-types is double-fold.  First, it is tricky to differentiate the label
of the false branch from the type while parsing conditional branches (which is
what apparently motivated the implementation to diverge from the spec in the
first place).  Second, the ongoing convergence between terminator instructions
and other operations prompts for consistency between their operand list syntax.
After this change, the only remaining difference between the two is the use of
parentheses.  Update the comment of the parser that did not correspond to the
code.  Remove the unused isParenthesized argument from parseSSAUseAndTypeList.

Update the spec accordingly.  Note that the examples in the spec were _not_
using the EBNF defined a couple of lines above them, but were using the current
syntax.  Add a supplementary example of a branch to a basic block with multiple
arguments.

PiperOrigin-RevId: 221162655
2019-03-29 13:55:36 -07:00
MLIR Team b2f77e1b8f Change the index upper bound for the outer-loop as the comment says the array has 8 rows.
PiperOrigin-RevId: 221082461
2019-03-29 13:54:53 -07:00
Chris Lattner 86a5323f04 - Simplify PatternMatch to *require* static benefits at pattern construction
time.  The "Fast and Flexible Instruction Selection With Constraints" paper
  from CC2018 makes a credible argument that dynamic costs aren't actually
  necessary/important, and we are not using them.

- Check in my "MLIR Generic DAG Rewriter Infrastructure" design doc into the
  source tree.

PiperOrigin-RevId: 221017546
2019-03-29 13:54:38 -07:00
Chris Lattner d469a5d675 Add the "MLIR: Incremental Application to TensorFlow Graph Algorithms" document
I wrote last weekend.

PiperOrigin-RevId: 221017318
2019-03-29 13:54:24 -07:00
Alex Zinenko 846e48d16f Allow vector types to have index elements.
It is unclear why vector types were not allowed to have "index" as element
type.  Index values are integers, although of unknown bit width, and should
behave as such.  Vectors of integers are allowed and so are tensors of indices
(for indirection purposes), it is more consistent to also have vectors of
indices.

PiperOrigin-RevId: 220630123
2019-03-29 13:51:33 -07:00
Alex Zinenko ac2a655e87 Enable arithmetics for index types.
Arithmetic and comparison instructions are necessary to implement, e.g.,
control flow when lowering MLFunctions to CFGFunctions.  (While it is possible
to replace some of the arithmetics by affine_apply instructions for loop
bounds, it is still necessary for loop bounds checking, steps, if-conditions,
non-trivial memref subscripts, etc.)  Furthermore, working with indirect
accesses in, e.g., lookup tables for large embeddings, may require operating on
tensors of indexes.  For example, the equivalents to C code "LUT[Index[i]]" or
"ResultIndex[i] = i + j" where i, j are loop induction variables require the
arithmetics on indices as well as the possibility to operate on tensors
thereof.  Allow arithmetic and comparison operations to apply to index types by
declaring them integer-like.  Allow tensors whose element type is index for
indirection purposes.

The absence of vectors with "index" element type is explicitly tested, but the
only justification for this restriction in the CL introducing the test is
"because we don't need them".  Do NOT enable vectors of index types, although
it makes vector and tensor types inconsistent with respect to allowed element
types.

PiperOrigin-RevId: 220614055
2019-03-29 13:51:19 -07:00
Alex Zinenko 3a38a5d0d6 Introduce integer comparison operation.
This binary operation is applicable to integers, vectors and tensors thereof
similarly to binary arithmetic operations.  The operand types must match
exactly, and the shape of the result type is the same as that of the operands.
The element type of the result is always i1.  The kind of the comparison is
defined by the "predicate" integer attribute.  This attribute requests one of:
- equals to;
- not equals to;
- signed less than;
- signed less than or equals;
- signed greater than;
- signed greater than or equals;
- unsigned less than;
- unsigned less than or equals;
- unsigned greater than;
- unsigned greater than or equals.
Since integer values themselves do not have a sign, the comparison operator
specifies whether to use signed or unsigned comparison logic, i.e. whether to
interpret values where the foremost bit is set as negatives expressed as two's
complements or as positive values.  For non-scalar operands, pairwise
per-element comparison is performed.  Comparison operators on scalars are
necessary to implement basic control flow with conditional branches.

PiperOrigin-RevId: 220613566
2019-03-29 13:50:49 -07:00
MLIR Team 710b20aeb1 Fix formatting of mlir snippet.
PiperOrigin-RevId: 219535523
2019-03-29 13:46:36 -07:00
Chris Lattner a10cd107de Introduce a common base class (IROperandOwner) between Instruction and
Statement, which paves the way to make SSAValue's have a useful owner
available, which will allow subsequent patches to improve their use/def
chains.

While I'm poking at this, shrink sizeof(Instruction) and sizeof(Statement) by a
word by packing the kind and location together into a single PointerIntPair.

NFC.

PiperOrigin-RevId: 218959651
2019-03-29 13:42:32 -07:00
Chris Lattner 967d934180 Fix two issues:
1) We incorrectly reassociated non-reassociative operations like subi, causing
    miscompilations.
 2) When constant folding, we didn't add users of the new constant back to the
    worklist for reprocessing, causing us to miss some cases (pointed out by
    Uday).

The code for tensorflow/mlir#2 is gross, but I'll add the new APIs in a followup patch.

PiperOrigin-RevId: 218803984
2019-03-29 13:40:35 -07:00
Chris Lattner 144795e35c Add a doc explaining our approach to canonicalization, which is more of a
framework than a useful doc at this point.

PiperOrigin-RevId: 218737032
2019-03-29 13:38:38 -07:00
Alex Zinenko e8d254b909 Rename shape_cast to tensor_cast.
"shape_cast" only applies to tensors, and there are other operations that
actually affect shape, for example "reshape".  Rename "shape_cast" to
"tensor_cast" in both the code and the documentation.

PiperOrigin-RevId: 218528122
2019-03-29 13:37:41 -07:00
Alex Zinenko c1b0918617 Add MLIR Rationale converted to g3doc.
This CL only converts the document to the g3doc format and does some minor
typesetting, e.g. removing unicode ellipsis and mdash symbols, replace single
quotes with backticks to trigger tt-type dispay, etc.  The original document
is located at
https://docs.google.com/document/d/1KoVYgp-m-dgAyKwqRne2c72j0FoxpsdNgfa9DTfWGgw/view
Links to the sections of the same document are updated to point to the anchors
in the converted document whereas links to external documents are kept as is.
Cross-links between LangRef.md and Rationale.md are updated to point to the
relevant anchors in the g3doc files.

PiperOrigin-RevId: 218527560
2019-03-29 13:37:27 -07:00
Alex Zinenko 1321f6affd Add MLIR specification.
PiperOrigin-RevId: 218527452
2019-03-29 13:37:13 -07:00