[Mlir-commits] [mlir] [MLIR] Reduce generated assembly printer compile time (NFC) (PR #225740)
Mehdi Amini
llvmlistbot at llvm.org
Wed Sep 23 06:18:10 PDT 2026
https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/225740
>From edf24c1440134c729c4358031f97703579848451 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Wed, 23 Sep 2026 04:53:47 -0700
Subject: [PATCH 1/2] [mlir] Reduce generated assembly printer compile time
Use fixed arrays for statically elided attributes and combine leading spaces
with literals. Initialize fixed elisions together when runtime elision is
needed; in strict properties mode, print discardable attributes directly.
Move common operand printing out of generated call sites and emit sliced
operand getters to reduce optimizer work in large printers.
For omp.target, the original patch reduced optimized print IR from 3,893 to
2,667 instructions. Its printing benchmark was 2.1% slower. check-mlir
passed before this follow-up.
Assisted-by: Codex
---
mlir/include/mlir/IR/OpImplementation.h | 18 ++++++++
mlir/lib/IR/AsmPrinter.cpp | 9 ++++
mlir/test/mlir-tblgen/op-decl-and-defs.td | 2 +
mlir/test/mlir-tblgen/op-format.td | 38 +++++++++++----
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 9 +++-
mlir/tools/mlir-tblgen/OpFormatGen.cpp | 51 +++++++++++++++++----
6 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index 63dde74c33d519..45385e06c3c27b 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -475,6 +475,13 @@ class OpAsmPrinter : public AsmPrinter {
virtual void printOperand(Value value) = 0;
virtual void printOperand(Value value, raw_ostream &os) = 0;
+ /// Print a comma separated range of operation operands out of line to avoid
+ /// instantiating the range iteration in every generated operation printer.
+ void printOperands(OperandRange operands);
+
+ /// Print the types of a comma separated range of operation operands.
+ void printOperandTypes(ValueTypeRange<OperandRange> types);
+
/// Print a comma separated list of operands.
template <typename ContainerType>
void printOperands(const ContainerType &container) {
@@ -562,6 +569,17 @@ inline OpAsmPrinter &operator<<(OpAsmPrinter &p, Value value) {
return p;
}
+inline OpAsmPrinter &operator<<(OpAsmPrinter &p, OperandRange values) {
+ p.printOperands(values);
+ return p;
+}
+
+inline OpAsmPrinter &operator<<(OpAsmPrinter &p,
+ ValueTypeRange<OperandRange> types) {
+ p.printOperandTypes(types);
+ return p;
+}
+
template <typename T,
std::enable_if_t<std::is_convertible<T &, ValueRange>::value &&
!std::is_convertible<T &, Value &>::value,
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index f7e269867c9be2..f78d33338904b0 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -91,6 +91,15 @@ DialectAsmPrinter::~DialectAsmPrinter() = default;
OpAsmPrinter::~OpAsmPrinter() = default;
+void OpAsmPrinter::printOperands(OperandRange operands) {
+ llvm::interleaveComma(operands, getStream(),
+ [this](Value value) { printOperand(value); });
+}
+
+void OpAsmPrinter::printOperandTypes(ValueTypeRange<OperandRange> types) {
+ llvm::interleaveComma(types, *this);
+}
+
void OpAsmPrinter::printFunctionalType(Operation *op) {
auto &os = getStream();
os << '(';
diff --git a/mlir/test/mlir-tblgen/op-decl-and-defs.td b/mlir/test/mlir-tblgen/op-decl-and-defs.td
index 32c4bb88d188be..5b4b0b4bc0a494 100644
--- a/mlir/test/mlir-tblgen/op-decl-and-defs.td
+++ b/mlir/test/mlir-tblgen/op-decl-and-defs.td
@@ -100,6 +100,8 @@ def NS_AOp : NS_Op<"a_op", [IsolatedFromAbove, IsolatedFromAbove]> {
// CHECK: return ::llvm::StringLiteral("test.a_op");
// CHECK: }
// CHECK: ::mlir::Operation::operand_range getODSOperands(unsigned index) {
+// CHECK-NEXT: auto [start, length] = getODSOperandIndexAndLength(index);
+// CHECK-NEXT: return getOperation()->getOperands().slice(start, length);
// CHECK: ::mlir::TypedValue<::mlir::IntegerType> getA() {
// CHECK: ::mlir::Operation::operand_range getB() {
// CHECK: ::mlir::OpOperand &getAMutable() {
diff --git a/mlir/test/mlir-tblgen/op-format.td b/mlir/test/mlir-tblgen/op-format.td
index f7f0c1b212e044..979480c0f8f782 100644
--- a/mlir/test/mlir-tblgen/op-format.td
+++ b/mlir/test/mlir-tblgen/op-format.td
@@ -32,6 +32,7 @@ class TestStrictPropertiesFormat_Op<string fmt, list<Trait> traits = []>
// CHECK: // coverity[ARRAY_VS_SINGLETON]
// CHECK-NEXT: if (parser.resolveOperands(
// CHECK-LABEL: AttrDictContextOperand::print
+// CHECK: ::llvm::ArrayRef<::llvm::StringRef> elidedAttrs;
// CHECK: _odsPrinter.printOptionalAttrDict(_odsAttrs.getDictionary((*this)->getContext()).getValue(), elidedAttrs);
def AttrDictContextOperand : TestFormat_Op<[{
$context `:` type($context) attr-dict
@@ -43,10 +44,32 @@ def AttrDictDefaultInherentAttr : TestFormat_Op<[{
$attr attr-dict
}]>, Arguments<(ins I64Attr:$attr)>;
+// CHECK-LABEL: AttrDictElideDefaultAndFixedAttr::print
+// CHECK: ::llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs = {"used"};
+// CHECK: elidedAttrs.push_back("attr");
+def AttrDictElideDefaultAndFixedAttr : TestFormat_Op<"$used attr-dict">,
+ Arguments<(ins I64Attr:$used,
+ DefaultValuedStrAttr<StrAttr, "default">:$attr)>;
+
+// CHECK-LABEL: AttrDictElideDefaultAttr::print
+// CHECK: ::llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs = {};
+// CHECK: if(attr && (attr ==
+// CHECK: elidedAttrs.push_back("attr");
+def AttrDictElideDefaultAttr : TestFormat_Op<"attr-dict">,
+ Arguments<(ins DefaultValuedStrAttr<StrAttr, "default">:$attr)>;
+
+// CHECK-LABEL: AttrDictStrictDefaultAttr::print
+// CHECK-NOT: elidedAttrs
+// CHECK: _odsPrinter.printOptionalAttrDict((*this)->getDiscardableAttrDictionary().getValue());
+def AttrDictStrictDefaultAttr : TestStrictPropertiesFormat_Op<
+ "prop-dict attr-dict">,
+ Arguments<(ins DefaultValuedStrAttr<StrAttr, "default">:$attr)>;
+
// CHECK-LABEL: AttrDictStrictInferredSegmentAttr::parse
// CHECK: result.getOrAddProperties<AttrDictStrictInferredSegmentAttr::Properties>().segment_sizes = parser.getBuilder().getDenseI32ArrayAttr(inputsOperandGroupSizes);
// CHECK-LABEL: AttrDictStrictInferredSegmentAttr::print
-// CHECK: elidedAttrs.push_back("segment_sizes");
+// CHECK-NOT: elidedAttrs
+// CHECK: _odsPrinter.printOptionalAttrDict((*this)->getDiscardableAttrDictionary().getValue());
def AttrDictStrictInferredSegmentAttr : TestStrictPropertiesFormat_Op<[{
custom<Foo>($inputs, type($inputs)) attr-dict
}]>, Arguments<(ins VariadicOfVariadic<I64, "segment_sizes">:$inputs,
@@ -85,6 +108,7 @@ def AttrDictStrictPropDictInherentAttr : TestStrictPropertiesFormat_Op<[{
// CHECK: parseFoo({{.*}}, parser.getBuilder().getI1Type())
// CHECK-LABEL: CustomStringLiteralA::print
// CHECK: printFoo({{.*}}, ::mlir::Builder(getContext()).getI1Type())
+// CHECK: ::llvm::ArrayRef<::llvm::StringRef> elidedAttrs;
def CustomStringLiteralA : TestFormat_Op<[{
custom<Foo>("$_builder.getI1Type()") attr-dict
}]>;
@@ -329,7 +353,7 @@ def LegacyUnquotedBitEnumOp : TestFormat_Op<"$attr attr-dict">,
// CHECK: parser.parseOptionalOperand
// CHECK-LABEL: OptionalGroupA::print
// CHECK: if (!getA())
-// CHECK-NEXT: odsPrinter << ' ' << "?";
+// CHECK-NEXT: odsPrinter << " ?";
// CHECK-NEXT: else
// CHECK: odsPrinter << value;
def OptionalGroupA : TestFormat_Op<[{
@@ -343,9 +367,9 @@ def OptionalGroupA : TestFormat_Op<[{
// CHECK: parser.parseKeyword("bar")
// CHECK-LABEL: OptionalGroupB::print
// CHECK: if (!(getAAttr() && getAAttr() != ((false) ? ::mlir::OpBuilder((*this)->getContext()).getUnitAttr() : nullptr)))
-// CHECK-NEXT: odsPrinter << ' ' << "foo"
+// CHECK-NEXT: odsPrinter << " foo"
// CHECK-NEXT: else
-// CHECK-NEXT: odsPrinter << ' ' << "bar"
+// CHECK-NEXT: odsPrinter << " bar"
def OptionalGroupB : TestFormat_Op<[{
(`foo`) : (`bar` $a^)? attr-dict
}]>, Arguments<(ins UnitAttr:$a)>;
@@ -357,8 +381,7 @@ def OptionalGroupB : TestFormat_Op<[{
// CHECK-NEXT: odsPrinter << ' ';
// CHECK-NEXT: odsPrinter.printAttributeWithoutType(getAAttr());
// CHECK-NEXT: }
-// CHECK: elidedAttrs.push_back("a");
-// CHECK-NOT: elidedAttrs.push_back("a");
+// CHECK: static constexpr ::llvm::StringRef elidedAttrs[] = {"a"};
// CHECK: _odsPrinter.printOptionalAttrDict
def OptionalGroupC : TestFormat_Op<[{
($a^)? attr-dict
@@ -368,8 +391,7 @@ def OptionalGroupC : TestFormat_Op<[{
// CHECK: elidedProps.push_back("a");
// CHECK-NOT: elidedProps.push_back("a");
// CHECK: printProperties
-// CHECK: elidedAttrs.push_back("a");
-// CHECK-NOT: elidedAttrs.push_back("a");
+// CHECK: static constexpr ::llvm::StringRef elidedAttrs[] = {"a"};
// CHECK: _odsPrinter.printOptionalAttrDict
def OptionalGroupCPropDict : TestFormat_Op<[{
($a^)? prop-dict attr-dict
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index aa9ff159903bc6..95cb292bbe7fc6 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -2108,8 +2108,13 @@ generateNamedOperandGetters(const Operator &op, Class &opClass,
MethodParameter("unsigned", "index"));
ERROR_IF_PRUNED(m, "getODSOperands", op);
auto &body = m->body();
- body << formatv(valueRangeReturnCode, rangeBeginCall,
- "getODSOperandIndexAndLength(index)");
+ if (isGenericAdaptorBase) {
+ body << formatv(valueRangeReturnCode, rangeBeginCall,
+ "getODSOperandIndexAndLength(index)");
+ } else {
+ body << " auto [start, length] = getODSOperandIndexAndLength(index);\n"
+ " return getOperation()->getOperands().slice(start, length);\n";
+ }
// Then we emit nicer named getter methods by redirecting to the "sink" getter
// method.
diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index becdcc825d5470..83982ca27912c8 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -2723,14 +2723,49 @@ static void genPropDictPrinter(OperationFormat &fmt, Operator &op,
/// Generate the printer for the 'attr-dict' directive.
static void genAttrDictPrinter(OperationFormat &fmt, Operator &op,
MethodBody &body, bool withKeyword) {
- body << " ::llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs;\n";
-
- genVariadicSegmentElision(fmt, op, body, "elidedAttrs");
+ // TODO: Remove the non-strict path when strict properties in assembly
+ // formats are always enabled.
+ if (fmt.useStrictPropertiesInAssemblyFormat) {
+ // Inherent attributes are printed by their bindings or prop-dict.
+ body << " _odsPrinter.printOptionalAttrDict"
+ << (withKeyword ? "WithKeyword" : "")
+ << "((*this)->getDiscardableAttrDictionary().getValue());\n";
+ return;
+ }
+ SmallVector<StringRef> fixedElidedAttrs;
+ if (!fmt.allOperands &&
+ op.getTrait("::mlir::OpTrait::AttrSizedOperandSegments"))
+ fixedElidedAttrs.push_back("operandSegmentSizes");
+ if (!fmt.allResultTypes &&
+ op.getTrait("::mlir::OpTrait::AttrSizedResultSegments"))
+ fixedElidedAttrs.push_back("resultSegmentSizes");
for (StringRef key : fmt.inferredAttributes.keys())
- body << " elidedAttrs.push_back(\"" << key << "\");\n";
+ fixedElidedAttrs.push_back(key);
for (const NamedAttribute *attr : fmt.usedAttributes)
- body << " elidedAttrs.push_back(\"" << attr->name << "\");\n";
+ fixedElidedAttrs.push_back(attr->name);
+
+ bool hasConditionalElision =
+ llvm::any_of(op.getAttributes(), [&](const NamedAttribute &namedAttr) {
+ return !fmt.usedAttributes.contains(&namedAttr) &&
+ !namedAttr.attr.isDerivedAttr() &&
+ namedAttr.attr.hasDefaultValue();
+ });
+ if (hasConditionalElision) {
+ body << " ::llvm::SmallVector<::llvm::StringRef, 2> elidedAttrs = {";
+ llvm::interleaveComma(fixedElidedAttrs, body, [&](StringRef name) {
+ body << "\"" << name << "\"";
+ });
+ body << "};\n";
+ } else if (fixedElidedAttrs.empty()) {
+ body << " ::llvm::ArrayRef<::llvm::StringRef> elidedAttrs;\n";
+ } else {
+ body << " static constexpr ::llvm::StringRef elidedAttrs[] = {";
+ llvm::interleaveComma(fixedElidedAttrs, body, [&](StringRef name) {
+ body << "\"" << name << "\"";
+ });
+ body << "};\n";
+ }
// Add code to check attributes for equality with their default values.
// Default-valued attributes will not be printed when their value matches the
@@ -2779,12 +2814,12 @@ static void genAttrDictPrinter(OperationFormat &fmt, Operator &op,
/// the previous element was a punctuation literal.
static void genLiteralPrinter(StringRef value, MethodBody &body,
bool &shouldEmitSpace, bool &lastWasPunctuation) {
- body << " _odsPrinter";
+ body << " _odsPrinter << \"";
// Don't insert a space for certain punctuation.
if (shouldEmitSpace && shouldEmitSpaceBefore(value, lastWasPunctuation))
- body << " << ' '";
- body << " << \"" << value << "\";\n";
+ body << ' ';
+ body << value << "\";\n";
// Insert a space after certain literals.
shouldEmitSpace =
>From a60a77c6bf9c8abfbf688fb433c59d5dbad63962 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Wed, 23 Sep 2026 06:11:57 -0700
Subject: [PATCH 2/2] [mlir][OpenMP] Split generated operation definitions into
three TUs
Compile independent and helper-backed OpenMP op definitions separately from
the handwritten dialect implementation. Move shared assembly helpers into
the dialect namespace and keep registration in the independent TU.
Outline the repeated block-argument interface body once for all 15 models.
The generated operation partitions cover all 72 OpenMP operations.
Assisted-by: Codex
---
.../mlir/Dialect/OpenMP/CMakeLists.txt | 34 ++++
.../mlir/Dialect/OpenMP/OpenMPDialect.td | 3 +
.../Dialect/OpenMP/OpenMPOpsInterfaces.td | 22 +-
mlir/lib/Dialect/OpenMP/IR/CMakeLists.txt | 2 +
mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 188 ++++++++++--------
.../Dialect/OpenMP/IR/OpenMPGeneratedOps.cpp | 24 +++
mlir/lib/Dialect/OpenMP/IR/OpenMPOpsHelpers.h | 159 +++++++++++++++
.../Dialect/OpenMP/IR/OpenMPOutlinedOps.cpp | 16 ++
8 files changed, 354 insertions(+), 94 deletions(-)
create mode 100644 mlir/lib/Dialect/OpenMP/IR/OpenMPGeneratedOps.cpp
create mode 100644 mlir/lib/Dialect/OpenMP/IR/OpenMPOpsHelpers.h
create mode 100644 mlir/lib/Dialect/OpenMP/IR/OpenMPOutlinedOps.cpp
diff --git a/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt b/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
index 366e7ba60e77bb..e6c0ee5b84b348 100644
--- a/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
+++ b/mlir/include/mlir/Dialect/OpenMP/CMakeLists.txt
@@ -21,6 +21,40 @@ mlir_tablegen(OpenMPOpsDialect.h.inc -gen-dialect-decls -dialect=omp)
mlir_tablegen(OpenMPOpsDialect.cpp.inc -gen-dialect-defs -dialect=omp)
mlir_tablegen(OpenMPOps.h.inc -gen-op-decls)
mlir_tablegen(OpenMPOps.cpp.inc -gen-op-defs)
+# These operations do not refer to helpers defined in OpenMPDialect.cpp, so
+# their definitions can compile in a separate translation unit.
+set(OPENMP_INDEPENDENT_OPS
+ affinity_entry alloc_shared_mem allocate_dir allocate_free barrier
+ canonical_loop critical declare_mapper.info declare_mapper
+ declare_reduction dispatch flush free_shared_mem groupprivate loop_nest
+ map.bounds masked master new_cli ordered ordered.region private scan
+ section target_freemem taskloop.wrapper taskyield terminator threadprivate
+ unroll_full unroll_heuristic unroll_partial workdistribute
+ workshare.loop_wrapper workshare yield)
+list(JOIN OPENMP_INDEPENDENT_OPS "|" OPENMP_INDEPENDENT_OP_NAMES)
+set(OPENMP_DEPEND_OPS
+ interop.destroy interop.init interop.use target_enter_data
+ target_exit_data target_update taskwait)
+set(OPENMP_ATOMIC_OPS
+ atomic.capture atomic.compare atomic.read atomic.update atomic.write
+ cancel cancellation_point critical.declare error)
+set(OPENMP_TASK_OPS task parallel taskgroup teams)
+set(OPENMP_HELPER_OPS ${OPENMP_DEPEND_OPS} ${OPENMP_ATOMIC_OPS}
+ target ${OPENMP_TASK_OPS} scope sections)
+list(JOIN OPENMP_HELPER_OPS "|" OPENMP_HELPER_OP_NAMES)
+set(OPENMP_OUTLINED_OPS ${OPENMP_INDEPENDENT_OPS} ${OPENMP_HELPER_OPS})
+list(JOIN OPENMP_OUTLINED_OPS "|" OPENMP_OUTLINED_OP_NAMES)
+# The doubled '$' reaches TableGen as a regex end anchor through Ninja.
+set(OPENMP_INDEPENDENT_OPS_REGEX "\"^omp[.](${OPENMP_INDEPENDENT_OP_NAMES})$$\"")
+set(OPENMP_HELPER_OPS_REGEX "\"^omp[.](${OPENMP_HELPER_OP_NAMES})$$\"")
+set(OPENMP_OUTLINED_OPS_REGEX
+ "\"^omp[.](${OPENMP_OUTLINED_OP_NAMES})$$\"")
+mlir_tablegen(OpenMPOpsIndependent.cpp.inc -gen-op-defs
+ -op-include-regex=${OPENMP_INDEPENDENT_OPS_REGEX})
+mlir_tablegen(OpenMPOpsOutlined.cpp.inc -gen-op-defs
+ -op-include-regex=${OPENMP_HELPER_OPS_REGEX})
+mlir_tablegen(OpenMPOpsDependent.cpp.inc -gen-op-defs
+ -op-exclude-regex=${OPENMP_OUTLINED_OPS_REGEX})
mlir_tablegen(OpenMPClauseOps.h.inc -gen-openmp-clause-ops)
mlir_tablegen(OpenMPOpsTypes.h.inc -gen-typedef-decls -typedefs-dialect=omp)
mlir_tablegen(OpenMPOpsTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=omp)
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
index dbc851a5e297c2..53bd724ab79332 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPDialect.td
@@ -19,6 +19,9 @@ def OpenMP_Dialect : Dialect {
let useStrictPropertiesInAssemblyFormat = 1;
let useDefaultTypePrinterParser = 1;
let hasOperationAttrVerify = 1;
+ let extraClassDeclaration = [{
+ void registerOperations();
+ }];
}
#endif // OPENMP_DIALECT
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
index a087439c87cb25..191508d129bcfd 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td
@@ -144,6 +144,13 @@ def BlockArgOpenMPOpInterface : OpInterface<"BlockArgOpenMPOpInterface"> {
let cppNamespace = "::mlir::omp";
+ let extraClassDeclaration = [{
+ /// Populate pairs of clause operands and their entry block arguments.
+ void getBlockArgsPairs(
+ ::llvm::SmallVectorImpl<std::pair<::mlir::Value,
+ ::mlir::BlockArgument>> &pairs);
+ }];
+
defvar clauses = [ BlockArgHasDeviceAddrClause, BlockArgHostEvalClause,
BlockArgInReductionClause, BlockArgMapClause, BlockArgPrivateClause,
BlockArgReductionClause, BlockArgTaskReductionClause,
@@ -162,21 +169,6 @@ def BlockArgOpenMPOpInterface : OpInterface<"BlockArgOpenMPOpInterface"> {
"return " # !interleave(
!foreach(clause, clauses, "$_op." # clause.numArgsMethod.name # "()"),
" + ") # ";"
- >,
- InterfaceMethod<
- "Populate a vector of pairs representing the matching between operands "
- "and entry block arguments.", "void", "getBlockArgsPairs",
- (ins "::llvm::SmallVectorImpl<std::pair<::mlir::Value, ::mlir::BlockArgument>> &" : $pairs),
- [{
- auto iface = ::llvm::cast<BlockArgOpenMPOpInterface>(*$_op);
- pairs.reserve(pairs.size() + iface.numClauseBlockArgs());
- }] # !interleave(!foreach(clause, clauses, [{
- }] # "if (iface." # clause.numArgsMethod.name # "() > 0) {" # [{
- }] # " for (auto [var, arg] : ::llvm::zip_equal(" #
- "iface." # clause.varsMethod.name # "()," #
- "iface." # clause.blockArgsMethod.name # "()))" # [{
- pairs.emplace_back(var, arg);
- } }]), "\n")
>
]
);
diff --git a/mlir/lib/Dialect/OpenMP/IR/CMakeLists.txt b/mlir/lib/Dialect/OpenMP/IR/CMakeLists.txt
index 1beea2098d3bb2..2cc332ee541f1d 100644
--- a/mlir/lib/Dialect/OpenMP/IR/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenMP/IR/CMakeLists.txt
@@ -1,5 +1,7 @@
add_mlir_dialect_library(MLIROpenMPDialect
OpenMPDialect.cpp
+ OpenMPGeneratedOps.cpp
+ OpenMPOutlinedOps.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/OpenMP
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index ed144f7b28983e..944c337e4d8356 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "OpenMPOpsHelpers.h"
#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/LLVMIR/LLVMTypes.h"
@@ -48,6 +49,34 @@
using namespace mlir;
using namespace mlir::omp;
+void BlockArgOpenMPOpInterface::getBlockArgsPairs(
+ llvm::SmallVectorImpl<std::pair<Value, BlockArgument>> &pairs) {
+ pairs.reserve(pairs.size() + numClauseBlockArgs());
+ auto appendPairs = [&](auto vars, auto args) {
+ for (auto [var, arg] : llvm::zip_equal(vars, args))
+ pairs.emplace_back(var, arg);
+ };
+
+ if (numHasDeviceAddrBlockArgs())
+ appendPairs(getHasDeviceAddrVars(), getHasDeviceAddrBlockArgs());
+ if (numHostEvalBlockArgs())
+ appendPairs(getHostEvalVars(), getHostEvalBlockArgs());
+ if (numInReductionBlockArgs())
+ appendPairs(getInReductionVars(), getInReductionBlockArgs());
+ if (numMapBlockArgs())
+ appendPairs(getMapVars(), getMapBlockArgs());
+ if (numPrivateBlockArgs())
+ appendPairs(getPrivateVars(), getPrivateBlockArgs());
+ if (numReductionBlockArgs())
+ appendPairs(getReductionVars(), getReductionBlockArgs());
+ if (numTaskReductionBlockArgs())
+ appendPairs(getTaskReductionVars(), getTaskReductionBlockArgs());
+ if (numUseDeviceAddrBlockArgs())
+ appendPairs(getUseDeviceAddrVars(), getUseDeviceAddrBlockArgs());
+ if (numUseDevicePtrBlockArgs())
+ appendPairs(getUseDevicePtrVars(), getUseDevicePtrBlockArgs());
+}
+
static ArrayAttr makeArrayAttr(MLIRContext *context,
llvm::ArrayRef<Attribute> attrs) {
return attrs.empty() ? nullptr : ArrayAttr::get(context, attrs);
@@ -306,10 +335,7 @@ static std::string generateLoopNestingName(StringRef prefix,
}
void OpenMPDialect::initialize() {
- addOperations<
-#define GET_OP_LIST
-#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
- >();
+ registerOperations();
addAttributes<
#define GET_ATTRDEF_LIST
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.cpp.inc"
@@ -395,7 +421,8 @@ OpenMPDialect::verifyOperationAttribute(Operation *op,
/// allocator-operand `,` allocate-operand-list
/// allocate-operand :: = ssa-id-and-type -> ssa-id-and-type
/// ssa-id-and-type ::= ssa-id `:` type
-static ParseResult parseAllocateAndAllocator(
+namespace mlir::omp {
+ParseResult parseAllocateAndAllocator(
OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &allocateVars,
SmallVectorImpl<Type> &allocateTypes,
@@ -421,41 +448,23 @@ static ParseResult parseAllocateAndAllocator(
}
/// Print allocate clause
-static void printAllocateAndAllocator(OpAsmPrinter &p, Operation *op,
- OperandRange allocateVars,
- TypeRange allocateTypes,
- OperandRange allocatorVars,
- TypeRange allocatorTypes) {
+void printAllocateAndAllocator(OpAsmPrinter &p, Operation *op,
+ OperandRange allocateVars,
+ TypeRange allocateTypes,
+ OperandRange allocatorVars,
+ TypeRange allocatorTypes) {
for (unsigned i = 0; i < allocateVars.size(); ++i) {
std::string separator = i == allocateVars.size() - 1 ? "" : ", ";
p << allocatorVars[i] << " : " << allocatorTypes[i] << " -> ";
p << allocateVars[i] << " : " << allocateTypes[i] << separator;
}
}
+} // namespace mlir::omp
//===----------------------------------------------------------------------===//
// Parser and printer for a clause attribute (StringEnumAttr)
//===----------------------------------------------------------------------===//
-template <typename ClauseAttr>
-static ParseResult parseClauseAttr(AsmParser &parser, ClauseAttr &attr) {
- using ClauseT = decltype(std::declval<ClauseAttr>().getValue());
- StringRef enumStr;
- SMLoc loc = parser.getCurrentLocation();
- if (parser.parseKeyword(&enumStr))
- return failure();
- if (std::optional<ClauseT> enumValue = symbolizeEnum<ClauseT>(enumStr)) {
- attr = ClauseAttr::get(parser.getContext(), *enumValue);
- return success();
- }
- return parser.emitError(loc, "invalid clause value: '") << enumStr << "'";
-}
-
-template <typename ClauseAttr>
-static void printClauseAttr(OpAsmPrinter &p, Operation *op, ClauseAttr attr) {
- p << stringifyEnum(attr.getValue());
-}
-
//===----------------------------------------------------------------------===//
// Parser and printer for Linear Clause
//===----------------------------------------------------------------------===//
@@ -1068,7 +1077,8 @@ verifyDynGroupprivateClause(Operation *op, AccessGroupModifierAttr accessGroup,
return success();
}
-static ParseResult parseDynGroupprivateClause(
+namespace mlir::omp {
+ParseResult parseDynGroupprivateClause(
OpAsmParser &parser, AccessGroupModifierAttr &accessGroupAttr,
FallbackModifierAttr &fallbackAttr,
std::optional<OpAsmParser::UnresolvedOperand> &dynGroupprivateSize,
@@ -1137,11 +1147,10 @@ static ParseResult parseDynGroupprivateClause(
});
}
-static void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
- AccessGroupModifierAttr modifierFirst,
- FallbackModifierAttr modifierSecond,
- Value dynGroupprivateSize,
- Type sizeType) {
+void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
+ AccessGroupModifierAttr modifierFirst,
+ FallbackModifierAttr modifierSecond,
+ Value dynGroupprivateSize, Type sizeType) {
bool needsComma = false;
@@ -1165,6 +1174,7 @@ static void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
printer << dynGroupprivateSize << " : " << sizeType;
}
}
+} // namespace mlir::omp
//===----------------------------------------------------------------------===//
// Parser and printer for in_reduction Clause
@@ -1173,7 +1183,8 @@ static void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
/// Parses an `in_reduction` clause for an operation that does not give its
/// list items entry block arguments (e.g. `omp.target`). The expected format is
/// a comma-separated list of `[byref] @sym %var` followed by `: types`.
-static ParseResult parseInReductionClause(
+namespace mlir::omp {
+ParseResult parseInReductionClause(
OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &inReductionVars,
SmallVectorImpl<Type> &inReductionTypes,
@@ -1209,11 +1220,11 @@ static ParseResult parseInReductionClause(
/// Prints an `in_reduction` clause for an operation that does not give its list
/// items entry block arguments (e.g. `omp.target`). Mirrors
/// `parseInReductionClause`.
-static void printInReductionClause(OpAsmPrinter &p, Operation *op,
- ValueRange inReductionVars,
- TypeRange inReductionTypes,
- DenseBoolArrayAttr inReductionByref,
- ArrayAttr inReductionSyms) {
+void printInReductionClause(OpAsmPrinter &p, Operation *op,
+ ValueRange inReductionVars,
+ TypeRange inReductionTypes,
+ DenseBoolArrayAttr inReductionByref,
+ ArrayAttr inReductionSyms) {
MLIRContext *ctx = op->getContext();
ArrayAttr syms = inReductionSyms;
@@ -1241,6 +1252,7 @@ static void printInReductionClause(OpAsmPrinter &p, Operation *op,
p << " : ";
llvm::interleaveComma(inReductionTypes, p);
}
+} // namespace mlir::omp
//===----------------------------------------------------------------------===//
// Parsers for operations including clauses that define entry block arguments.
@@ -1503,7 +1515,8 @@ static ParseResult parseBlockArgRegion(OpAsmParser &parser, Region ®ion,
// These parseXyz functions correspond to the custom<Xyz> definitions
// in the .td file(s).
-static ParseResult parseTargetOpRegion(
+namespace mlir::omp {
+ParseResult parseTargetOpRegion(
OpAsmParser &parser, Region ®ion,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &hasDeviceAddrVars,
SmallVectorImpl<Type> &hasDeviceAddrTypes,
@@ -1522,8 +1535,10 @@ static ParseResult parseTargetOpRegion(
privateNeedsBarrier, &privateMaps);
return parseBlockArgRegion(parser, region, args);
}
+} // namespace mlir::omp
-static ParseResult parseInReductionPrivateRegion(
+namespace mlir::omp {
+ParseResult parseInReductionPrivateRegion(
OpAsmParser &parser, Region ®ion,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &inReductionVars,
SmallVectorImpl<Type> &inReductionTypes,
@@ -1538,6 +1553,7 @@ static ParseResult parseInReductionPrivateRegion(
privateNeedsBarrier);
return parseBlockArgRegion(parser, region, args);
}
+} // namespace mlir::omp
static ParseResult parseInReductionPrivateReductionRegion(
OpAsmParser &parser, Region ®ion,
@@ -1571,7 +1587,8 @@ static ParseResult parsePrivateRegion(
return parseBlockArgRegion(parser, region, args);
}
-static ParseResult parsePrivateReductionRegion(
+namespace mlir::omp {
+ParseResult parsePrivateReductionRegion(
OpAsmParser &parser, Region ®ion,
llvm::SmallVectorImpl<OpAsmParser::UnresolvedOperand> &privateVars,
llvm::SmallVectorImpl<Type> &privateTypes, ArrayAttr &privateSyms,
@@ -1586,8 +1603,10 @@ static ParseResult parsePrivateReductionRegion(
reductionSyms, &reductionMod);
return parseBlockArgRegion(parser, region, args);
}
+} // namespace mlir::omp
-static ParseResult parseTaskReductionRegion(
+namespace mlir::omp {
+ParseResult parseTaskReductionRegion(
OpAsmParser &parser, Region ®ion,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &taskReductionVars,
SmallVectorImpl<Type> &taskReductionTypes,
@@ -1597,6 +1616,7 @@ static ParseResult parseTaskReductionRegion(
taskReductionByref, taskReductionSyms);
return parseBlockArgRegion(parser, region, args);
}
+} // namespace mlir::omp
static ParseResult parseUseDeviceAddrUseDevicePtrRegion(
OpAsmParser &parser, Region ®ion,
@@ -1767,15 +1787,15 @@ static void printBlockArgRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
// These parseXyz functions correspond to the custom<Xyz> definitions
// in the .td file(s).
-static void printTargetOpRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
- ValueRange hasDeviceAddrVars,
- TypeRange hasDeviceAddrTypes,
- ValueRange hostEvalVars,
- TypeRange hostEvalTypes, ValueRange mapVars,
- TypeRange mapTypes, ValueRange privateVars,
- TypeRange privateTypes, ArrayAttr privateSyms,
- UnitAttr privateNeedsBarrier,
- DenseI64ArrayAttr privateMaps) {
+namespace mlir::omp {
+void printTargetOpRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
+ ValueRange hasDeviceAddrVars,
+ TypeRange hasDeviceAddrTypes, ValueRange hostEvalVars,
+ TypeRange hostEvalTypes, ValueRange mapVars,
+ TypeRange mapTypes, ValueRange privateVars,
+ TypeRange privateTypes, ArrayAttr privateSyms,
+ UnitAttr privateNeedsBarrier,
+ DenseI64ArrayAttr privateMaps) {
AllRegionPrintArgs args;
args.hasDeviceAddrArgs.emplace(hasDeviceAddrVars, hasDeviceAddrTypes);
args.hostEvalArgs.emplace(hostEvalVars, hostEvalTypes);
@@ -1784,8 +1804,10 @@ static void printTargetOpRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
privateNeedsBarrier, privateMaps);
printBlockArgRegion(p, op, region, args);
}
+} // namespace mlir::omp
-static void printInReductionPrivateRegion(
+namespace mlir::omp {
+void printInReductionPrivateRegion(
OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange inReductionVars,
TypeRange inReductionTypes, DenseBoolArrayAttr inReductionByref,
ArrayAttr inReductionSyms, ValueRange privateVars, TypeRange privateTypes,
@@ -1798,6 +1820,7 @@ static void printInReductionPrivateRegion(
/*mapIndices=*/nullptr);
printBlockArgRegion(p, op, region, args);
}
+} // namespace mlir::omp
static void printInReductionPrivateReductionRegion(
OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange inReductionVars,
@@ -1829,7 +1852,8 @@ static void printPrivateRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
printBlockArgRegion(p, op, region, args);
}
-static void printPrivateReductionRegion(
+namespace mlir::omp {
+void printPrivateReductionRegion(
OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange privateVars,
TypeRange privateTypes, ArrayAttr privateSyms, UnitAttr privateNeedsBarrier,
ReductionModifierAttr reductionMod, ValueRange reductionVars,
@@ -1843,18 +1867,20 @@ static void printPrivateReductionRegion(
reductionSyms, reductionMod);
printBlockArgRegion(p, op, region, args);
}
+} // namespace mlir::omp
-static void printTaskReductionRegion(OpAsmPrinter &p, Operation *op,
- Region ®ion,
- ValueRange taskReductionVars,
- TypeRange taskReductionTypes,
- DenseBoolArrayAttr taskReductionByref,
- ArrayAttr taskReductionSyms) {
+namespace mlir::omp {
+void printTaskReductionRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
+ ValueRange taskReductionVars,
+ TypeRange taskReductionTypes,
+ DenseBoolArrayAttr taskReductionByref,
+ ArrayAttr taskReductionSyms) {
AllRegionPrintArgs args;
args.taskReductionArgs.emplace(taskReductionVars, taskReductionTypes,
taskReductionByref, taskReductionSyms);
printBlockArgRegion(p, op, region, args);
}
+} // namespace mlir::omp
static void printUseDeviceAddrUseDevicePtrRegion(OpAsmPrinter &p, Operation *op,
Region ®ion,
@@ -2075,7 +2101,8 @@ verifyCopyprivateVarList(Operation *op, OperandRange copyprivateVars,
/// | depend-entry-list `,` depend-entry
/// depend-entry ::= depend-kind `->` ssa-id `:` type
/// | depend-kind `->` ssa-id `:` iterated-type
-static ParseResult parseDependVarList(
+namespace mlir::omp {
+ParseResult parseDependVarList(
OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &dependVars,
SmallVectorImpl<Type> &dependTypes, ArrayAttr &dependKinds,
@@ -2116,12 +2143,11 @@ static ParseResult parseDependVarList(
}
/// Print Depend clause
-static void printDependVarList(OpAsmPrinter &p, Operation *op,
- OperandRange dependVars, TypeRange dependTypes,
- std::optional<ArrayAttr> dependKinds,
- OperandRange iteratedVars,
- TypeRange iteratedTypes,
- std::optional<ArrayAttr> iteratedKinds) {
+void printDependVarList(OpAsmPrinter &p, Operation *op, OperandRange dependVars,
+ TypeRange dependTypes,
+ std::optional<ArrayAttr> dependKinds,
+ OperandRange iteratedVars, TypeRange iteratedTypes,
+ std::optional<ArrayAttr> iteratedKinds) {
bool first = true;
auto printEntries = [&](OperandRange vars, TypeRange types,
std::optional<ArrayAttr> kinds) {
@@ -2138,6 +2164,7 @@ static void printDependVarList(OpAsmPrinter &p, Operation *op,
printEntries(dependVars, dependTypes, dependKinds);
printEntries(iteratedVars, iteratedTypes, iteratedKinds);
}
+} // namespace mlir::omp
/// Verifies Depend clause
static LogicalResult verifyDependVarList(Operation *op,
@@ -2174,8 +2201,9 @@ static LogicalResult verifyDependVarList(Operation *op,
/// which is a combination of different hints from `omp_sync_hint_t`.
///
/// hint-clause = `hint` `(` hint-value `)`
-static ParseResult parseSynchronizationHint(OpAsmParser &parser,
- IntegerAttr &hintAttr) {
+namespace mlir::omp {
+ParseResult parseSynchronizationHint(OpAsmParser &parser,
+ IntegerAttr &hintAttr) {
StringRef hintKeyword;
int64_t hint = 0;
if (succeeded(parser.parseOptionalKeyword("none"))) {
@@ -2205,8 +2233,8 @@ static ParseResult parseSynchronizationHint(OpAsmParser &parser,
}
/// Prints a Synchronization Hint clause
-static void printSynchronizationHint(OpAsmPrinter &p, Operation *op,
- IntegerAttr hintAttr) {
+void printSynchronizationHint(OpAsmPrinter &p, Operation *op,
+ IntegerAttr hintAttr) {
int64_t hint = hintAttr.getInt();
if (hint == 0) {
@@ -2234,6 +2262,7 @@ static void printSynchronizationHint(OpAsmPrinter &p, Operation *op,
llvm::interleaveComma(hints, p);
}
+} // namespace mlir::omp
/// Verifies a synchronization hint clause
static LogicalResult verifySynchronizationHint(Operation *op, uint64_t hint) {
@@ -5619,7 +5648,8 @@ static void printUniformClause(OpAsmPrinter &p, Operation *op,
// Parser and printer for Affinity Clause
//===----------------------------------------------------------------------===//
-static ParseResult parseAffinityClause(
+namespace mlir::omp {
+ParseResult parseAffinityClause(
OpAsmParser &parser,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &iterated,
SmallVectorImpl<OpAsmParser::UnresolvedOperand> &affinityVars,
@@ -5632,16 +5662,16 @@ static ParseResult parseAffinityClause(
return success();
}
-static void printAffinityClause(OpAsmPrinter &p, Operation *op,
- ValueRange iterated, ValueRange affinityVars,
- TypeRange iteratedTypes,
- TypeRange affinityVarTypes) {
+void printAffinityClause(OpAsmPrinter &p, Operation *op, ValueRange iterated,
+ ValueRange affinityVars, TypeRange iteratedTypes,
+ TypeRange affinityVarTypes) {
auto nop = [&](Value, Type) {};
printSplitIteratedList(p, iterated, iteratedTypes, affinityVars,
affinityVarTypes,
/*plain prefix*/ nop,
/*iterated prefix*/ nop);
}
+} // namespace mlir::omp
//===----------------------------------------------------------------------===//
// Parser, printer, and verifier for Iterator modifier
@@ -5809,7 +5839,7 @@ GroupprivateOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
#include "mlir/Dialect/OpenMP/OpenMPOpsAttributes.cpp.inc"
#define GET_OP_CLASSES
-#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
+#include "mlir/Dialect/OpenMP/OpenMPOpsDependent.cpp.inc"
#define GET_TYPEDEF_CLASSES
#include "mlir/Dialect/OpenMP/OpenMPOpsTypes.cpp.inc"
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPGeneratedOps.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPGeneratedOps.cpp
new file mode 100644
index 00000000000000..2b51d56e43d0b5
--- /dev/null
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPGeneratedOps.cpp
@@ -0,0 +1,24 @@
+//===- OpenMPGeneratedOps.cpp - Independent OpenMP op definitions ---------===//
+//
+// Part of the LLVM Project, 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/OpImplementation.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace mlir;
+using namespace mlir::omp;
+
+void OpenMPDialect::registerOperations() {
+ addOperations<
+#define GET_OP_LIST
+#include "mlir/Dialect/OpenMP/OpenMPOps.cpp.inc"
+ >();
+}
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/OpenMP/OpenMPOpsIndependent.cpp.inc"
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPOpsHelpers.h b/mlir/lib/Dialect/OpenMP/IR/OpenMPOpsHelpers.h
new file mode 100644
index 00000000000000..7ad116a32b6016
--- /dev/null
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPOpsHelpers.h
@@ -0,0 +1,159 @@
+//===- OpenMPOpsHelpers.h - Shared OpenMP assembly helpers ------*- C++ -*-===//
+//
+// Part of the LLVM Project, 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_LIB_DIALECT_OPENMP_IR_OPENMPOPSHELPERS_H_
+#define MLIR_LIB_DIALECT_OPENMP_IR_OPENMPOPSHELPERS_H_
+
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/IR/OpImplementation.h"
+
+namespace mlir::omp {
+
+template <typename ClauseAttr>
+ParseResult parseClauseAttr(AsmParser &parser, ClauseAttr &attr) {
+ using ClauseT = decltype(std::declval<ClauseAttr>().getValue());
+ StringRef enumStr;
+ SMLoc loc = parser.getCurrentLocation();
+ if (parser.parseKeyword(&enumStr))
+ return failure();
+ if (std::optional<ClauseT> enumValue = symbolizeEnum<ClauseT>(enumStr)) {
+ attr = ClauseAttr::get(parser.getContext(), *enumValue);
+ return success();
+ }
+ return parser.emitError(loc, "invalid clause value: '") << enumStr << "'";
+}
+
+template <typename ClauseAttr>
+void printClauseAttr(OpAsmPrinter &p, Operation *op, ClauseAttr attr) {
+ p << stringifyEnum(attr.getValue());
+}
+
+ParseResult parseSynchronizationHint(OpAsmParser &parser,
+ IntegerAttr &hintAttr);
+void printSynchronizationHint(OpAsmPrinter &p, Operation *op,
+ IntegerAttr hintAttr);
+
+ParseResult parseAllocateAndAllocator(
+ OpAsmParser &parser,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &allocateVars,
+ SmallVectorImpl<Type> &allocateTypes,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &allocatorVars,
+ SmallVectorImpl<Type> &allocatorTypes);
+void printAllocateAndAllocator(OpAsmPrinter &p, Operation *op,
+ OperandRange allocateVars,
+ TypeRange allocateTypes,
+ OperandRange allocatorVars,
+ TypeRange allocatorTypes);
+
+ParseResult parseDynGroupprivateClause(
+ OpAsmParser &parser, AccessGroupModifierAttr &accessGroupAttr,
+ FallbackModifierAttr &fallbackAttr,
+ std::optional<OpAsmParser::UnresolvedOperand> &dynGroupprivateSize,
+ Type &sizeType);
+void printDynGroupprivateClause(OpAsmPrinter &printer, Operation *op,
+ AccessGroupModifierAttr modifierFirst,
+ FallbackModifierAttr modifierSecond,
+ Value dynGroupprivateSize, Type sizeType);
+
+ParseResult parseInReductionClause(
+ OpAsmParser &parser,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &inReductionVars,
+ SmallVectorImpl<Type> &inReductionTypes,
+ DenseBoolArrayAttr &inReductionByref, ArrayAttr &inReductionSyms);
+void printInReductionClause(OpAsmPrinter &p, Operation *op,
+ ValueRange inReductionVars,
+ TypeRange inReductionTypes,
+ DenseBoolArrayAttr inReductionByref,
+ ArrayAttr inReductionSyms);
+
+ParseResult parseTargetOpRegion(
+ OpAsmParser &parser, Region ®ion,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &hasDeviceAddrVars,
+ SmallVectorImpl<Type> &hasDeviceAddrTypes,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &hostEvalVars,
+ SmallVectorImpl<Type> &hostEvalTypes,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &mapVars,
+ SmallVectorImpl<Type> &mapTypes,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &privateVars,
+ SmallVectorImpl<Type> &privateTypes, ArrayAttr &privateSyms,
+ UnitAttr &privateNeedsBarrier, DenseI64ArrayAttr &privateMaps);
+void printTargetOpRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
+ ValueRange hasDeviceAddrVars,
+ TypeRange hasDeviceAddrTypes, ValueRange hostEvalVars,
+ TypeRange hostEvalTypes, ValueRange mapVars,
+ TypeRange mapTypes, ValueRange privateVars,
+ TypeRange privateTypes, ArrayAttr privateSyms,
+ UnitAttr privateNeedsBarrier,
+ DenseI64ArrayAttr privateMaps);
+
+ParseResult parseInReductionPrivateRegion(
+ OpAsmParser &parser, Region ®ion,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &inReductionVars,
+ SmallVectorImpl<Type> &inReductionTypes,
+ DenseBoolArrayAttr &inReductionByref, ArrayAttr &inReductionSyms,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &privateVars,
+ SmallVectorImpl<Type> &privateTypes, ArrayAttr &privateSyms,
+ UnitAttr &privateNeedsBarrier);
+void printInReductionPrivateRegion(
+ OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange inReductionVars,
+ TypeRange inReductionTypes, DenseBoolArrayAttr inReductionByref,
+ ArrayAttr inReductionSyms, ValueRange privateVars, TypeRange privateTypes,
+ ArrayAttr privateSyms, UnitAttr privateNeedsBarrier);
+
+ParseResult parsePrivateReductionRegion(
+ OpAsmParser &parser, Region ®ion,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &privateVars,
+ SmallVectorImpl<Type> &privateTypes, ArrayAttr &privateSyms,
+ UnitAttr &privateNeedsBarrier, ReductionModifierAttr &reductionMod,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &reductionVars,
+ SmallVectorImpl<Type> &reductionTypes, DenseBoolArrayAttr &reductionByref,
+ ArrayAttr &reductionSyms);
+void printPrivateReductionRegion(
+ OpAsmPrinter &p, Operation *op, Region ®ion, ValueRange privateVars,
+ TypeRange privateTypes, ArrayAttr privateSyms, UnitAttr privateNeedsBarrier,
+ ReductionModifierAttr reductionMod, ValueRange reductionVars,
+ TypeRange reductionTypes, DenseBoolArrayAttr reductionByref,
+ ArrayAttr reductionSyms);
+
+ParseResult parseTaskReductionRegion(
+ OpAsmParser &parser, Region ®ion,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &taskReductionVars,
+ SmallVectorImpl<Type> &taskReductionTypes,
+ DenseBoolArrayAttr &taskReductionByref, ArrayAttr &taskReductionSyms);
+void printTaskReductionRegion(OpAsmPrinter &p, Operation *op, Region ®ion,
+ ValueRange taskReductionVars,
+ TypeRange taskReductionTypes,
+ DenseBoolArrayAttr taskReductionByref,
+ ArrayAttr taskReductionSyms);
+
+ParseResult parseAffinityClause(
+ OpAsmParser &parser,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &iterated,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &affinityVars,
+ SmallVectorImpl<Type> &iteratedTypes,
+ SmallVectorImpl<Type> &affinityVarTypes);
+void printAffinityClause(OpAsmPrinter &p, Operation *op, ValueRange iterated,
+ ValueRange affinityVars, TypeRange iteratedTypes,
+ TypeRange affinityVarTypes);
+
+ParseResult parseDependVarList(
+ OpAsmParser &parser,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &dependVars,
+ SmallVectorImpl<Type> &dependTypes, ArrayAttr &dependKinds,
+ SmallVectorImpl<OpAsmParser::UnresolvedOperand> &iteratedVars,
+ SmallVectorImpl<Type> &iteratedTypes, ArrayAttr &iteratedKinds);
+
+void printDependVarList(OpAsmPrinter &p, Operation *op, OperandRange dependVars,
+ TypeRange dependTypes,
+ std::optional<ArrayAttr> dependKinds,
+ OperandRange iteratedVars, TypeRange iteratedTypes,
+ std::optional<ArrayAttr> iteratedKinds);
+
+} // namespace mlir::omp
+
+#endif // MLIR_LIB_DIALECT_OPENMP_IR_OPENMPOPSHELPERS_H_
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPOutlinedOps.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPOutlinedOps.cpp
new file mode 100644
index 00000000000000..5d7b6a3a5975c9
--- /dev/null
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPOutlinedOps.cpp
@@ -0,0 +1,16 @@
+//===- OpenMPOutlinedOps.cpp - OpenMP definitions using shared helpers ----===//
+//
+// Part of the LLVM Project, 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "OpenMPOpsHelpers.h"
+#include "llvm/ADT/STLExtras.h"
+
+using namespace mlir;
+using namespace mlir::omp;
+
+#define GET_OP_CLASSES
+#include "mlir/Dialect/OpenMP/OpenMPOpsOutlined.cpp.inc"
More information about the Mlir-commits
mailing list