platform/upstream/llvm.git
5 years agoDocument the conversion into the LLVM IR dialect
Alex Zinenko [Fri, 22 Feb 2019 15:45:55 +0000 (07:45 -0800)]
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

5 years agoAdd a test example of calling a builtin function.
Brian Patton [Fri, 22 Feb 2019 09:02:24 +0000 (01:02 -0800)]
Add a test example of calling a builtin function.

PiperOrigin-RevId: 235149430

5 years agoAdd documentation for the LLVM IR dialect
Alex Zinenko [Fri, 22 Feb 2019 09:00:25 +0000 (01:00 -0800)]
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

5 years agoDefine a PassID class to use when defining a pass. This allows for the type used...
River Riddle [Fri, 22 Feb 2019 02:01:09 +0000 (18:01 -0800)]
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

5 years agoLower standard DivF and RemF operations to the LLVM IR dialect
Alex Zinenko [Thu, 21 Feb 2019 14:30:53 +0000 (06:30 -0800)]
Lower standard DivF and RemF operations to the LLVM IR dialect

Add support for lowering DivF and RemF to LLVM::FDiv and LLMV::FRem
respectively.  The lowering is a trivial one-to-one transformation.
The corresponding operations already existed in the LLVM IR dialect and can be
lowered to the LLVM IR proper.  Add the necessary tests for scalar and vector
forms.

PiperOrigin-RevId: 234984608

5 years agoExposed division and remainder operations in EDSC
Sergei Lebedev [Thu, 21 Feb 2019 11:09:51 +0000 (03:09 -0800)]
Exposed division and remainder operations in EDSC

This change introduces three new operators in EDSC: Div (also exposed
via Expr.__div__ aka /) -- floating-point division, FloorDiv and CeilDiv
for flooring/ceiling index division.

The lowering to LLVM will be implemented in b/124872679.

PiperOrigin-RevId: 234963217

5 years agoEDSC: support call instructions
Alex Zinenko [Thu, 21 Feb 2019 10:36:51 +0000 (02:36 -0800)]
EDSC: support call instructions

Introduce support for binding MLIR functions as constant expressions.  Standard
constant operation supports functions as possible constant values.

Provide C APIs to look up existing named functions in an MLIR module and expose
them to the Python bindings.  Provide Python bindings to declare a function in
an MLIR module without defining it and to add a definition given a function
declaration.  These declarations are useful when attempting to link MLIR
modules with, e.g., the standard library.

Introduce EDSC support for direct and indirect calls to other MLIR functions.
Internally, an indirect call is always emitted to leverage existing support for
delayed construction of MLIR Values using EDSC Exprs.  If the expression is
bound to a constant function (looked up or declared beforehand), MLIR constant
folding will be able to replace an indirect call by a direct call.  Currently,
only zero- and one-result functions are supported since we don't have support
for multi-valued expressions in EDSC.

Expose function calling interface to Python bindings on expressions by defining
a `__call__` function accepting a variable number of arguments.

PiperOrigin-RevId: 234959444

5 years agoUpdate / cleanup pass documentation + Langref alloc examples
Uday Bondhugula [Wed, 20 Feb 2019 22:12:21 +0000 (14:12 -0800)]
Update / cleanup pass documentation + Langref alloc examples

PiperOrigin-RevId: 234866323

5 years agoFix unused errors in opt build.
Jacques Pienaar [Wed, 20 Feb 2019 20:01:42 +0000 (12:01 -0800)]
Fix unused errors in opt build.

PiperOrigin-RevId: 234841678

5 years agoPrint debug message better + switch a dma-generate cl opt to uint64_t
Uday Bondhugula [Wed, 20 Feb 2019 19:54:35 +0000 (11:54 -0800)]
Print debug message better + switch a dma-generate cl opt to uint64_t

PiperOrigin-RevId: 234840316

5 years agoFix for getMemRefSizeInBytes: unsigned -> uint64_t
Uday Bondhugula [Wed, 20 Feb 2019 19:02:25 +0000 (11:02 -0800)]
Fix for getMemRefSizeInBytes: unsigned -> uint64_t

PiperOrigin-RevId: 234829637

5 years agoCreate OpTrait base class & allow operation predicate OpTraits.
Jacques Pienaar [Wed, 20 Feb 2019 18:50:26 +0000 (10:50 -0800)]
Create OpTrait base class & allow operation predicate OpTraits.

* Introduce a OpTrait class in C++ to wrap the TableGen definition;
* Introduce PredOpTrait and rename previous usage of OpTrait to NativeOpTrait;
* PredOpTrait allows specifying a trait of the operation by way of predicate on the operation. This will be used in future to create reusable set of trait building blocks in the definition of operations. E.g., indicating whether to operands have the same type and allowing locally documenting op requirements by trait composition.
  - Some of these building blocks could later evolve into known fixed set as LLVMs backends do, but that can be considered with more data.
* Use the modelling to address one verify TODO in a very local manner.

This subsumes the current custom verify specification which will be removed in a separate mechanical CL.

PiperOrigin-RevId: 234827169

5 years agoAdding -mlir-print-internal-attributes to print attributes with ':' prefixes.
Ben Vanik [Wed, 20 Feb 2019 17:22:56 +0000 (09:22 -0800)]
Adding -mlir-print-internal-attributes to print attributes with ':' prefixes.
This enables lit testing of passes that add internal attributes.

PiperOrigin-RevId: 234809949

5 years agoAllow Builder to create function-type constants
Alex Zinenko [Wed, 20 Feb 2019 16:08:16 +0000 (08:08 -0800)]
Allow Builder to create function-type constants

A recent change made ConstantOp::build accept a NumericAttr or assert that a
generic Attribute is in fact a NumericAttr.  The rationale behind the change
was that NumericAttrs have a type that can be used as the result type of the
constant operation.  FunctionAttr also has a type, and it is valid to construct
function-typed constants as exercised by the parser.mlir test.  Relax
ConstantOp::build back to take a generic Attribute.  In the overload that only
takes an attribute, assert that the Attribute is either a NumericAttr or a
FunctionAttr, because it is necessary to extract the type.  In the overload
that takes both type type and the attribute, delegate the attribute type
checking to ConstantOp::verify to prevent non-Builder-based Op construction
mechanisms from creating invalid IR.
PiperOrigin-RevId: 234798569

5 years agoEDSC: emit composed affine maps again
Alex Zinenko [Wed, 20 Feb 2019 15:08:50 +0000 (07:08 -0800)]
EDSC: emit composed affine maps again

The recent rework of MLIREmitter switched to using the generic call to
`builder.createOperation` from OperationState instead of individual customized
calls to `builder.create<>`.  As a result, regular non-composed affine apply
operations where emitted.  Introduce a special case in Expr::build to always
create composed affine maps instead, as it used to be the case before the
rework.

