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
|
|
|
// Defined in the test directory, no public header.
|
2020-11-05 05:18:26 +08:00
|
|
|
namespace mlir {
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerConvertToTargetEnvPass();
|
|
|
|
void registerPassManagerTestPass();
|
2020-02-25 02:35:33 +08:00
|
|
|
void registerPrintOpAvailabilityPass();
|
2020-11-30 03:15:30 +08:00
|
|
|
void registerShapeFunctionTestPasses();
|
[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-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-04-10 19:42:49 +08:00
|
|
|
void registerTestAffineLoopUnswitchingPass();
|
2020-07-29 20:58:09 +08:00
|
|
|
void registerTestAllReduceLoweringPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
void registerTestFunc();
|
|
|
|
void registerTestGpuMemoryPromotionPass();
|
|
|
|
void registerTestLoopPermutationPass();
|
|
|
|
void registerTestMatchers();
|
|
|
|
void registerTestPrintDefUsePass();
|
|
|
|
void registerTestPrintNestingPass();
|
|
|
|
void registerTestReducer();
|
|
|
|
void registerTestSpirvEntryPointABIPass();
|
2020-12-23 22:32:31 +08:00
|
|
|
void registerTestSpirvGLSLCanonicalizationPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
void registerTestSpirvModuleCombinerPass();
|
|
|
|
void registerTestTraitsPass();
|
2020-11-08 10:32:35 +08:00
|
|
|
void registerTosaTestQuantUtilAPIPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
void registerVectorizerTestPass();
|
|
|
|
|
|
|
|
namespace test {
|
|
|
|
void registerConvertCallOpPass();
|
|
|
|
void registerInliner();
|
|
|
|
void registerMemRefBoundCheck();
|
|
|
|
void registerPatternsTestPass();
|
|
|
|
void registerSimpleParametricTilingPass();
|
|
|
|
void registerTestAffineLoopParametricTilingPass();
|
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-11-06 11:35:15 +08:00
|
|
|
void registerTestDecomposeCallGraphTypes();
|
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-11-05 05:18:26 +08:00
|
|
|
void registerTestDominancePass();
|
2020-09-22 08:51:27 +08:00
|
|
|
void registerTestDynamicPipelinePass();
|
2020-06-16 01:26:32 +08:00
|
|
|
void registerTestExpandTanhPass();
|
2020-07-29 20:58:09 +08:00
|
|
|
void registerTestGpuParallelLoopMappingPass();
|
2020-07-01 06:42:52 +08:00
|
|
|
void registerTestInterfaces();
|
2020-10-14 17:02:47 +08:00
|
|
|
void registerTestLinalgCodegenStrategy();
|
2020-10-01 05:55:59 +08:00
|
|
|
void registerTestLinalgFusionTransforms();
|
2021-01-29 02:51:01 +08:00
|
|
|
void registerTestLinalgTensorFusionTransforms();
|
2020-10-29 22:02:56 +08:00
|
|
|
void registerTestLinalgGreedyFusion();
|
2020-06-05 06:55:26 +08:00
|
|
|
void registerTestLinalgHoisting();
|
2020-11-24 02:07:34 +08:00
|
|
|
void registerTestLinalgTileAndFuseSequencePass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestLinalgTransforms();
|
|
|
|
void registerTestLivenessPass();
|
|
|
|
void registerTestLoopFusion();
|
|
|
|
void 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
|
|
|
void registerTestLoopUnrollingPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestMemRefDependenceCheck();
|
|
|
|
void registerTestMemRefStrideCalculation();
|
2020-11-11 17:38:51 +08:00
|
|
|
void registerTestNumberOfBlockExecutionsPass();
|
|
|
|
void registerTestNumberOfOperationExecutionsPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestOpaqueLoc();
|
[mlir][PDL] Add support for PDL bytecode and expose PDL support to OwningRewritePatternList
PDL patterns are now supported via a new `PDLPatternModule` class. This class contains a ModuleOp with the pdl::PatternOp operations representing the patterns, as well as a collection of registered C++ functions for native constraints/creations/rewrites/etc. that may be invoked via the pdl patterns. Instances of this class are added to an OwningRewritePatternList in the same fashion as C++ RewritePatterns, i.e. via the `insert` method.
The PDL bytecode is an in-memory representation of the PDL interpreter dialect that can be efficiently interpreted/executed. The representation of the bytecode boils down to a code array(for opcodes/memory locations/etc) and a memory buffer(for storing attributes/operations/values/any other data necessary). The bytecode operations are effectively a 1-1 mapping to the PDLInterp dialect operations, with a few exceptions in cases where the in-memory representation of the bytecode can be more efficient than the MLIR representation. For example, a generic `AreEqual` bytecode op can be used to represent AreEqualOp, CheckAttributeOp, and CheckTypeOp.
The execution of the bytecode is split into two phases: matching and rewriting. When matching, all of the matched patterns are collected to avoid the overhead of re-running parts of the matcher. These matched patterns are then considered alongside the native C++ patterns, which rewrite immediately in-place via `RewritePattern::matchAndRewrite`, for the given root operation. When a PDL pattern is matched and has the highest benefit, it is passed back to the bytecode to execute its rewriter.
Differential Revision: https://reviews.llvm.org/D89107
2020-12-02 06:30:18 +08:00
|
|
|
void registerTestPDLByteCodePass();
|
2020-06-03 00:12:57 +08:00
|
|
|
void registerTestPreparationPassWithAllowedMemrefResults();
|
2020-07-22 19:03:24 +08:00
|
|
|
void registerTestRecursiveTypesPass();
|
2020-05-29 18:42:35 +08:00
|
|
|
void registerTestSCFUtilsPass();
|
2020-11-18 04:13:18 +08:00
|
|
|
void registerTestSparsification();
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestVectorConversions();
|
2020-11-05 05:18:26 +08:00
|
|
|
} // namespace test
|
2020-02-12 17:03:40 +08:00
|
|
|
} // namespace mlir
|
|
|
|
|
2020-05-19 00:44:26 +08:00
|
|
|
#ifdef MLIR_INCLUDE_TESTS
|
2020-02-12 17:03:40 +08:00
|
|
|
void registerTestPasses() {
|
|
|
|
registerConvertToTargetEnvPass();
|
|
|
|
registerPassManagerTestPass();
|
2020-02-25 02:35:33 +08:00
|
|
|
registerPrintOpAvailabilityPass();
|
2020-11-30 03:15:30 +08:00
|
|
|
registerShapeFunctionTestPasses();
|
[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-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-04-10 19:42:49 +08:00
|
|
|
registerTestAffineLoopUnswitchingPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
registerTestAllReduceLoweringPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestFunc();
|
|
|
|
registerTestGpuMemoryPromotionPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
registerTestLoopPermutationPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerTestMatchers();
|
2020-09-08 08:06:37 +08:00
|
|
|
registerTestPrintDefUsePass();
|
|
|
|
registerTestPrintNestingPass();
|
2020-07-11 08:46:55 +08:00
|
|
|
registerTestReducer();
|
2020-07-29 02:47:30 +08:00
|
|
|
registerTestSpirvEntryPointABIPass();
|
2020-12-23 22:32:31 +08:00
|
|
|
registerTestSpirvGLSLCanonicalizationPass();
|
2020-10-31 02:36:19 +08:00
|
|
|
registerTestSpirvModuleCombinerPass();
|
2020-10-14 04:58:19 +08:00
|
|
|
registerTestTraitsPass();
|
2020-02-12 17:03:40 +08:00
|
|
|
registerVectorizerTestPass();
|
2020-11-08 10:32:35 +08:00
|
|
|
registerTosaTestQuantUtilAPIPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
|
|
|
|
test::registerConvertCallOpPass();
|
|
|
|
test::registerInliner();
|
|
|
|
test::registerMemRefBoundCheck();
|
|
|
|
test::registerPatternsTestPass();
|
|
|
|
test::registerSimpleParametricTilingPass();
|
|
|
|
test::registerTestAffineLoopParametricTilingPass();
|
|
|
|
test::registerTestCallGraphPass();
|
|
|
|
test::registerTestConstantFold();
|
|
|
|
#if MLIR_CUDA_CONVERSIONS_ENABLED
|
|
|
|
test::registerTestConvertGPUKernelToCubinPass();
|
|
|
|
#endif
|
|
|
|
#if MLIR_ROCM_CONVERSIONS_ENABLED
|
|
|
|
test::registerTestConvertGPUKernelToHsacoPass();
|
|
|
|
#endif
|
|
|
|
test::registerTestConvVectorization();
|
2020-11-06 11:35:15 +08:00
|
|
|
test::registerTestDecomposeCallGraphTypes();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestDominancePass();
|
|
|
|
test::registerTestDynamicPipelinePass();
|
|
|
|
test::registerTestExpandTanhPass();
|
|
|
|
test::registerTestGpuParallelLoopMappingPass();
|
|
|
|
test::registerTestInterfaces();
|
|
|
|
test::registerTestLinalgCodegenStrategy();
|
|
|
|
test::registerTestLinalgFusionTransforms();
|
2021-01-29 02:51:01 +08:00
|
|
|
test::registerTestLinalgTensorFusionTransforms();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestLinalgGreedyFusion();
|
|
|
|
test::registerTestLinalgHoisting();
|
2020-11-24 02:07:34 +08:00
|
|
|
test::registerTestLinalgTileAndFuseSequencePass();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestLinalgTransforms();
|
|
|
|
test::registerTestLivenessPass();
|
|
|
|
test::registerTestLoopFusion();
|
|
|
|
test::registerTestLoopMappingPass();
|
|
|
|
test::registerTestLoopUnrollingPass();
|
|
|
|
test::registerTestMemRefDependenceCheck();
|
|
|
|
test::registerTestMemRefStrideCalculation();
|
2020-11-11 17:38:51 +08:00
|
|
|
test::registerTestNumberOfBlockExecutionsPass();
|
|
|
|
test::registerTestNumberOfOperationExecutionsPass();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestOpaqueLoc();
|
[mlir][PDL] Add support for PDL bytecode and expose PDL support to OwningRewritePatternList
PDL patterns are now supported via a new `PDLPatternModule` class. This class contains a ModuleOp with the pdl::PatternOp operations representing the patterns, as well as a collection of registered C++ functions for native constraints/creations/rewrites/etc. that may be invoked via the pdl patterns. Instances of this class are added to an OwningRewritePatternList in the same fashion as C++ RewritePatterns, i.e. via the `insert` method.
The PDL bytecode is an in-memory representation of the PDL interpreter dialect that can be efficiently interpreted/executed. The representation of the bytecode boils down to a code array(for opcodes/memory locations/etc) and a memory buffer(for storing attributes/operations/values/any other data necessary). The bytecode operations are effectively a 1-1 mapping to the PDLInterp dialect operations, with a few exceptions in cases where the in-memory representation of the bytecode can be more efficient than the MLIR representation. For example, a generic `AreEqual` bytecode op can be used to represent AreEqualOp, CheckAttributeOp, and CheckTypeOp.
The execution of the bytecode is split into two phases: matching and rewriting. When matching, all of the matched patterns are collected to avoid the overhead of re-running parts of the matcher. These matched patterns are then considered alongside the native C++ patterns, which rewrite immediately in-place via `RewritePattern::matchAndRewrite`, for the given root operation. When a PDL pattern is matched and has the highest benefit, it is passed back to the bytecode to execute its rewriter.
Differential Revision: https://reviews.llvm.org/D89107
2020-12-02 06:30:18 +08:00
|
|
|
test::registerTestPDLByteCodePass();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestRecursiveTypesPass();
|
|
|
|
test::registerTestSCFUtilsPass();
|
2020-11-18 04:13:18 +08:00
|
|
|
test::registerTestSparsification();
|
2020-11-05 05:18:26 +08:00
|
|
|
test::registerTestVectorConversions();
|
2020-02-12 17:03:40 +08:00
|
|
|
}
|
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
|
|
|
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
|
2020-11-05 05:18:26 +08:00
|
|
|
test::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
|
|
|
}
|