Commit Graph

771 Commits

Author SHA1 Message Date
Nicolas Vasilache e6f2f17f05 [mlir][Linalg] Refactor StructuredOpInterface - NFC
This revision refactors and cleans up a bunch of things to simplify StructuredOpInterface
before work can proceed on Linalg on tensors:
- break out pieces of the StructuredOps trait that are part of the StructuredOpInterface,
- drop referenceIterators and referenceIndexingMaps that end up being more confusing than useful,
- drop NamedStructuredOpTrait
2020-09-11 07:53:12 -04:00
MaheshRavishankar 0a391c6079 [mlir][Analysis] Allow Slice Analysis to work with linalg::LinalgOp
Differential Revision: https://reviews.llvm.org/D87307
2020-09-10 18:54:22 -07:00
Jakub Lichman 67b37f571c [mlir] Conv ops vectorization pass
In this commit a new way of convolution ops lowering is introduced.
The conv op vectorization pass lowers linalg convolution ops
into vector contractions. This lowering is possible when conv op
is first tiled by 1 along specific dimensions which transforms
it into dot product between input and kernel subview memory buffers.
This pass converts such conv op into vector contraction and does
all necessary vector transfers that make it work.

Differential Revision: https://reviews.llvm.org/D86619
2020-09-08 08:47:42 +00:00
Mehdi Amini 63d1dc6665 Add a doc/tutorial on traversing the IR
Reviewed By: stephenneuendorffer

Differential Revision: https://reviews.llvm.org/D87221
2020-09-08 00:07:03 +00:00
Marius Brehler c633842f13 [mlir] Fix includes in mlir-translate
Drops the include on InitAllDialects.h, as dialects are now initialized in the translation passes.

Differential Revision: https://reviews.llvm.org/D87129
2020-09-04 15:22:38 +02:00
Lei Zhang 7939b76e2a [mlir] Support default valued attribute in StructsGen
Its handling is similar to optional attributes, except for the
getter method.

Reviewed By: rsuderman

Differential Revision: https://reviews.llvm.org/D87055
2020-09-03 09:46:44 -04:00
Mehdi Amini 6478caa034 Tweak `mlir-linalg-ods-gen` library dependency: only MLIRIR is needed, not the entire parser (NFC) 2020-09-02 23:58:32 +00:00
Thomas Raoux 8d65504223 [mlir][vulkan-runner] Explicitly export vulkan-runtime-wrapper entry points.
This ensure that the symbols are being exported no matter what default
visibility is set.
2020-09-01 15:37:54 -07:00
Mehdi Amini f54914081f Fix mlir-reduce to explicitly register dialects and disable the global dialect registry by default
Clients who rely on the Context loading dialects from the global
registry can call `mlir::enableGlobalDialectRegistry(true);` before
creating an MLIRContext

Differential Revision: https://reviews.llvm.org/D86897
2020-08-31 22:54:58 +00:00
River Riddle eaeadce9bd [mlir][OpFormatGen] Add initial support for regions in the custom op assembly format
This adds some initial support for regions and does not support formatting the specific arguments of a region. For now this can be achieved by using a custom directive that formats the arguments and then parses the region.

Differential Revision: https://reviews.llvm.org/D86760
2020-08-31 13:26:24 -07:00
River Riddle 24b88920fe [mlir][ODS] Add new SymbolNameAttr and add support for in assemblyFormat
Symbol names are a special form of StringAttr that get treated specially in certain areas, such as formatting. This revision adds a special derived attr for them in ODS and adds support in the assemblyFormat for formatting them properly.

Differential Revision: https://reviews.llvm.org/D86759
2020-08-31 13:26:23 -07:00
River Riddle 88c6e25e4f [mlir][OpFormatGen] Add support for specifiy "custom" directives.
This revision adds support for custom directives to the declarative assembly format. This allows for users to use C++ for printing and parsing subsections of an otherwise declaratively specified format. The custom directive is structured as follows:

```
custom-directive ::= `custom` `<` UserDirective `>` `(` Params `)`
```

`user-directive` is used as a suffix when this directive is used during printing and parsing. When parsing, `parseUserDirective` will be invoked. When printing, `printUserDirective` will be invoked. The first parameter to these methods must be a reference to either the OpAsmParser, or OpAsmPrinter. The type of rest of the parameters is dependent on the `Params` specified in the assembly format.