Such special-casing goes against the idea of EDSC generality and extensibility.
Instead, we should consider declaring the composed form canonical for
affine.apply operations and using the builder support for creating operations
and canonicalizing them immediately (ongoing effort).

PiperOrigin-RevId: 234790129

5 years agoEDSC: introduce min/max only usable inside for upper/lower bounds of a loop
Alex Zinenko [Wed, 20 Feb 2019 14:54:53 +0000 (06:54 -0800)]
EDSC: introduce min/max only usable inside for upper/lower bounds of a loop

Introduce a type-safe way of building a 'for' loop with max/min bounds in EDSC.
Define new types MaxExpr and MinExpr in C++ EDSC API and expose them to Python
bindings.  Use values of these type to construct 'for' loops with max/min in
newly introduced overloads of the `edsc::For` factory function.  Note that in C
APIs, we still must expose MaxMinFor as a different function because C has no
overloads.  Also note that MaxExpr and MinExpr do _not_ derive from Expr
because they are not allowed to be used in a regular Expr context (which may
produce `affine.apply` instructions not expecting `min` or `max`).

Factory functions `Min` and `Max` in Python can be further overloaded to
produce chains of comparisons and selects on non-index types.  This is not
trivial in C++ since overloaded functions cannot differ by the return type only
(`MaxExpr` or `Expr`) and making `MaxExpr` derive from `Expr` defies the
purpose of type-safe construction.

PiperOrigin-RevId: 234786131

5 years agoEDSC: support multi-expression loop bounds
Alex Zinenko [Wed, 20 Feb 2019 14:54:36 +0000 (06:54 -0800)]
EDSC: support multi-expression loop bounds

MLIR supports 'for' loops with lower(upper) bound defined by taking a
maximum(minimum) of a list of expressions, but does not have first-class affine
constructs for the maximum(minimum).  All these expressions must have affine
provenance, similarly to a single-expression bound.  Add support for
constructing such loops using EDSC.  The expression factory function is called
`edsc::MaxMinFor` to (1) highlight that the maximum(minimum) operation is
applied to the lower(upper) bound expressions and (2) differentiate it from a
`edsc::For` that creates multiple perfectly nested loops (and should arguably
be called `edsc::ForNest`).

PiperOrigin-RevId: 234785996

5 years agoEDSC: create constants as expressions
Alex Zinenko [Wed, 20 Feb 2019 09:54:07 +0000 (01:54 -0800)]
EDSC: create constants as expressions

Introduce a functionality to create EDSC expressions from typed constants.
This complements the current functionality that uses "unbound" expressions and
binds them to a specific constant before emission.  It comes in handy in cases
where we want to check if something is a constant early during construciton
rather than late during emission, for example multiplications and divisions in
affine expressions.  This is also consistent with MLIR vision of constants
being defined by an operation (rather than being special kinds of values in the
IR) by exposing this operation as EDSC expression.

PiperOrigin-RevId: 234758020

5 years ago[EDSC] Fix Stmt::operator= and allow DimOp in For loops
Nicolas Vasilache [Wed, 20 Feb 2019 08:41:42 +0000 (00:41 -0800)]
[EDSC] Fix Stmt::operator= and allow DimOp in For loops

This CL fixes 2 recent issues with EDSCs:
1. the type of the LHS in Stmt::operator=(Expr rhs) should be the same as the (asserted unique) return type;
2. symbols coming from DimOp should be admissible as lower / upper bounds in For

The relevant tests are added.

PiperOrigin-RevId: 234750249

5 years agoExtend/improve getSliceBounds() / complete TODO + update unionBoundingBox
Uday Bondhugula [Wed, 20 Feb 2019 02:17:19 +0000 (18:17 -0800)]
Extend/improve getSliceBounds() / complete TODO + update unionBoundingBox

- compute slices precisely where the destination iteration depends on multiple source
  iterations (instead of over-approximating to the whole source loop extent)
- update unionBoundingBox to deal with input with non-matching symbols
- reenable disabled backend test case

PiperOrigin-RevId: 234714069

5 years agoNFC: Refactor the files related to passes.
River Riddle [Wed, 20 Feb 2019 01:17:46 +0000 (17:17 -0800)]
NFC: Refactor the files related to passes.

* PassRegistry is split into its own source file.
* Pass related files are moved to a new library 'Pass'.

PiperOrigin-RevId: 234705771

5 years agoDMA placement update - hoist loops invariant DMAs
Uday Bondhugula [Tue, 19 Feb 2019 18:33:41 +0000 (10:33 -0800)]
DMA placement update - hoist loops invariant DMAs

- hoist DMAs past all loops immediately surrounding the region that the latter
  is invariant on - do this at DMA generation time itself

PiperOrigin-RevId: 234628447

5 years ago[EDSC] Remove dead code in MLIREmitter.cpp
Nicolas Vasilache [Tue, 19 Feb 2019 18:27:04 +0000 (10:27 -0800)]
[EDSC] Remove dead code in MLIREmitter.cpp

cl/234609882 made EDSCs typed on construction (instead of typed on emission).
This CL cleans up some leftover dead code.

PiperOrigin-RevId: 234627105

5 years agoUpdate pass documentation + improve/fix some comments
Uday Bondhugula [Tue, 19 Feb 2019 18:26:53 +0000 (10:26 -0800)]
Update pass documentation + improve/fix some comments

- add documentation for passes
- improve / fix outdated doc comments

PiperOrigin-RevId: 234627076

5 years agoAdd a generic pattern matcher for matching constant values produced by an operation...
River Riddle [Tue, 19 Feb 2019 17:33:11 +0000 (09:33 -0800)]
Add a generic pattern matcher for matching constant values produced by an operation with zero operands and a single result.

PiperOrigin-RevId: 234616691

5 years agoEDSC: clean up type casting mechanism
Alex Zinenko [Tue, 19 Feb 2019 17:08:59 +0000 (09:08 -0800)]
EDSC: clean up type casting mechanism

Originally, edsc::Expr had a long enum edsc::ExprKind with all supported types
of operations.  Recent Expr extensibility support removed the need to specify
supported types in advance.  Replace the no-longer-used blocks of enum values
reserved for unary/binary/ternary/variadic expressions with simple values (it
is still useful to know if an expression is, e.g., binary to access it through
a simpler API).

Furthermore, wrap string-comparison now used to identify specific ops into an
`Expr::is_op<>` function template, that acts similarly to `Instruction::isa<>`.
Introduce `{Unary,Binary,Ternary,Variadic}Expr::make<> ` function template that
creates a Expression emitting the MLIR Op specified as template argument.

PiperOrigin-RevId: 234612916

5 years agoEDSC: make Expr typed and extensible
Alex Zinenko [Tue, 19 Feb 2019 16:51:52 +0000 (08:51 -0800)]
EDSC: make Expr typed and extensible

