2018-06-22 00:49:33 +08:00
|
|
|
//===- mlir-opt.cpp - MLIR Optimizer Driver -------------------------------===//
|
|
|
|
//
|
2020-01-26 11:58:30 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
2019-12-24 01:35:36 +08:00
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2018-06-22 00:49:33 +08:00
|
|
|
//
|
2019-12-24 01:35:36 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2018-06-22 00:49:33 +08:00
|
|
|
//
|
2019-06-24 23:41:52 +08:00
|
|
|
// Main entry function for mlir-opt for when built as standalone binary.
|
2018-06-22 00:49:33 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2020-04-12 14:11:51 +08:00
|
|
|
#include "mlir/IR/AsmState.h"
|
2020-02-19 06:56:45 +08:00
|
|
|
#include "mlir/IR/Dialect.h"
|
|
|
|
#include "mlir/IR/MLIRContext.h"
|
2020-04-12 14:11:51 +08:00
|
|
|
#include "mlir/InitAllDialects.h"
|
|
|
|
#include "mlir/InitAllPasses.h"
|
2019-02-28 06:45:36 +08:00
|
|
|
#include "mlir/Pass/Pass.h"
|
2019-02-28 02:59:29 +08:00
|
|
|
#include "mlir/Pass/PassManager.h"
|
2019-01-11 23:22:57 +08:00
|
|
|
#include "mlir/Support/FileUtilities.h"
|
2019-06-24 23:41:52 +08:00
|
|
|
#include "mlir/Support/MlirOptMain.h"
|
2018-06-22 00:49:33 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
#include "llvm/Support/InitLLVM.h"
|
2018-07-08 10:12:22 +08:00
|
|
|
#include "llvm/Support/SourceMgr.h"
|
2018-06-22 06:22:42 +08:00
|
|
|
#include "llvm/Support/ToolOutputFile.h"
|
2018-08-31 08:35:15 +08:00
|
|
|
|
2018-06-22 06:22:42 +08:00
|
|
|
using namespace llvm;
|
2019-06-24 23:41:52 +08:00
|
|
|
using namespace mlir;
|
2018-06-22 06:22:42 +08:00
|
|
|
|
2020-02-12 17:03:40 +08:00
|
|
|
namespace mlir {
|
|
|
|
// Defined in the test directory, no public header.
|
2020-08-14 00:53:07 +08:00
|
|
|
void registerConvertCallOpPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerConvertToTargetEnvPass();
|
|
|
|
void registerInliner();
|
|
|
|
void registerMemRefBoundCheck();
|
|
|
|
void registerPassManagerTestPass();
|
|
|
|
void registerPatternsTestPass();
|
2020-02-25 02:35:33 +08:00
|
|
|
void registerPrintOpAvailabilityPass();
|
[mlir][SideEffects] Define a set of interfaces and traits for defining side effects
This revision introduces the infrastructure for defining side-effects and attaching them to operations. This infrastructure allows for defining different types of side effects, that don't interact with each other, but use the same internal mechanisms. At the base of this is an interface that allows operations to specify the different effect instances that are exhibited by a specific operation instance. An effect instance is comprised of the following:
* Effect: The specific effect being applied.
For memory related effects this may be reading from memory, storing to memory, etc.
* Value: A specific value, either operand/result/region argument, the effect pertains to.
* Resource: This is a global entity that represents the domain within which the effect is being applied.
MLIR serves many different abstractions, which cover many different domains. Simple effects are may have very different context, for example writing to an in-memory buffer vs a database. This revision defines uses this infrastructure to define a set of initial MemoryEffects. The are effects that generally correspond to memory of some kind; Allocate, Free, Read, Write.
This set of memory effects will be used in follow revisions to generalize various parts of the compiler, and make others more powerful(e.g. DCE).
This infrastructure was originally proposed here:
https://groups.google.com/a/tensorflow.org/g/mlir/c/v2mNl4vFCUM
Differential Revision: https://reviews.llvm.org/D74439
2020-03-07 05:53:16 +08:00
|
|
|
void registerSideEffectTestPasses();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerSimpleParametricTilingPass();
|
2020-09-11 07:47:29 +08:00
|
|
|
void registerSliceAnalysisTestPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerSymbolTestPasses();
|
2020-02-15 05:41:01 +08:00
|
|
|
void registerTestAffineDataCopyPass();
|
2020-09-18 02:07:21 +08:00
|
|
|
void registerTestAffineLoopParametricTilingPass();
|
2020-04-10 19:42:49 +08:00
|
|
|
void registerTestAffineLoopUnswitchingPass();
|
2020-07-29 20:58:09 +08:00
|
|
|
void registerTestAllReduceLoweringPass();
|
Providing buffer assignment for MLIR
We have provided a generic buffer assignment transformation ported from
TensorFlow. This generic transformation pass automatically analyzes the values
and their aliases (also in other blocks) and returns the valid positions for
Alloc and Dealloc operations. To find these positions, the algorithm uses the
block Dominator and Post-Dominator analyses. In our proposed algorithm, we have
considered aliasing, liveness, nested regions, branches, conditional branches,
critical edges, and independency to custom block terminators. This
implementation doesn't support block loops. However, we have considered this in
our design. For this purpose, it is only required to have a loop analysis to
insert Alloc and Dealloc operations outside of these loops in some special
cases.
Differential Revision: https://reviews.llvm.org/D78484
2020-04-20 18:41:14 +08:00
|
|
|
void registerTestBufferPlacementPreparationPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestCallGraphPass();
|
|
|
|
void registerTestConstantFold();
|
2020-09-08 16:31:52 +08:00
|
|
|
void registerTestConvVectorization();
|
2020-03-22 18:13:40 +08:00
|
|
|
void registerTestConvertGPUKernelToCubinPass();
|
2020-05-23 05:25:00 +08:00
|
|
|
void registerTestConvertGPUKernelToHsacoPass();
|
2020-03-03 17:33:16 +08:00
|
|
|
void registerTestDominancePass();
|
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 ®istry) 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 04:01:19 +08:00
|
|
|
void registerTestDialect(DialectRegistry &);
|
2020-09-22 08:51:27 +08:00
|
|
|
void registerTestDynamicPipelinePass();
|
2020-06-16 01:26:32 +08:00
|
|
|
void registerTestExpandTanhPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestFunc();
|
|
|
|
void registerTestGpuMemoryPromotionPass();
|
2020-07-29 20:58:09 +08:00
|
|
|
void registerTestGpuParallelLoopMappingPass();
|
2020-07-01 06:42:52 +08:00
|
|
|
void registerTestInterfaces();
|
2020-10-01 05:55:59 +08:00
|
|
|
void registerTestLinalgFusionTransforms();
|
2020-06-05 06:55:26 +08:00
|
|
|
void registerTestLinalgHoisting();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestLinalgTransforms();
|
|
|
|
void registerTestLivenessPass();
|
|
|
|
void registerTestLoopFusion();
|
|
|
|
void registerTestLoopMappingPass();
|
2020-07-29 20:58:09 +08:00
|
|
|
void registerTestLoopPermutationPass();
|
[MLIR][LoopOps] Adds the loop unroll transformation for loop::ForOp.
Summary:
Adds the loop unroll transformation for loop::ForOp.
Adds support for promoting the body of single-iteration loop::ForOps into its containing block.
Adds check tests for loop::ForOps with dynamic and static lower/upper bounds and step.
Care was taken to share code (where possible) with the AffineForOp unroll transformation to ease maintenance and potential future transition to a LoopLike construct on which loop transformations for different loop types can implemented.
Reviewers: ftynse, nicolasvasilache
Reviewed By: ftynse
Subscribers: bondhugula, mgorny, zzheng, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, grosul1, frgossen, Kayjukh, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79184
2020-05-06 01:29:09 +08:00
|
|
|
void registerTestLoopUnrollingPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestMatchers();
|
|
|
|
void registerTestMemRefDependenceCheck();
|
|
|
|
void registerTestMemRefStrideCalculation();
|
|
|
|
void registerTestOpaqueLoc();
|
2020-06-03 00:12:57 +08:00
|
|
|
void registerTestPreparationPassWithAllowedMemrefResults();
|
2020-09-08 08:06:37 +08:00
|
|
|
void registerTestPrintDefUsePass();
|
|
|
|
void registerTestPrintNestingPass();
|
2020-07-22 19:03:24 +08:00
|
|
|
void registerTestRecursiveTypesPass();
|
2020-07-11 08:46:55 +08:00
|
|
|
void registerTestReducer();
|
2020-07-29 02:47:30 +08:00
|
|
|
void registerTestSpirvEntryPointABIPass();
|
2020-05-29 18:42:35 +08:00
|
|
|
void registerTestSCFUtilsPass();
|
2020-10-14 04:58:19 +08:00
|
|
|
void registerTestTraitsPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestVectorConversions();
|
|
|
|
void registerVectorizerTestPass();
|
|
|
|
} // namespace mlir
|
|
|
|
|
2020-05-19 00:44:26 +08:00
|
|
|
#ifdef MLIR_INCLUDE_TESTS
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestPasses() {
|
2020-08-14 00:53:07 +08:00
|
|
|
registerConvertCallOpPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerConvertToTargetEnvPass();
|
|
|
|
registerInliner();
|
|
|
|
registerMemRefBoundCheck();
|
|
|
|
registerPassManagerTestPass();
|
|
|
|
registerPatternsTestPass();
|
2020-02-25 02:35:33 +08:00
|
|
|
registerPrintOpAvailabilityPass();
|
[mlir][SideEffects] Define a set of interfaces and traits for defining side effects
This revision introduces the infrastructure for defining side-effects and attaching them to operations. This infrastructure allows for defining different types of side effects, that don't interact with each other, but use the same internal mechanisms. At the base of this is an interface that allows operations to specify the different effect instances that are exhibited by a specific operation instance. An effect instance is comprised of the following:
* Effect: The specific effect being applied.
For memory related effects this may be reading from memory, storing to memory, etc.
* Value: A specific value, either operand/result/region argument, the effect pertains to.
* Resource: This is a global entity that represents the domain within which the effect is being applied.
MLIR serves many different abstractions, which cover many different domains. Simple effects are may have very different context, for example writing to an in-memory buffer vs a database. This revision defines uses this infrastructure to define a set of initial MemoryEffects. The are effects that generally correspond to memory of some kind; Allocate, Free, Read, Write.
This set of memory effects will be used in follow revisions to generalize various parts of the compiler, and make others more powerful(e.g. DCE).
This infrastructure was originally proposed here:
https://groups.google.com/a/tensorflow.org/g/mlir/c/v2mNl4vFCUM
Differential Revision: https://reviews.llvm.org/D74439
2020-03-07 05:53:16 +08:00
|
|
|
registerSideEffectTestPasses();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerSimpleParametricTilingPass();
|
2020-09-11 07:47:29 +08:00
|
|
|
registerSliceAnalysisTestPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerSymbolTestPasses();
|
2020-02-15 05:41:01 +08:00
|
|
|
registerTestAffineDataCopyPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestAllReduceLoweringPass();
|
2020-04-10 19:42:49 +08:00
|
|
|
registerTestAffineLoopUnswitchingPass();
|
2020-03-29 02:49:09 +08:00
|
|
|
registerTestLoopPermutationPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestCallGraphPass();
|
2020-09-08 16:31:52 +08:00
|
|
|
registerTestConvVectorization();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestConstantFold();
|
2020-03-22 18:13:40 +08:00
|
|
|
#if MLIR_CUDA_CONVERSIONS_ENABLED
|
|
|
|
registerTestConvertGPUKernelToCubinPass();
|
2020-05-23 05:25:00 +08:00
|
|
|
#endif
|
|
|
|
#if MLIR_ROCM_CONVERSIONS_ENABLED
|
|
|
|
registerTestConvertGPUKernelToHsacoPass();
|
2020-03-22 18:13:40 +08:00
|
|
|
#endif
|
2020-09-18 02:07:21 +08:00
|
|
|
registerTestAffineLoopParametricTilingPass();
|
Providing buffer assignment for MLIR
We have provided a generic buffer assignment transformation ported from
TensorFlow. This generic transformation pass automatically analyzes the values
and their aliases (also in other blocks) and returns the valid positions for
Alloc and Dealloc operations. To find these positions, the algorithm uses the
block Dominator and Post-Dominator analyses. In our proposed algorithm, we have
considered aliasing, liveness, nested regions, branches, conditional branches,
critical edges, and independency to custom block terminators. This
implementation doesn't support block loops. However, we have considered this in
our design. For this purpose, it is only required to have a loop analysis to
insert Alloc and Dealloc operations outside of these loops in some special
cases.
Differential Revision: https://reviews.llvm.org/D78484
2020-04-20 18:41:14 +08:00
|
|
|
registerTestBufferPlacementPreparationPass();
|
2020-03-03 17:33:16 +08:00
|
|
|
registerTestDominancePass();
|
2020-09-22 08:51:27 +08:00
|
|
|
registerTestDynamicPipelinePass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestFunc();
|
2020-06-16 01:26:32 +08:00
|
|
|
registerTestExpandTanhPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestGpuMemoryPromotionPass();
|
2020-07-01 06:42:52 +08:00
|
|
|
registerTestInterfaces();
|
2020-10-01 05:55:59 +08:00
|
|
|
registerTestLinalgFusionTransforms();
|
2020-06-05 06:55:26 +08:00
|
|
|
registerTestLinalgHoisting();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestLinalgTransforms();
|
|
|
|
registerTestLivenessPass();
|
|
|
|
registerTestLoopFusion();
|
|
|
|
registerTestLoopMappingPass();
|
[MLIR][LoopOps] Adds the loop unroll transformation for loop::ForOp.
Summary:
Adds the loop unroll transformation for loop::ForOp.
Adds support for promoting the body of single-iteration loop::ForOps into its containing block.
Adds check tests for loop::ForOps with dynamic and static lower/upper bounds and step.
Care was taken to share code (where possible) with the AffineForOp unroll transformation to ease maintenance and potential future transition to a LoopLike construct on which loop transformations for different loop types can implemented.
Reviewers: ftynse, nicolasvasilache
Reviewed By: ftynse
Subscribers: bondhugula, mgorny, zzheng, mehdi_amini, rriddle, jpienaar, shauheen, antiagainst, nicolasvasilache, arpith-jacob, mgester, lucyrfox, aartbik, liufengdb, Joonsoo, grosul1, frgossen, Kayjukh, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79184
2020-05-06 01:29:09 +08:00
|
|
|
registerTestLoopUnrollingPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestMatchers();
|
|
|
|
registerTestMemRefDependenceCheck();
|
|
|
|
registerTestMemRefStrideCalculation();
|
|
|
|
registerTestOpaqueLoc();
|
2020-06-03 00:12:57 +08:00
|
|
|
registerTestPreparationPassWithAllowedMemrefResults();
|
2020-09-08 08:06:37 +08:00
|
|
|
registerTestPrintDefUsePass();
|
|
|
|
registerTestPrintNestingPass();
|
2020-07-22 19:03:24 +08:00
|
|
|
registerTestRecursiveTypesPass();
|
2020-07-11 08:46:55 +08:00
|
|
|
registerTestReducer();
|
2020-02-21 23:18:22 +08:00
|
|
|
registerTestGpuParallelLoopMappingPass();
|
2020-07-29 02:47:30 +08:00
|
|
|
registerTestSpirvEntryPointABIPass();
|
2020-05-29 18:42:35 +08:00
|
|
|
registerTestSCFUtilsPass();
|
2020-10-14 04:58:19 +08:00
|
|
|
registerTestTraitsPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestVectorConversions();
|
|
|
|
registerVectorizerTestPass();
|
|
|
|
}
|
2020-05-19 00:44:26 +08:00
|
|
|
#endif
|
2020-02-12 17:03:40 +08:00
|
|
|
|
2018-06-25 00:10:36 +08:00
|
|
|
int main(int argc, char **argv) {
|
2020-02-12 17:03:40 +08:00
|
|
|
registerAllDialects();
|
|
|
|
registerAllPasses();
|
2020-05-19 00:44:26 +08:00
|
|
|
#ifdef MLIR_INCLUDE_TESTS
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestPasses();
|
2020-05-19 00:44:26 +08:00
|
|
|
#endif
|
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 ®istry) 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 04:01:19 +08:00
|
|
|
DialectRegistry registry;
|
|
|
|
registerAllDialects(registry);
|
2020-08-27 12:01:23 +08:00
|
|
|
#ifdef MLIR_INCLUDE_TESTS
|
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 ®istry) 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 04:01:19 +08:00
|
|
|
registerTestDialect(registry);
|
2020-08-27 12:01:23 +08:00
|
|
|
#endif
|
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 ®istry) 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 04:01:19 +08:00
|
|
|
return failed(MlirOptMain(argc, argv, "MLIR modular optimizer driver\n",
|
|
|
|
registry,
|
|
|
|
/*preloadDialectsInContext=*/false));
|
2018-06-22 00:49:33 +08:00
|
|
|
}
|