forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merged main:8ac8c922fb3f into amd-gfx:83d58f188c87
Local branch amd-gfx 83d58f1 Merged main:e9f9467da063 into amd-gfx:f037b7084d35 Remote branch main 8ac8c92 [mlir][irdl] Add IRDL registration
- Loading branch information
Showing
10 changed files
with
357 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
//===- IRDLRegistration.h - IRDL registration -------------------*- C++ -*-===// | ||
// | ||
// This file is licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Manages the registration of MLIR objects from IRDL operations. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef MLIR_DIALECT_IRDL_IRDLREGISTRATION_H | ||
#define MLIR_DIALECT_IRDL_IRDLREGISTRATION_H | ||
|
||
namespace mlir { | ||
struct LogicalResult; | ||
class ModuleOp; | ||
} // namespace mlir | ||
|
||
namespace mlir { | ||
namespace irdl { | ||
|
||
/// Load all the dialects defined in the module. | ||
LogicalResult loadDialects(ModuleOp op); | ||
|
||
} // namespace irdl | ||
} // namespace mlir | ||
|
||
#endif // MLIR_DIALECT_IRDL_IRDLREGISTRATION_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
add_mlir_dialect_library(MLIRIRDL | ||
IR/IRDL.cpp | ||
IRDLLoading.cpp | ||
|
||
DEPENDS | ||
MLIRIRDLIncGen | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
//===- IRDLLoading.cpp - IRDL dialect loading --------------------- C++ -*-===// | ||
// | ||
// This file is licensed under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// Manages the loading of MLIR objects from IRDL operations. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "mlir/Dialect/IRDL/IRDLLoading.h" | ||
#include "mlir/Dialect/IRDL/IR/IRDL.h" | ||
#include "mlir/IR/BuiltinOps.h" | ||
#include "mlir/IR/ExtensibleDialect.h" | ||
#include "mlir/Support/LogicalResult.h" | ||
#include "llvm/ADT/STLExtras.h" | ||
#include "llvm/ADT/SmallPtrSet.h" | ||
#include "llvm/Support/SMLoc.h" | ||
|
||
using namespace mlir; | ||
using namespace mlir::irdl; | ||
|
||
/// Define and load an operation represented by a `irdl.operation` | ||
/// operation. | ||
static WalkResult loadOperation(OperationOp op, ExtensibleDialect *dialect) { | ||
// IRDL does not support defining custom parsers or printers. | ||
auto parser = [](OpAsmParser &parser, OperationState &result) { | ||
return failure(); | ||
}; | ||
auto printer = [](Operation *op, OpAsmPrinter &printer, StringRef) { | ||
printer.printGenericOp(op); | ||
}; | ||
|
||
auto verifier = [](Operation *op) { return success(); }; | ||
|
||
// IRDL does not support defining regions. | ||
auto regionVerifier = [](Operation *op) { return success(); }; | ||
|
||
auto opDef = DynamicOpDefinition::get( | ||
op.getName(), dialect, std::move(verifier), std::move(regionVerifier), | ||
std::move(parser), std::move(printer)); | ||
dialect->registerDynamicOp(std::move(opDef)); | ||
|
||
return WalkResult::advance(); | ||
} | ||
|
||
/// Load all dialects in the given module, without loading any operation, type | ||
/// or attribute definitions. | ||
static DenseMap<DialectOp, ExtensibleDialect *> loadEmptyDialects(ModuleOp op) { | ||
DenseMap<DialectOp, ExtensibleDialect *> dialects; | ||
op.walk([&](DialectOp dialectOp) { | ||
MLIRContext *ctx = dialectOp.getContext(); | ||
StringRef dialectName = dialectOp.getName(); | ||
|
||
DynamicDialect *dialect = ctx->getOrLoadDynamicDialect( | ||
dialectName, [](DynamicDialect *dialect) {}); | ||
|
||
dialects.insert({dialectOp, dialect}); | ||
}); | ||
return dialects; | ||
} | ||
|
||
/// Preallocate type definitions objects with empty verifiers. | ||
/// This in particular allocates a TypeID for each type definition. | ||
static DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> | ||
preallocateTypeDefs(ModuleOp op, | ||
DenseMap<DialectOp, ExtensibleDialect *> dialects) { | ||
DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> typeDefs; | ||
op.walk([&](TypeOp typeOp) { | ||
ExtensibleDialect *dialect = dialects[typeOp.getParentOp()]; | ||
auto typeDef = DynamicTypeDefinition::get( | ||
typeOp.getName(), dialect, | ||
[](function_ref<InFlightDiagnostic()>, ArrayRef<Attribute>) { | ||
return success(); | ||
}); | ||
typeDefs.try_emplace(typeOp, std::move(typeDef)); | ||
}); | ||
return typeDefs; | ||
} | ||
|
||
/// Preallocate attribute definitions objects with empty verifiers. | ||
/// This in particular allocates a TypeID for each attribute definition. | ||
static DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> | ||
preallocateAttrDefs(ModuleOp op, | ||
DenseMap<DialectOp, ExtensibleDialect *> dialects) { | ||
DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> attrDefs; | ||
op.walk([&](AttributeOp attrOp) { | ||
ExtensibleDialect *dialect = dialects[attrOp.getParentOp()]; | ||
auto attrDef = DynamicAttrDefinition::get( | ||
attrOp.getName(), dialect, | ||
[](function_ref<InFlightDiagnostic()>, ArrayRef<Attribute>) { | ||
return success(); | ||
}); | ||
attrDefs.try_emplace(attrOp, std::move(attrDef)); | ||
}); | ||
return attrDefs; | ||
} | ||
|
||
LogicalResult mlir::irdl::loadDialects(ModuleOp op) { | ||
// Preallocate all dialects, and type and attribute definitions. | ||
// In particular, this allocates TypeIDs so type and attributes can have | ||
// verifiers that refer to each other. | ||
DenseMap<DialectOp, ExtensibleDialect *> dialects = loadEmptyDialects(op); | ||
DenseMap<TypeOp, std::unique_ptr<DynamicTypeDefinition>> types = | ||
preallocateTypeDefs(op, dialects); | ||
DenseMap<AttributeOp, std::unique_ptr<DynamicAttrDefinition>> attrs = | ||
preallocateAttrDefs(op, dialects); | ||
|
||
// Define and load all operations. | ||
WalkResult res = op.walk([&](OperationOp opOp) { | ||
return loadOperation(opOp, dialects[opOp.getParentOp()]); | ||
}); | ||
if (res.wasInterrupted()) | ||
return failure(); | ||
|
||
// Load all types in their dialects. | ||
for (auto &pair : types) { | ||
ExtensibleDialect *dialect = dialects[pair.first.getParentOp()]; | ||
dialect->registerDynamicType(std::move(pair.second)); | ||
} | ||
|
||
// Load all attributes in their dialects. | ||
for (auto &pair : attrs) { | ||
ExtensibleDialect *dialect = dialects[pair.first.getParentOp()]; | ||
dialect->registerDynamicAttr(std::move(pair.second)); | ||
} | ||
|
||
return success(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,4 +12,5 @@ add_mlir_library(MLIROptLib | |
MLIRParser | ||
MLIRPluginsLib | ||
MLIRSupport | ||
MLIRIRDL | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// RUN: mlir-opt %s --irdl-file=%S/cmath.irdl.mlir | mlir-opt --irdl-file=%S/cmath.irdl.mlir | FileCheck %s | ||
|
||
module { | ||
// CHECK: func.func @conorm(%[[p:[^:]*]]: !cmath.complex<f32>, %[[q:[^:]*]]: !cmath.complex<f32>) -> f32 { | ||
// CHECK: %[[norm_p:[^ ]*]] = "cmath.norm"(%[[p]]) : (!cmath.complex<f32>) -> f32 | ||
// CHECK: %[[norm_q:[^ ]*]] = "cmath.norm"(%[[q]]) : (!cmath.complex<f32>) -> f32 | ||
// CHECK: %[[pq:[^ ]*]] = arith.mulf %[[norm_p]], %[[norm_q]] : f32 | ||
// CHECK: return %[[pq]] : f32 | ||
// CHECK: } | ||
func.func @conorm(%p: !cmath.complex<f32>, %q: !cmath.complex<f32>) -> f32 { | ||
%norm_p = "cmath.norm"(%p) : (!cmath.complex<f32>) -> f32 | ||
%norm_q = "cmath.norm"(%q) : (!cmath.complex<f32>) -> f32 | ||
%pq = arith.mulf %norm_p, %norm_q : f32 | ||
return %pq : f32 | ||
} | ||
|
||
// CHECK: func.func @conorm2(%[[p:[^:]*]]: !cmath.complex<f32>, %[[q:[^:]*]]: !cmath.complex<f32>) -> f32 { | ||
// CHECK: %[[pq:[^ ]*]] = "cmath.mul"(%[[p]], %[[q]]) : (!cmath.complex<f32>, !cmath.complex<f32>) -> !cmath.complex<f32> | ||
// CHECK: %[[conorm:[^ ]*]] = "cmath.norm"(%[[pq]]) : (!cmath.complex<f32>) -> f32 | ||
// CHECK: return %[[conorm]] : f32 | ||
// CHECK: } | ||
func.func @conorm2(%p: !cmath.complex<f32>, %q: !cmath.complex<f32>) -> f32 { | ||
%pq = "cmath.mul"(%p, %q) : (!cmath.complex<f32>, !cmath.complex<f32>) -> !cmath.complex<f32> | ||
%conorm = "cmath.norm"(%pq) : (!cmath.complex<f32>) -> f32 | ||
return %conorm : f32 | ||
} | ||
} |
Oops, something went wrong.