Differential Revision: https://reviews.llvm.org/D84719
2020-08-31 13:26:23 -07:00
Mehdi Amini 719548d63d Fix gcc warning by explicitly initializing the base class copy ctor (NFC)
Full diagnostic was:

warning: base class ‘class mlir::OptReductionBase<mlir::OptReductionPass>’ should be explicitly initialized in the copy constructor [-Wextra]
2020-08-30 17:46:51 +00:00
Kamlesh Kumar deb99610ab Improve doc comments for several methods returning bools
Differential Revision: https://reviews.llvm.org/D86848
2020-08-30 13:33:05 +05:30
Kazuaki Ishizaki a23d055912 [mlir] NFC: fix trivial typo under test and tools
Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D86648
2020-08-27 15:37:42 +09:00
Ni Hui df2efd7700 Fix MLIR build with MLIR_INCLUDE_TESTS=OFF
error message

/usr/bin/ld: CMakeFiles/mlir-opt.dir/mlir-opt.cpp.o: in function `main':
mlir-opt.cpp:(.text.startup.main+0xb9): undefined reference to `mlir::registerTestDialect(mlir::DialectRegistry&)'

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D86592
2020-08-27 04:04:20 +00:00
River Riddle d289a97f91 [mlir][PDL] Add a PDL Interpreter Dialect
The PDL Interpreter dialect provides a lower level abstraction compared to the PDL dialect, and is targeted towards low level optimization and interpreter code generation. The dialect operations encapsulates low-level pattern match and rewrite "primitives", such as navigating the IR (Operation::getOperand), creating new operations (OpBuilder::create), etc. Many of the operations within this dialect also fuse branching control flow with some form of a predicate comparison operation. This type of fusion reduces the amount of work that an interpreter must do when executing.

An example of this representation is shown below:

```mlir
// The following high level PDL pattern:
pdl.pattern : benefit(1) {
  %resultType = pdl.type
  %inputOperand = pdl.input
  %root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
  pdl.rewrite %root {
    pdl.replace %root with (%inputOperand)
  }
}

// May be represented in the interpreter dialect as follows:
module {
  func @matcher(%arg0: !pdl.operation) {
    pdl_interp.check_operation_name of %arg0 is "foo.op" -> ^bb2, ^bb1
  ^bb1:
    pdl_interp.return
  ^bb2:
    pdl_interp.check_operand_count of %arg0 is 1 -> ^bb3, ^bb1
  ^bb3:
    pdl_interp.check_result_count of %arg0 is 1 -> ^bb4, ^bb1
  ^bb4:
    %0 = pdl_interp.get_operand 0 of %arg0
    pdl_interp.is_not_null %0 : !pdl.value -> ^bb5, ^bb1
  ^bb5:
    %1 = pdl_interp.get_result 0 of %arg0
    pdl_interp.is_not_null %1 : !pdl.value -> ^bb6, ^bb1
  ^bb6:
    pdl_interp.record_match @rewriters::@rewriter(%0, %arg0 : !pdl.value, !pdl.operation) : benefit(1), loc([%arg0]), root("foo.op") -> ^bb1
  }
  module @rewriters {
    func @rewriter(%arg0: !pdl.value, %arg1: !pdl.operation) {
      pdl_interp.replace %arg1 with(%arg0)
      pdl_interp.return
    }
  }
}
```

Differential Revision: https://reviews.llvm.org/D84579
2020-08-26 05:22:27 -07:00
Eric Christopher 1a2a34a38a Add NDEBUG checks around debug only loop to avoid unused variable
warnings.
2020-08-24 17:58:57 -07:00
Mehdi Amini f164534ca8 Add a `dialect_registration` callback for "translations" registered with mlir-translate
This will allow out-of-tree translation to register the dialects they expect
to see in their input, on the model of getDependentDialects() for passes.

Differential Revision: https://reviews.llvm.org/D86409
2020-08-23 01:00:39 +00:00
Mehdi Amini 96cb8cdeb0 Refactor `mlir-translate` to extract the `main()` logic in a helper on the model of `MlirOptMain()` (NFC)
Differential Revision: https://reviews.llvm.org/D86408
2020-08-23 01:00:31 +00:00
Mauricio Sifontes 21f8d41468 Refactor Reduction Tree Pass
Refactor the way the reduction tree pass works in the MLIR Reduce tool by introducing a set of utilities that facilitate the implementation of new Reducer classes to be used in the passes.