Expose the result types of edsc::Expr, which are now stored for all types of
Exprs and not only for the variadic ones.  Require return types when an Expr is
constructed, if it will ever have some.  An empty return type list is
interpreted as an Expr that does not create a value (e.g. `return` or `store`).

Conceptually, all edss::Exprs are now typed, with the type being a (potentially
empty) tuple of return types.  Unbound expressions and Bindables must now be
constructed with a specific type they will take.  This makes EDSC less
evidently type-polymorphic, but we can still write generic code such as

    Expr sumOfSquares(Expr lhs, Expr rhs) { return lhs * lhs + rhs * rhs; }

and use it to construct different typed expressions as

    sumOfSquares(Bindable(IndexType::get(ctx)), Bindable(IndexType::get(ctx)));
    sumOfSquares(Bindable(FloatType::getF32(ctx)),
                 Bindable(FloatType::getF32(ctx)));

On the positive side, we get the following.
1. We can now perform type checking when constructing Exprs rather than during
   MLIR emission.  Nevertheless, this is still duplicates the Op::verify()
   until we can factor out type checking from that.
2. MLIREmitter is significantly simplified.
3. ExprKind enum is only used for actual kinds of expressions.  Data structures
   are converging with AbstractOperation, and the users can now create a
   VariadicExpr("canonical_op_name", {types}, {exprs}) for any operation, even
   an unregistered one without having to extend the enum and make pervasive
   changes to EDSCs.

On the negative side, we get the following.
1. Typed bindables are more verbose, even in Python.
2. We lose the ability to do print debugging for higher-level EDSC abstractions
   that are implemented as multiple MLIR Ops, for example logical disjunction.

This is the step 2/n towards making EDSC extensible.

***

Move MLIR Op construction from MLIREmitter::emitExpr to Expr::build since Expr
now has sufficient information to build itself.

This is the step 3/n towards making EDSC extensible.

Both of these strive to minimize the amount of irrelevant changes.  In
particular, this introduces more complex pretty-printing for affine and binary
expression to make sure tests continue to pass.  It also relies on string
comparison to identify specific operations that an Expr produces.

PiperOrigin-RevId: 234609882

5 years ago[TableGen] Support using Variadic<Type> in results
Lei Zhang [Tue, 19 Feb 2019 15:15:59 +0000 (07:15 -0800)]
[TableGen] Support using Variadic<Type> in results

This CL extended TableGen Operator class to provide accessors for information on op
results.

In OpDefinitionGen, added checks to make sure only the last result can be variadic,
and adjusted traits and builders generation to consider variadic results.

PiperOrigin-RevId: 234596124

5 years agoEDSC: introduce support for blocks
Alex Zinenko [Tue, 19 Feb 2019 08:53:16 +0000 (00:53 -0800)]
EDSC: introduce support for blocks

EDSC currently implement a block as a statement that is itself a list of
statements.  This suffers from two modeling problems: (1) these blocks are not
addressable, i.e. one cannot create an instruction where thus constructed block
is a successor; (2) they support block nesting, which is not supported by MLIR
blocks.  Furthermore, emitting such "compound statement" (misleadingly named
`Block` in Python bindings) does not actually produce a new Block in the IR.

Implement support for creating actual IR Blocks in EDSC.  In particular, define
a new StmtBlock EDSC class that is neither an Expr nor a Stmt but contains a
list of Stmts.  Additionally, StmtBlock may have (early-) typed arguments.
These arguments are Bindable expressions that can be used inside the block.
Provide two calls in the MLIREmitter, `emitBlock` that actually emits a new
block and `emitBlockBody` that only emits the instructions contained in the
block without creating a new block.  In the latter case, the instructions must
not use block arguments.

Update Python bindings to make it clear when instruction emission happens
without creating a new block.

PiperOrigin-RevId: 234556474

5 years ago[TableGen] Fix discrepancy between parameter meaning and code logic
Lei Zhang [Mon, 18 Feb 2019 15:21:12 +0000 (07:21 -0800)]
[TableGen] Fix discrepancy between parameter meaning and code logic

The parameter to emitStandaloneParamBuilder() was renamed from hasResultType to
isAllSameType, which is the opposite boolean value. The logic should be changed
to make them consistent.

Also re-ordered some methods in Operator. And few other tiny improvements.

PiperOrigin-RevId: 234478316

5 years agoMisc. updates/fixes to analysis utils used for DMA generation; update DMA
Uday Bondhugula [Sat, 16 Feb 2019 01:54:49 +0000 (17:54 -0800)]
Misc. updates/fixes to analysis utils used for DMA generation; update DMA
generation pass to make it drop certain assumptions, complete TODOs.

- multiple fixes for getMemoryFootprintBytes
  - pass loopDepth correctly from getMemoryFootprintBytes()
  - use union while computing memory footprints

- bug fixes for addAffineForOpDomain
  - take into account loop step
  - add domains of other loop IVs in turn that might have been used in the bounds

- dma-generate: drop assumption of "non-unit stride loops being tile space loops
  and skipping those and recursing to inner depths"; DMA generation is now purely
  based on available fast mem capacity and memory footprint's calculated

- handle memory region compute failures/bailouts correctly from dma-generate

- loop tiling cleanup/NFC

- update some debug and error messages to use emitNote/emitError in
  pipeline-data-transfer pass - NFC

PiperOrigin-RevId: 234245969

5 years agoSupport fusing producer loop nests which write to a memref which is live out, provide...
MLIR Team [Sat, 16 Feb 2019 01:12:19 +0000 (17:12 -0800)]
Support fusing producer loop nests which write to a memref which is live out, provided that the write region of the consumer loop nest to the same memref is a super set of the producer's write region.

PiperOrigin-RevId: 234240958

5 years agoEDSC: properly construct FunctionTypes
Alex Zinenko [Fri, 15 Feb 2019 19:07:23 +0000 (11:07 -0800)]
EDSC: properly construct FunctionTypes

The existing implementation of makeFunctionType in EDSC contains a bug: the
array of input types is overwritten using output types passed as arguments and
the array of output types is never filled in.  This leads to all sorts of
incorrect memory behavior.  Fill in the array of output types using the proper
argument.

PiperOrigin-RevId: 234177221

5 years agoExecutionEngine: provide utils for running CLI-configured LLVM passes
Alex Zinenko [Fri, 15 Feb 2019 18:50:28 +0000 (10:50 -0800)]
ExecutionEngine: provide utils for running CLI-configured LLVM passes

A recent change introduced a possibility to run LLVM IR transformation during
JIT-compilation in the ExecutionEngine.  Provide helper functions that
construct IR transformers given either clang-style optimization levels or a
list passes to run.  The latter wraps the LLVM command line option parser to
parse strings rather than actual command line arguments.  As a result, we can
run either of

    mlir-cpu-runner -O3 input.mlir
    mlir-cpu-runner -some-mlir-pass -llvm-opts="-llvm-pass -other-llvm-pass"

to combine different transformations.  The transformer builder functions are
provided as a separate library that depends on LLVM pass libraries unlike the
main execution engine library.  The library can be used for integrating MLIR
execution engine into external frameworks.

PiperOrigin-RevId: 234173493

5 years agoLoopFusion: perform a series of loop interchanges to increase the loop depth at which...
MLIR Team [Fri, 15 Feb 2019 17:32:18 +0000 (09:32 -0800)]
LoopFusion: perform a series of loop interchanges to increase the loop depth at which slices of producer loop nests can be fused into constumer loop nests.
*) Adds utility to LoopUtils to perform loop interchange of two AffineForOps.
*) Adds utility to LoopUtils to sink a loop to a specified depth within a loop nest, using a series of loop interchanges.
*) Computes dependences between all loads and stores in the loop nest, and classifies each loop as parallel or sequential.
*) Computes loop interchange permutation required to sink sequential loops (and raise parallel loop nests) while preserving relative order among them.
*) Checks each dependence against the permutation to make sure that dependences would not be violated by the loop interchange transformation.
*) Calls loop interchange in LoopFusion pass on consumer loop nests before fusing in producers, sinking loops with loop carried dependences deeper into the consumer loop nest.
*) Adds and updates related unit tests.

PiperOrigin-RevId: 234158370

5 years ago[TableGen] Rename Operand to Value to prepare sharing between operand and result
Lei Zhang [Fri, 15 Feb 2019 17:01:05 +0000 (09:01 -0800)]
[TableGen] Rename Operand to Value to prepare sharing between operand and result

We specify op operands and results in TableGen op definition using the same syntax.
They should be modelled similarly in TableGen driver wrapper classes.

PiperOrigin-RevId: 234153332

5 years agoLLVM dialect conversion and target: support indirect calls
Alex Zinenko [Fri, 15 Feb 2019 14:25:30 +0000 (06:25 -0800)]
LLVM dialect conversion and target: support indirect calls

Add support for converting MLIR `call_indirect` instructions to the LLVM IR
dialect.  In LLVM IR, the same instruction is used for direct and indirect
calls.  In the dialect, we have `llvm.call` and `llvm.call0` to work around the
absence of the void type in MLIR.  For direct calls, the callee is stored as
instruction attribute.  Use the same pair of instructions for indirect calls by
omitting the callee attribute.  In the MLIR to LLVM IR translator, check the
presence of attribute to decide whether to construct a direct or an indirect
call using different LLVM IR Builder functions.

Add support for converting constants of function type to the LLVM IR dialect
and for translating them to the LLVM IR proper.  The `llvm.constant` operation
works similarly to other types: its attribute has MLIR function type but the
value it produces has LLVM IR function type wrapped in the dialect type.  While
lowering, look up the pointer to the converted function in the corresponding
mapping.

PiperOrigin-RevId: 234132351

5 years agoDialect conversion: decouple function signature conversion from type conversion
Alex Zinenko [Fri, 15 Feb 2019 13:06:15 +0000 (05:06 -0800)]
Dialect conversion: decouple function signature conversion from type conversion

Function types are built-in in MLIR and affect the validity of the IR itself.
However, advanced target dialects such as the LLVM IR dialect may include
custom function types.  Until now, dialect conversion was expecting function
types not to be converted to the custom type: although the signatures was
allowed to change, the outer type must have been an mlir::FunctionType.  This
effectively prevented dialect conversion from creating instructions that
operate on values of the custom function type.

Dissociate function signature conversion from general type conversion.
Function signature conversion must still produce an mlir::FunctionType and is
used in places where built-in types are required to make IR valid.  General
type conversion is used for SSA values, including function and block arguments
and function results.

Exercise this behavior in the LLVM IR dialect conversion by converting function
types to LLVM IR function pointer types.  The pointer to a function is chosen
to provide consistent lowering of higher-order functions: while it is possible
to have a value of function type, it is not possible to create a function type
accepting a returning another function type.

PiperOrigin-RevId: 234124494

5 years agoUpdate direction vector computation to use FlatAffineConstraints::getLower/UpperBounds.
MLIR Team [Thu, 14 Feb 2019 21:25:46 +0000 (13:25 -0800)]
Update direction vector computation to use FlatAffineConstraints::getLower/UpperBounds.
Update FlatAffineConstraints::getLower/UpperBounds to project to the identifier for which bounds are being computed. This change enables computing bounds on an identifier which were previously dependent on the bounds of another identifier.

PiperOrigin-RevId: 234017514

5 years agoAdd -tile-sizes command line option for loop tiling; clean up cl options for
Uday Bondhugula [Thu, 14 Feb 2019 20:24:18 +0000 (12:24 -0800)]
Add -tile-sizes command line option for loop tiling; clean up cl options for
for dma-generate, loop-unroll.

- add -tile-sizes command line option for loop tiling to specify different tile
  sizes for loops in a band

- clean up command line options for loop-unroll, dma-generate (remove
  cl::hidden)

PiperOrigin-RevId: 234006232

5 years ago[TFLite] Fuse AddOp into preceding convolution ops
Lei Zhang [Thu, 14 Feb 2019 19:01:08 +0000 (11:01 -0800)]
[TFLite] Fuse AddOp into preceding convolution ops

If we see an add op adding a constant value to a convolution op with constant
bias, we can fuse the add into the convolution op by constant folding the
bias and the add op's constant operand.

This CL also removes dangling RewriterGen check that prevents us from using
nested DAG nodes in result patterns, which is already supported.

PiperOrigin-RevId: 233989654

5 years ago[TableGen] Use deduced result types for build() of suitable ops
Lei Zhang [Thu, 14 Feb 2019 18:54:50 +0000 (10:54 -0800)]
[TableGen] Use deduced result types for build() of suitable ops

For ops with the SameOperandsAndResultType trait, we know that all result types
should be the same as the first operand's type. So we can generate a build()
method without requiring result types as parameters and also invoke this method
when constructing such ops during expanding rewrite patterns.

Similarly for ops have broadcast behavior, we can define build() method to use
the deduced type as the result type. So we can also calling into this build()
method when constructing ops in RewriterGen.

PiperOrigin-RevId: 233988307

5 years agoEDSC: fix unused-wariable warning when compiling without assertions
Alex Zinenko [Thu, 14 Feb 2019 13:18:18 +0000 (05:18 -0800)]
EDSC: fix unused-wariable warning when compiling without assertions

In LowerEDSCTestPass, there are two range-for loops that only do assertions on
the loop variable.  With assertions disabled, the variable becomes unused and
triggers a warning promoted to error.  Cast it to void in the loop to supress
the warning.

PiperOrigin-RevId: 233936171