This will allow for the fast implementation of general transformations to operate on all mlir modules as well as custom transformations for different dialects.

These utilities allow for the implementation of Reducer classes by simply defining a method that indexes the operations/blocks/regions to be transformed and a method to perform the deletion or transfomration based on the indexes.

Create the transformSpace class member in the ReductionNode class to keep track of the indexes that have already been transformed or deleted at a current level.

Delete the FunctionReducer class and replace it with the OpReducer class to reflect this new API while performing the same transformation and allowing the instantiation of a reduction pass for different types of operations at the module's highest hierarchichal level.

Modify the SinglePath Traversal method to reflect the use of the new API.

Reviewed: jpienaar

Differential Revision: https://reviews.llvm.org/D85591
2020-08-21 04:59:24 +00:00
River Riddle 3fb3927bd3 [mlir] Add a new "Pattern Descriptor Language" (PDL) dialect.
PDL presents a high level abstraction for the rewrite pattern infrastructure available in MLIR. This abstraction allows for representing patterns transforming MLIR, as MLIR. This allows for applying all of the benefits that the general MLIR infrastructure provides, to the infrastructure itself. This means that pattern matching can be more easily verified for correctness, targeted by frontends, and optimized.

PDL abstracts over various different aspects of patterns and core MLIR data structures. Patterns are specified via a `pdl.pattern` operation. These operations contain a region body for the "matcher" code, and terminate with a `pdl.rewrite` that either dispatches to an external rewriter or contains a region for the rewrite specified via `pdl`. The types of values in `pdl` are handle types to MLIR C++ types, with `!pdl.attribute`, `!pdl.operation`, and `!pdl.type` directly mapping to `mlir::Attribute`, `mlir::Operation*`, and `mlir::Value` respectively.

An example pattern is shown below:

```mlir
// pdl.pattern contains metadata similarly to a `RewritePattern`.
pdl.pattern : benefit(1) {
  // External input operand values are specified via `pdl.input` operations.
  // Result types are constrainted via `pdl.type` operations.

  %resultType = pdl.type
  %inputOperand = pdl.input
  %root, %results = pdl.operation "foo.op"(%inputOperand) -> %resultType
  pdl.rewrite(%root) {
    pdl.replace %root with (%inputOperand)
  }
}
```

This is a culmination of the work originally discussed here: https://groups.google.com/a/tensorflow.org/g/mlir/c/j_bn74ByxlQ

Differential Revision: https://reviews.llvm.org/D84578
2020-08-19 13:13:06 -07:00
Mehdi Amini f9dc2b7079 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-19 01:19:03 +00:00
Mehdi Amini e75bc5c791 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit d14cf45735.
The build is broken with GCC-5.
2020-08-19 01:19:03 +00:00
Mehdi Amini d14cf45735 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  registry.insert<mlir::standalone::StandaloneDialect>();
  registry.insert<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()

Differential Revision: https://reviews.llvm.org/D85622
2020-08-18 23:23:56 +00:00
Mehdi Amini d84fe55e0d Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit e1de2b7550.
Broke a build bot.
2020-08-18 22:16:34 +00:00
Mehdi Amini e1de2b7550 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally
registered dialects on construction. Instead Dialects are only loaded explicitly
on demand:
- the Parser is lazily loading Dialects in the context as it encounters them
during parsing. This is the only purpose for registering dialects and not load
them in the context.
- Passes are expected to declare the dialects they will create entity from
(Operations, Attributes, or Types), and the PassManager is loading Dialects into
the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only
need to load the dialect for the IR it will emit, and the optimizer is
self-contained and load the required Dialects. For example in the Toy tutorial,
the compiler only needs to load the Toy dialect in the Context, all the others
(linalg, affine, std, LLVM, ...) are automatically loaded depending on the
optimization pipeline enabled.

To adjust to this change, stop using the existing dialect registration: the
global registry will be removed soon.

1) For passes, you need to override the method:

virtual void getDependentDialects(DialectRegistry &registry) const {}

and registery on the provided registry any dialect that this pass can produce.
Passes defined in TableGen can provide this list in the dependentDialects list
field.

2) For dialects, on construction you can register dependent dialects using the
provided MLIRContext: `context.getOrLoadDialect<DialectName>()`
This is useful if a dialect may canonicalize or have interfaces involving
another dialect.

3) For loading IR, dialect that can be in the input file must be explicitly
registered with the context. `MlirOptMain()` is taking an explicit registry for
this purpose. See how the standalone-opt.cpp example is setup:

  mlir::DialectRegistry registry;
  mlir::registerDialect<mlir::standalone::StandaloneDialect>();
  mlir::registerDialect<mlir::StandardOpsDialect>();

Only operations from these two dialects can be in the input file. To include all
of the dialects in MLIR Core, you can populate the registry this way:

  mlir::registerAllDialects(registry);

4) For `mlir-translate` callback, as well as frontend, Dialects can be loaded in
the context before emitting the IR: context.getOrLoadDialect<ToyDialect>()
2020-08-18 21:14:39 +00:00
Mauricio Sifontes 8f4859d351 Create Optimization Pass Wrapper for MLIR Reduce
Create a reduction pass that accepts an optimization pass as argument
and only replaces the golden module in the pipeline if the output of the
optimization pass is smaller than the input and still exhibits the
interesting behavior.

Add a -test-pass option to test individual passes in the MLIR Reduce
tool.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D84783
2020-08-18 16:47:10 +00:00
Mehdi Amini 54ce344314 Refactor mlir-opt setup in a new helper function (NFC)
This will help refactoring some of the tools to prepare for the explicit registration of
Dialects.

Differential Revision: https://reviews.llvm.org/D86023
2020-08-15 20:09:06 +00:00
Mehdi Amini 25ee851746 Revert "Separate the Registration from Loading dialects in the Context"
This reverts commit 2056393387.

Build is broken on a few bots
2020-08-15 09:21:47 +00:00
Mehdi Amini 2056393387 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.

Differential Revision: https://reviews.llvm.org/D85622
2020-08-15 08:07:31 +00:00
Mehdi Amini ba92dadf05 Revert "Separate the Registration from Loading dialects in the Context"
This was landed by accident, will reland with the right comments
addressed from the reviews.
Also revert dependent build fixes.
2020-08-15 07:35:10 +00:00
Mehdi Amini ebf521e784 Separate the Registration from Loading dialects in the Context
This changes the behavior of constructing MLIRContext to no longer load globally registered dialects on construction. Instead Dialects are only loaded explicitly on demand:
- the Parser is lazily loading Dialects in the context as it encounters them during parsing. This is the only purpose for registering dialects and not load them in the context.
- Passes are expected to declare the dialects they will create entity from (Operations, Attributes, or Types), and the PassManager is loading Dialects into the Context when starting a pipeline.

This changes simplifies the configuration of the registration: a compiler only need to load the dialect for the IR it will emit, and the optimizer is self-contained and load the required Dialects. For example in the Toy tutorial, the compiler only needs to load the Toy dialect in the Context, all the others (linalg, affine, std, LLVM, ...) are automatically loaded depending on the optimization pipeline enabled.
2020-08-14 09:40:27 +00:00
Alexander Belyaev fed9ff5117 [mlir] Test CallOp STD->LLVM conversion.
This exercises the corner case that was fixed in
https://reviews.llvm.org/rG8979a9cdf226066196f1710903d13492e6929563.

The bug can be reproduced when there is a @callee with a custom type argument and @caller has a producer of this argument passed to the @callee.

Example:
func @callee(!test.test_type) -> i32
func @caller() -> i32 {
  %arg = "test.type_producer"() : () -> !test.test_type
  %out = call @callee(%arg) : (!test.test_type) -> i32
  return %out : i32
}

Even though there is a type conversion for !test.test_type, the output IR (before the fix) contained a DialectCastOp:

module {
  llvm.func @callee(!llvm.ptr<i8>) -> !llvm.i32
  llvm.func @caller() -> !llvm.i32 {
    %0 = llvm.mlir.null : !llvm.ptr<i8>
    %1 = llvm.mlir.cast %0 : !llvm.ptr<i8> to !test.test_type
    %2 = llvm.call @callee(%1) : (!test.test_type) -> !llvm.i32
    llvm.return %2 : !llvm.i32
  }
}