5 years agoReimplement LLVM IR translation to use the MLIR LLVM IR dialect
Alex Zinenko [Wed, 13 Feb 2019 23:30:24 +0000 (15:30 -0800)]
Reimplement LLVM IR translation to use the MLIR LLVM IR dialect

Original implementation of the translation from MLIR to LLVM IR operated on the
Standard+BuiltIn dialect, with a later addition of the SuperVector dialect.
This required the translation to be aware of a potetially large number of other
dialects as the infrastructure extended.  With the recent introduction of the
LLVM IR dialect into MLIR, the translation can be switched to only translate
the LLVM IR dialect, and the translation of the operations becomes largely
mechanical.

The reimplementation of the translator follows the lines of the original
translator in function and basic block conversion.  In particular, block
arguments are converted to LLVM IR PHI nodes, which are connected to their
sources after all blocks of a function had been converted.  Thanks to LLVM IR
types being wrapped in the MLIR LLVM dialect type, type conversion is
simplified to only convert function types, all other types are simply
unwrapped.  Individual instructions are constructed using the LLVM IRBuilder,
which has a great potential for being table-generated from the LLVM IR dialect
operation definitions.

The input of the test/Target/llvmir.mlir is updated to use the MLIR LLVM IR
dialect.  While it is now redundant with the dialect conversion test, the point
of the exercise is to guarantee exactly the same LLVM IR is emitted.  (Only the
name of the allocation function is changed from `__mlir_alloc` to `alloc` in
the CHECK lines.)  It will be simplified in a follow-up commit.

PiperOrigin-RevId: 233842306

5 years agoAdd pattern constraints.
Jacques Pienaar [Wed, 13 Feb 2019 22:30:40 +0000 (14:30 -0800)]
Add pattern constraints.

Enable matching pattern only if constraint is met. Start with type constraints and more general C++ constraints.

PiperOrigin-RevId: 233830768

5 years agoEDSC: unify Expr storage
Alex Zinenko [Wed, 13 Feb 2019 08:54:55 +0000 (00:54 -0800)]
EDSC: unify Expr storage

EDSC expressions evolved to have different types of underlying storage.
Separate classes are used for unary, binary, ternary and variadic expressions.
The latter covers all the needs of the three special cases.  Remove these
special cases and use a single ExprStorage class everywhere while maintaining
the same APIs at the Expr level (ExprStorage is an internal implementation
class).

This is step 1/n to converging EDSC expressions and Ops and making EDSCs
support custom operations.

PiperOrigin-RevId: 233704912

5 years agoLLVM IR Dialect: port DimOp lowering from the translator
Alex Zinenko [Tue, 12 Feb 2019 21:47:25 +0000 (13:47 -0800)]
LLVM IR Dialect: port DimOp lowering from the translator

DimOp is converted to a constant LLVM IR dialect operation for static
dimensions and to an access to the dynamic size info stored in the memref
descriptor for the dynamic dimensions.  This behavior is consistent with the
existing mlir-translator.

This completes the porting of MLIR -> LLVM lowering to the dialect conversion
infrastructure.

PiperOrigin-RevId: 233665634

5 years agoAdd langref descriptions for the attribute values supported in MLIR.
River Riddle [Tue, 12 Feb 2019 20:55:40 +0000 (12:55 -0800)]
Add langref descriptions for the attribute values supported in MLIR.

PiperOrigin-RevId: 233661338

5 years agoGenerate dealloc's for alloc's of pipeline-data-transfer
Uday Bondhugula [Tue, 12 Feb 2019 20:08:01 +0000 (12:08 -0800)]
Generate dealloc's for alloc's of pipeline-data-transfer

- for the DMA transfers being pipelined through double buffering, generate
  deallocs for the double buffers being alloc'ed

This change is along the lines of cl/233502632. We initially wanted to experiment with
scoped allocation - so the deallocation's were usually not necessary; however, they are
needed even with scoped allocations in some situations - for eg. when the enclosing loop
gets unrolled. The dealloc serves as an end of lifetime marker.

PiperOrigin-RevId: 233653463

5 years agoMake IndexType a standard type instead of a builtin. This also cleans up some unneces...
River Riddle [Tue, 12 Feb 2019 19:08:04 +0000 (11:08 -0800)]
Make IndexType a standard type instead of a builtin. This also cleans up some unnecessary factory methods on the Type class.

PiperOrigin-RevId: 233640730

5 years agoLLVM IR Dialect: add select op and lower standard select to it
Alex Zinenko [Tue, 12 Feb 2019 17:31:20 +0000 (09:31 -0800)]
LLVM IR Dialect: add select op and lower standard select to it

This is a similar one-to-one mapping.

PiperOrigin-RevId: 233621006

5 years agoEDSC: move Expr and Stmt construction operators to a namespace
Alex Zinenko [Tue, 12 Feb 2019 11:39:24 +0000 (03:39 -0800)]
EDSC: move Expr and Stmt construction operators to a namespace

In the current state, edsc::Expr and edsc::Stmt overload operators to construct
other Exprs and Stmts.  This includes some unconventional overloads of the
`operator==` to create a comparison expression and of the `operator!` to create
a negation expression.  This situation could lead to unpleasant surprises where
the code does not behave like expected.  Make all Expr and Stmt construction
operators free functions and move them to the `edsc::op` namespace.  Callers
willing to use these operators must explicitly include them with the `using`
declaration.  This can be done in some local scope.

Additionally, we currently emit signed comparisons for order-comparison
operators.  With namespaces, we can later introduce two sets of operators in
different namespace, e.g. `edsc::op::sign` and `edsc::op::unsign` to clearly
state which kind of comparison is implied.

PiperOrigin-RevId: 233578674

5 years agoEDSC: support 'for' loops with dynamic bounds
Alex Zinenko [Tue, 12 Feb 2019 11:34:52 +0000 (03:34 -0800)]
EDSC: support 'for' loops with dynamic bounds

The existing implementation in EDSC of 'for' loops in MLIREmitter is
unnecessarily restricted to constant bounds.  The underlying AffineForOp can be
constructed from (a list of) Values and AffineMaps instead of constants.  Its
verifier will check that the "affine provenance" conditions, i.e. that the
values used in the loop conditions are defined in such a way that they can be
analyzed by affine passes, are respected.  One can use non-constant values in
affine loop bounds in conjunction with a single-dimensional identity affine
map.  Implement this in MLIREmitter while maintaining the special case for
constant bounds that leads to significantly simpler generated IR when
applicable.

Test this change using the EDSC lowering test pass to inject code emitted from
EDSC into functions with predefined names.

PiperOrigin-RevId: 233578220

5 years agoAdd dialect-specific decoding for opaque constants.
Tatiana Shpeisman [Tue, 12 Feb 2019 06:51:34 +0000 (22:51 -0800)]
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

5 years agoFix incorrect type in iterator.
Jacques Pienaar [Tue, 12 Feb 2019 06:24:22 +0000 (22:24 -0800)]
Fix incorrect type in iterator.