instead of

module {
  llvm.func @callee(!llvm.ptr<i8>) -> !llvm.i32
  llvm.func @caller() -> !llvm.i32 {
    %0 = llvm.mlir.null : !llvm.ptr<i8>
    %1 = llvm.call @callee(%0) : (!llvm.ptr<i8>) -> !llvm.i32
    llvm.return %1 : !llvm.i32
  }
}

Differential Revision: https://reviews.llvm.org/D85914
2020-08-13 19:10:21 +02:00
Kiran Chandramohan fc544dcf2d [NFC][MLIR][OpenMP] Add comments and test for OpenMP enum declaration utility
Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D85857
2020-08-14 23:22:23 +01:00
Kiran Chandramohan e6c5e6efd0 [MLIR,OpenMP] Lowering of parallel operation: proc_bind clause 2/n
This patch adds the translation of the proc_bind clause in a
parallel operation.

The values that can be specified for the proc_bind clause are
specified in the OMP.td tablegen file in the llvm/Frontend/OpenMP
directory. From this single source of truth enumeration for
proc_bind is generated in llvm and mlir (used in specification of
the parallel Operation in the OpenMP dialect). A function to return
the enum value from the string representation is also generated.
A new header file (DirectiveEmitter.h) containing definitions of
classes directive, clause, clauseval etc is created so that it can
be used in mlir as well.

Reviewers: clementval, jdoerfert, DavidTruby

Differential Revision: https://reviews.llvm.org/D84347
2020-08-12 08:03:13 +01:00
Jacques Pienaar 29429d1a44 [drr] Add $_loc special directive for NativeCodeCall
Allows propagating the location to ops created via NativeCodeCall.

Differential Revision: https://reviews.llvm.org/D85704
2020-08-11 14:06:17 -07:00
Christian Sigg 2c48e3629c [MLIR] Adding gpu.host_register op and lower it to a runtime call.
Reviewed By: herhut

Differential Revision: https://reviews.llvm.org/D85631
2020-08-10 22:46:17 +02:00
Christian Sigg 0d4b7adb82 [MLIR] Make gpu.launch_func rewrite pattern part of the LLVM lowering pass.
Reviewed By: herhut

Differential Revision: https://reviews.llvm.org/D85073
2020-08-10 19:28:30 +02:00
Rahul Joshi 13d05787d0 [MLIR][TableGen] Fix ambiguous build methods when inferring result types.
- Fix ODS framework to suppress build methods that infer result types and are
  ambiguous with collective variants. This applies to operations with a single variadic
  inputs whose result types can be inferred.
- Extended OpBuildGenTest to test these kinds of ops.

Differential Revision: https://reviews.llvm.org/D85060
2020-08-10 10:05:06 -07:00
Jacques Pienaar 4b211b94d7 [mlir][drr] Make error easier to understand
Changes error from
  error: referencing unbound symbol ''
to
  error: raw string not supported as argument
2020-08-09 18:02:08 -07:00
Mehdi Amini eebd0a57fc Remove unused class member (NFC)
Fix include/mlir/Reducer/ReductionNode.h:79:18: warning: private field 'parent' is not used [-Wunused-private-field]
2020-08-08 05:36:41 +00:00
Mauricio Sifontes 27d0e14da9 Create Reduction Tree Pass
Implement the Reduction Tree Pass framework as part of the MLIR Reduce tool. This is a parametarizable pass that allows for the implementation of custom reductions passes in the tool.
Implement the FunctionReducer class as an example of a Reducer class parameter for the instantiation of a Reduction Tree Pass.
Create a pass pipeline with a Reduction Tree Pass with the FunctionReducer class specified as parameter.

Reviewed By: jpienaar

Differential Revision: https://reviews.llvm.org/D83969
2020-08-07 23:17:31 +00:00
Mehdi Amini 575b22b5d1 Revisit Dialect registration: require and store a TypeID on dialects
This patch moves the registration to a method in the MLIRContext: getOrCreateDialect<ConcreteDialect>()

This method requires dialect to provide a static getDialectNamespace()
and store a TypeID on the Dialect itself, which allows to lazyily
create a dialect when not yet loaded in the context.
As a side effect, it means that duplicated registration of the same
dialect is not an issue anymore.