PiperOrigin-RevId: 233542711

5 years agoGenerate dealloc's for the alloc's of dma-generate.
Uday Bondhugula [Tue, 12 Feb 2019 00:33:53 +0000 (16:33 -0800)]
Generate dealloc's for the alloc's of dma-generate.

- for the DMA buffers being allocated (and their tags), generate corresponding deallocs
- minor related update to replaceAllMemRefUsesWith and PipelineDataTransfer pass

Code generation for DMA transfers was being done with the initial simplifying
assumption that the alloc's would map to scoped allocations, and so no
deallocations would be necessary. Drop this assumption to generalize. Note that
even with scoped allocations, unrolling loops that have scoped allocations
could create a series of allocations and exhaustion of fast memory. Having a
end of lifetime marker like a dealloc in fact allows creating new scopes if
necessary when lowering to a backend and still utilize scoped allocation.
DMA buffers created by -dma-generate are guaranteed to have either
non-overlapping lifetimes or nested lifetimes.

PiperOrigin-RevId: 233502632

5 years agoFix + cleanup for getMemRefRegion()
Uday Bondhugula [Mon, 11 Feb 2019 23:43:26 +0000 (15:43 -0800)]
Fix + cleanup for getMemRefRegion()

- determine symbols for the memref region correctly

- this wasn't exposed earlier since we didn't have any test cases where the
  portion of the nest being DMAed for was non-hyperrectangular (i.e., bounds of
  one IV  depending on other IVs within that part)

PiperOrigin-RevId: 233493872

5 years agoAdd binary broadcastable builder.
Jacques Pienaar [Sun, 10 Feb 2019 22:14:08 +0000 (14:14 -0800)]
Add binary broadcastable builder.

* Add common broadcastable binary adder in TF ops and use for a few ops;
  - Adding Sub, Mul here
* Change the prepare lowering to use TF variants;
* Add some more legalization patterns;

PiperOrigin-RevId: 233310952

5 years ago[TFLite] Add rewrite pattern to fuse conv ops with Relu6 op
Lei Zhang [Sun, 10 Feb 2019 01:38:24 +0000 (17:38 -0800)]
[TFLite] Add rewrite pattern to fuse conv ops with Relu6 op

* Fixed tfl.conv_2d and tfl.depthwise_conv_2d to have fused activation
  function attribute
* Fixed RewriterGen crash: trying to get attribute match template when
  the matcher is unspecified (UnsetInit)

PiperOrigin-RevId: 233241755

5 years ago[TableGen] Support nested DAG nodes in result result op arguments
Lei Zhang [Sat, 9 Feb 2019 14:45:55 +0000 (06:45 -0800)]
[TableGen] Support nested DAG nodes in result result op arguments

This CL allowed developers to write result ops having nested DAG nodes as their
arguments. Now we can write

```
def : Pat<(...), (AOp (BOp, ...), AOperand)>
```
PiperOrigin-RevId: 233207225

5 years ago[TableGen] Assign created ops to variables and rewrite with PatternRewriter::replaceOp()
Lei Zhang [Sat, 9 Feb 2019 14:36:23 +0000 (06:36 -0800)]
[TableGen] Assign created ops to variables and rewrite with PatternRewriter::replaceOp()

Previously we were using PatternRewrite::replaceOpWithNewOp() to both create the new op
inline and rewrite the matched op. That does not work well if we want to generate multiple
ops in a sequence. To support that, this CL changed to assign each newly created op to a
separate variable.

This CL also refactors how PatternEmitter performs the directive dispatch logic.

PiperOrigin-RevId: 233206819

5 years agoConvert MemRefCastOp to the LLVM IR dialect
Alex Zinenko [Fri, 8 Feb 2019 18:20:01 +0000 (10:20 -0800)]
Convert MemRefCastOp to the LLVM IR dialect

Add support for converting `memref_cast` operations into the LLVM IR dialect.
This goes beyond want is currently implemented in the MLIR standard ops to LLVM
IR translation, but follows the general principles of the memref descriptors.
A memref cast creates a new descriptor containing the same buffer pointer but a
potentially different number of dynamic sizes (as many as dynamic dimensions in
the target memref type).  The lowering copies the buffer pointer to the new
descriptor and inserts dynamic sizes to it.  If the size is static in the
source type, a constant value is inserted as the dynamic size, otherwise a
dynamic value is copied from the source descriptor, taking into account the
difference in dynamic size positions in the descriptor.

PiperOrigin-RevId: 233082035

5 years agoRemove the restriction that only registered terminator operations may terminate a...
River Riddle [Fri, 8 Feb 2019 17:52:26 +0000 (09:52 -0800)]
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

5 years agoCleanups in ExecutionEngine.
Alex Zinenko [Fri, 8 Feb 2019 16:59:23 +0000 (08:59 -0800)]
Cleanups in ExecutionEngine.

Make sure the module is always passed to the optimization layer.
Drop unused default argument for the IR transformation and remove the function
that was only used in this default argument.  The transformation wrapper
constructor already checks for the null function, so the caller can just pass
`{}` if they don't want any transformation (no callers currently need this).

PiperOrigin-RevId: 233068817

5 years agoPort load/store op translation to LLVM IR dialect lowering
Alex Zinenko [Fri, 8 Feb 2019 13:26:20 +0000 (05:26 -0800)]
Port load/store op translation to LLVM IR dialect lowering

Implement the lowering of memref load and store standard operations into the
LLVM IR dialect.  This largely follows the existing mechanism in
MLIR-to-LLVM-IR translation for the sake of compatibility.  A memref value is
transformed into a memref descriptor value which holds the pointer to the
underlying data buffer and the dynamic memref sizes.  The data buffer is
contiguous.  Accesses to multidimensional memrefs are linearized in row-major
form.  In linear address computation, statically known sizes are used as
constants while dynamic sizes are extracted from the memref descriptor.

PiperOrigin-RevId: 233043846

5 years ago Automated rollback of changelist 232728977.
Uday Bondhugula [Thu, 7 Feb 2019 22:24:18 +0000 (14:24 -0800)]
Automated rollback of changelist 232728977.

PiperOrigin-RevId: 232944889

5 years agoHandle dynamic shapes in Broadcastable op trait
Smit Hinsu [Thu, 7 Feb 2019 20:56:12 +0000 (12:56 -0800)]
Handle dynamic shapes in Broadcastable op trait

That allows TensorFlow Add and Div ops to use Broadcastable op trait instead of
more restrictive SameValueType op trait.

That in turn allows TensorFlow ops to be registered by defining GET_OP_LIST and
including the generated ops file. Currently, tf-raise-control-flow pass tests
are using dynamic shapes in tf.Add op and AddOp can't be registered without
supporting the dynamic shapes.

TESTED with unit tests