To limit the boilerplate, TableGen dialect generation is modified to
emit the constructor entirely and invoke separately a "init()" method
that the user implements.

Differential Revision: https://reviews.llvm.org/D85495
2020-08-07 15:57:08 +00:00
Alex Zinenko db1c197bf8 [mlir] take LLVMContext in MLIR-to-LLVM-IR translation
Due to the original type system implementation, LLVMDialect in MLIR contains an
LLVMContext in which the relevant objects (types, metadata) are created. When
an MLIR module using the LLVM dialect (and related intrinsic-based dialects
NVVM, ROCDL, AVX512) is converted to LLVM IR, it could only live in the
LLVMContext owned by the dialect. The type system no longer relies on the
LLVMContext, so this limitation can be removed. Instead, translation functions
now take a reference to an LLVMContext in which the LLVM IR module should be
constructed. The caller of the translation functions is responsible for
ensuring the same LLVMContext is not used concurrently as the translation no
longer uses a dialect-wide context lock.

As an additional bonus, this change removes the need to recreate the LLVM IR
module in a different LLVMContext through printing and parsing back, decreasing
the compilation overhead in JIT and GPU-kernel-to-blob passes.

Reviewed By: rriddle, mehdi_amini

Differential Revision: https://reviews.llvm.org/D85443
2020-08-07 14:22:30 +02:00
Christian Sigg 45676a8936 [MLIR] Change GpuLaunchFuncToGpuRuntimeCallsPass to wrap a RewritePattern with the same functionality.
The RewritePattern will become one of several, and will be part of the LLVM conversion pass (instead of a separate pass following LLVM conversion).

Reviewed By: herhut

Differential Revision: https://reviews.llvm.org/D84946
2020-08-06 11:55:46 +02:00
Alex Zinenko b2ab375d1f [mlir] use the new stateful LLVM type translator by default
Previous type model in the LLVM dialect did not support identified structure
types properly and therefore could use stateless translations implemented as
free functions. The new model supports identified structs and must keep track
of the identified structure types present in the target context (LLVMContext or
MLIRContext) to avoid creating duplicate structs due to LLVM's type
auto-renaming. Expose the stateful type translation classes and use them during
translation, storing the state as part of ModuleTranslation.

Drop the test type translation mechanism that is no longer necessary and update
the tests to exercise type translation as part of the main translation flow.

Update the code in vector-to-LLVM dialect conversion that relied on stateless
translation to use the new class in a stateless manner.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85297
2020-08-06 00:36:33 +02:00
Alex Zinenko 4e491570b5 [mlir] Remove LLVMTypeTestDialect
This dialect was introduced during the bring-up of the new LLVM dialect type
system for testing purposes. The main LLVM dialect now uses the new type system
and the test dialect is no longer necessary, so remove it.

Reviewed By: rriddle

Differential Revision: https://reviews.llvm.org/D85224
2020-08-05 14:39:36 +02:00
Alex Zinenko d4fbbab2e4 [mlir] translate types between MLIR LLVM dialect and LLVM IR
With new LLVM dialect type modeling, the dialect types no longer wrap LLVM IR
types. Therefore, they need to be translated to and from LLVM IR during export
and import. Introduce the relevant functionality for translating types. It is
currently exercised by an ad-hoc type translation roundtripping test that will
be subsumed by the actual translation test when the type system transition is
complete.

Depends On D84339

Reviewed By: herhut

Differential Revision: https://reviews.llvm.org/D85019
2020-08-04 13:42:43 +02:00
River Riddle 8c39e70679 [mlir][OpFormatGen] Add support for eliding UnitAttr when used to anchor an optional group
Unit attributes are given meaning by their existence, and thus have no meaningful value beyond "is it present". As such, in the format of an operation unit attributes are generally used to guard the printing of other elements and aren't generally printed themselves; as the presence of the group when parsing means that the unit attribute should be added. This revision adds support to the declarative format for eliding unit attributes in situations where they anchor an optional group, but aren't the first element.

For example,
```
let assemblyFormat = "(`is_optional` $unit_attr^)? attr-dict";
```

would print `foo.op is_optional` when $unit_attr is present, instead of the current `foo.op is_optional unit`.

Differential Revision: https://reviews.llvm.org/D84577
2020-08-03 14:31:41 -07:00