PiperOrigin-RevId: 232927998

5 years agoAdd verification for AffineApply/AffineFor/AffineIf dimension and symbol operands...
River Riddle [Thu, 7 Feb 2019 20:29:31 +0000 (12:29 -0800)]
Add verification for AffineApply/AffineFor/AffineIf dimension and symbol operands. This also allows a DimOp to be a valid dimension identifier if its operand is a valid dimension identifier.

PiperOrigin-RevId: 232923468

5 years agoAdd tf.LeakyRelu.
Jacques Pienaar [Thu, 7 Feb 2019 20:28:48 +0000 (12:28 -0800)]
Add tf.LeakyRelu.

* Add tf.LeakyRelu op definition + folders (well one is really canonicalizer)
* Change generated error message to use attribute description instead;
* Change the return type of F32Attr to be APFloat - internally it is already
  stored as APFloat so let the caller decides if they want to convert it or
  not. I could see varying opinions here though :) (did not change i32attr
  similarly)

PiperOrigin-RevId: 232923358

5 years agoDisallow zero dimensions in vectors and memrefs
Alex Zinenko [Thu, 7 Feb 2019 18:13:50 +0000 (10:13 -0800)]
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

5 years agoDisallow hexadecimal literals in type declarations
Alex Zinenko [Thu, 7 Feb 2019 16:36:50 +0000 (08:36 -0800)]
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

5 years agoModify the canonicalizations of select and muli to use the fold hook.
River Riddle [Thu, 7 Feb 2019 16:26:31 +0000 (08:26 -0800)]
Modify the canonicalizations of select and muli to use the fold hook.

This also extends the greedy pattern rewrite driver to add the operands of folded operations back to the worklist.

PiperOrigin-RevId: 232878959

5 years agoExecutionEngine: provide a hook for LLVM IR passes
Alex Zinenko [Thu, 7 Feb 2019 16:12:14 +0000 (08:12 -0800)]
ExecutionEngine: provide a hook for LLVM IR passes

The current ExecutionEngine flow generates the LLVM IR from MLIR and
JIT-compiles it as is without any transformation.  It thus misses the
opportunity to perform optimizations supported by LLVM or collect statistics
about the module.  Modify the Orc JITter to perform transformations on the LLVM
IR.  Accept an optional LLVM module transformation function when constructing
the ExecutionEngine and use it while JIT-compiling.  This prevents MLIR
ExecutionEngine from depending on LLVM passes; its clients should depend on the
passes they require.

PiperOrigin-RevId: 232877060

5 years ago Automated rollback of changelist 232717775.
Uday Bondhugula [Thu, 7 Feb 2019 05:54:18 +0000 (21:54 -0800)]
Automated rollback of changelist 232717775.

PiperOrigin-RevId: 232807986

5 years agoWhen canonicalizing only erase the operation after calling the 'fold' hook if replace...
River Riddle [Wed, 6 Feb 2019 23:21:02 +0000 (15:21 -0800)]
When canonicalizing only erase the operation after calling the 'fold' hook if replacement results were supplied. This fixes a bug where the operation would always get erased, even if it was modified in place.

PiperOrigin-RevId: 232757964

5 years agoRename the 'if' operation in the AffineOps dialect to 'affine.if' and namespace
River Riddle [Wed, 6 Feb 2019 20:59:50 +0000 (12:59 -0800)]
Rename the 'if' operation in the AffineOps dialect to 'affine.if' and namespace
the AffineOps dialect with 'affine'.

PiperOrigin-RevId: 232728977

5 years agoAdd constant build() method not requiring result type
Lei Zhang [Wed, 6 Feb 2019 20:27:30 +0000 (12:27 -0800)]
Add constant build() method not requiring result type

Instead, we deduce the result type from the given attribute.

This is in preparation for generating constant ops with TableGen.

PiperOrigin-RevId: 232723467

5 years agoImplement Quantization dialect and minimal UniformQuantizedType.
Stella Laurenzo [Wed, 6 Feb 2019 20:26:11 +0000 (12:26 -0800)]
Implement Quantization dialect and minimal UniformQuantizedType.

PiperOrigin-RevId: 232723240

5 years agoPort alloc/dealloc LLVM IR conversion into the LLVM IR dialect lowering
Alex Zinenko [Wed, 6 Feb 2019 20:04:58 +0000 (12:04 -0800)]
Port alloc/dealloc LLVM IR conversion into the LLVM IR dialect lowering

Implement the lowering of memref allocation and deallocation standard
operations into the LLVM IR dialect.  This largely follows the existing
mechanism in MLIR-to-LLVM-IR translation for the sake of compatibility.
A memref value is transformed into a memref descriptor value which holds the
pointer to the underlying data buffer and the dynamic memref sizes.  The buffer
is allocated using `malloc` and freed using `free`.  The lowering inserts
declarations of these functions if necessary.  Memref descriptors are values of
the LLVM IR structure type wrapped into an MLIR LLVM dialect type.  The pointer
to the buffer and the individual sizes are accessed using `extractvalue` and
`insertvalue` LLVM IR instructions.

PiperOrigin-RevId: 232719419

5 years agoNFC: Rename the 'for' operation in the AffineOps dialect to 'affine.for'. The is...
River Riddle [Wed, 6 Feb 2019 19:58:03 +0000 (11:58 -0800)]
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

5 years agoAddress post submit review comments for removing Block::findInstPositionInBlock.
River Riddle [Wed, 6 Feb 2019 19:36:16 +0000 (11:36 -0800)]
Address post submit review comments for removing Block::findInstPositionInBlock.

PiperOrigin-RevId: 232713514

5 years agoNFC: Rename affine_apply to affine.apply. This is the first step to adding a namespac...
River Riddle [Wed, 6 Feb 2019 19:08:18 +0000 (11:08 -0800)]
NFC: Rename affine_apply to affine.apply. This is the first step to adding a namespace to the affine dialect.

PiperOrigin-RevId: 232707862

5 years agoAdds the ability to compute the MemRefRegion of a sliced loop nest. Utilizes this...
MLIR Team [Wed, 6 Feb 2019 19:01:10 +0000 (11:01 -0800)]
Adds the ability to compute the MemRefRegion of a sliced loop nest. Utilizes this feature during loop fusion cost computation, to compute what the write region of a fusion candidate loop nest slice would be (without having to materialize the slice or change the IR).
*) Adds parameter to public API of MemRefRegion::compute for passing in the slice loop bounds to compute the memref region of the loop nest slice.
*) Exposes public method MemRefRegion::getRegionSize for computing the size of the memref region in bytes.

PiperOrigin-RevId: 232706165

5 years agoAddress follow on comments for quickstart doc.
Jacques Pienaar [Wed, 6 Feb 2019 18:57:50 +0000 (10:57 -0800)]
Address follow on comments for quickstart doc.

PiperOrigin-RevId: 232705423

5 years agoRemove findInstPositionInBlock from the Block api.
River Riddle [Wed, 6 Feb 2019 18:54:57 +0000 (10:54 -0800)]
Remove findInstPositionInBlock from the Block api.

PiperOrigin-RevId: 232704766

5 years ago[TableGen] Model variadic operands using Variadic<Type>
Lei Zhang [Wed, 6 Feb 2019 13:06:11 +0000 (05:06 -0800)]
[TableGen] Model variadic operands using Variadic<Type>

Previously, we were using the trait mechanism to specify that an op has variadic operands.
That led a discrepancy between how we handle ops with deterministic number of operands.
Besides, we have no way to specify the constraints and match against the variadic operands.

This CL introduced Variadic<Type> as a way to solve the above issues.

PiperOrigin-RevId: 232656104

5 years agoMove the AffineFor loop bound folding to a canonicalization pattern on the AffineForOp.
River Riddle [Wed, 6 Feb 2019 04:55:28 +0000 (20:55 -0800)]
Move the AffineFor loop bound folding to a canonicalization pattern on the AffineForOp.

PiperOrigin-RevId: 232610715

5 years agoEmit a parser error when the min/max prefix is missing from a multi value AffineFor...
River Riddle [Wed, 6 Feb 2019 04:41:52 +0000 (20:41 -0800)]
Emit a parser error when the min/max prefix is missing from a multi value AffineFor loop bound AffineMap.

PiperOrigin-RevId: 232609693

5 years agoRefactor the affine analysis by moving some functionality to IR and some to AffineOps...
River Riddle [Wed, 6 Feb 2019 01:00:13 +0000 (17:00 -0800)]
Refactor the affine analysis by moving some functionality to IR and some to AffineOps. This is important for allowing the affine dialect to define canonicalizations directly on the operations instead of relying on transformation passes, e.g. ComposeAffineMaps. A summary of the refactoring:

* AffineStructures has moved to IR.

* simplifyAffineExpr/simplifyAffineMap/getFlattenedAffineExpr have moved to IR.

* makeComposedAffineApply/fullyComposeAffineMapAndOperands have moved to AffineOps.

* ComposeAffineMaps is replaced by AffineApplyOp::canonicalize and deleted.

PiperOrigin-RevId: 232586468

5 years agoDefine the initial g3doc for the Affine dialect.
River Riddle [Wed, 6 Feb 2019 00:29:25 +0000 (16:29 -0800)]
Define the initial g3doc for the Affine dialect.

PiperOrigin-RevId: 232581506

5 years agoAdd derived type attributes for TensorFlow ops generated by TableGen
Smit Hinsu [Tue, 5 Feb 2019 20:02:53 +0000 (12:02 -0800)]
Add derived type attributes for TensorFlow ops generated by TableGen

Motivation for this change is to remove redundant TF type attributes for
TensorFlow ops. For example, tf$T: "tfdtype$DT_FLOAT". Type attributes can be derived using the MLIR operand or result MLIR types, attribute names and their mapping. This will also allow constant folding of instructions generated within MLIR (and not imported from TensorFlow) without adding type attributes for the instruction.

Derived attributes are populated while exporting MLIR to TF GraphDef using
auto-generated populators. Populators are only available for the ops that are generated by the TableGen.

Also, fixed Operator::getNumArgs method to exclude derived attributes as they are not
part of the arguments.

TESTED with unit test

PiperOrigin-RevId: 232531561

5 years agoPrint parens around the return type of a function if it is also a function type
Alex Zinenko [Tue, 5 Feb 2019 19:47:02 +0000 (11:47 -0800)]
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

5 years agoMLIR graph rewrite using pattern quickstart doc.
Jacques Pienaar [Tue, 5 Feb 2019 16:26:02 +0000 (08:26 -0800)]
MLIR graph rewrite using pattern quickstart doc.

Start quickstart guide of how to define ops + specify patterns for rewrite.

PiperOrigin-RevId: 232490287

5 years agoImplemented __invert__, __and__ and __or__ in the EDSC Python bindings
Sergei Lebedev [Tue, 5 Feb 2019 16:17:34 +0000 (08:17 -0800)]
Implemented __invert__, __and__ and __or__ in the EDSC Python bindings

This allows to use bitwise operators as logical (accounting for differences
in precedence).

PiperOrigin-RevId: 232489024

5 years agoPrint non-default attribute types in optional attr dictionary
Alex Zinenko [Tue, 5 Feb 2019 15:12:46 +0000 (07:12 -0800)]
Print non-default attribute types in optional attr dictionary

In optional attribute dictionary used, among others, in the generic form of the
ops, attribute types for integers and floats are omitted.  This could lead to
inconsistencies when round-tripping the IR, in particular the attributes are
created with incorrect types after parsing (integers default to i64, floats
default to f64).  Provide API to emit a trailing type after the attribute for
integers and floats.  Use it while printing the optional attribute dictionary.

Omitting types for i64 and f64 is a pragmatic decision that minimizes changes
in tests.  We may want to reconsider in the future and always print types of
attributes in the generic form.

PiperOrigin-RevId: 232480116

5 years agoLoop fusion improvements:
MLIR Team [Tue, 5 Feb 2019 14:57:08 +0000 (06:57 -0800)]
Loop fusion improvements:
*) After a private memref buffer is created for a fused loop nest, dependences on the old memref are reduced, which can open up fusion opportunities. In these cases, users of the old memref are added back to the worklist to be reconsidered for fusion.
*) Fixed a bug in fusion insertion point dependence check where the memref being privatized was being skipped from the check.

PiperOrigin-RevId: 232477853

5 years agoImplemented __eq__ and __ne__ in EDSC Python bindings
Sergei Lebedev [Tue, 5 Feb 2019 14:18:01 +0000 (06:18 -0800)]
Implemented __eq__ and __ne__ in EDSC Python bindings

PiperOrigin-RevId: 232473201

5 years agoRemove stray debug output - NFC
Uday Bondhugula [Tue, 5 Feb 2019 00:36:33 +0000 (16:36 -0800)]
Remove stray debug output - NFC

PiperOrigin-RevId: 232390076

5 years agoRemove InstWalker and move all instruction walking to the api facilities on Function...
River Riddle [Tue, 5 Feb 2019 00:24:44 +0000 (16:24 -0800)]
Remove InstWalker and move all instruction walking to the api facilities on Function/Block/Instruction.

PiperOrigin-RevId: 232388113

5 years agoNFC: Move AffineApplyOp to the AffineOps dialect. This also moves the isValidDim...
River Riddle [Tue, 5 Feb 2019 00:15:13 +0000 (16:15 -0800)]
NFC: Move AffineApplyOp to the AffineOps dialect. This also moves the isValidDim/isValidSymbol methods from Value to the AffineOps dialect.

PiperOrigin-RevId: 232386632