diff options
author | Dominik Adamski <dominik.adamski@amd.com> | 2022-10-20 12:29:57 +0300 |
---|---|---|
committer | Dominik Adamski <dominik.adamski@amd.com> | 2022-11-01 19:07:53 +0300 |
commit | 25243d717dc944bca1b6441686815be84ec8bbf0 (patch) | |
tree | 42ba13ce17ef808802fa8b3f3ca1448571ec1f96 /mlir/lib | |
parent | d4c61314420ca8794ad6d2588566c64109482505 (diff) |
[mlir][OpenMP] Add aligned clause definition to simd construct
simd aligned construct is represented as pair of variable which needs
to be aligned and corresponding alignment value.
Added parser, printer and verifier of aligned clause. MLIR tests were
updated to test correctness of MLIR definition of aligned clause.
Differential Revision: https://reviews.llvm.org/D135865
Reviewed By: kiranchandramohan
Diffstat (limited to 'mlir/lib')
-rw-r--r-- | mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 79 |
1 files changed, 77 insertions, 2 deletions
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index 78a1cfd3a853..ba762339168e 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -171,6 +171,81 @@ static void printLinearClause(OpAsmPrinter &p, Operation *op, } //===----------------------------------------------------------------------===// +// Parser, verifier and printer for Aligned Clause +//===----------------------------------------------------------------------===// +static LogicalResult verifyAlignedClause(Operation *op, + Optional<ArrayAttr> alignmentValues, + OperandRange alignedVariables) { + // Check if number of alignment values equals to number of aligned variables + if (!alignedVariables.empty()) { + if (!alignmentValues || alignmentValues->size() != alignedVariables.size()) + return op->emitOpError() + << "expected as many alignment values as aligned variables"; + } else { + if (alignmentValues) + return op->emitOpError() << "unexpected alignment values attribute"; + return success(); + } + + // Check if each var is aligned only once - OpenMP 4.5 -> 2.8.1 section + DenseSet<Value> alignedItems; + for (auto it : alignedVariables) + if (!alignedItems.insert(it).second) + return op->emitOpError() << "aligned variable used more than once"; + + if (!alignmentValues) + return success(); + + // Check if all alignment values are positive - OpenMP 4.5 -> 2.8.1 section + for (unsigned i = 0; i < (*alignmentValues).size(); ++i) { + if (auto intAttr = (*alignmentValues)[i].dyn_cast<IntegerAttr>()) { + if (intAttr.getValue().sle(0)) + return op->emitOpError() << "alignment should be greater than 0"; + } else { + return op->emitOpError() << "expected integer alignment"; + } + } + + return success(); +} + +/// aligned ::= `aligned` `(` aligned-list `)` +/// aligned-list := aligned-val | aligned-val aligned-list +/// aligned-val := ssa-id-and-type `->` alignment +static ParseResult parseAlignedClause( + OpAsmParser &parser, + SmallVectorImpl<OpAsmParser::UnresolvedOperand> &alignedItems, + SmallVectorImpl<Type> &types, ArrayAttr &alignmentValues) { + SmallVector<Attribute> alignmentVec; + if (failed(parser.parseCommaSeparatedList([&]() { + if (parser.parseOperand(alignedItems.emplace_back()) || + parser.parseColonType(types.emplace_back()) || + parser.parseArrow() || + parser.parseAttribute(alignmentVec.emplace_back())) { + return failure(); + } + return success(); + }))) + return failure(); + SmallVector<Attribute> alignments(alignmentVec.begin(), alignmentVec.end()); + alignmentValues = ArrayAttr::get(parser.getContext(), alignments); + return success(); +} + +/// Print Aligned Clause +static void printAlignedClause(OpAsmPrinter &p, Operation *op, + ValueRange alignedVars, + TypeRange alignedVarTypes, + Optional<ArrayAttr> alignmentValues) { + for (unsigned i = 0; i < alignedVars.size(); ++i) { + if (i != 0) + p << ", "; + p << alignedVars[i] << " : " << alignedVars[i].getType(); + p << " -> " << (*alignmentValues)[i]; + } +} + +//===----------------------------------------------------------------------===// // Parser, printer and verifier for Schedule Clause //===----------------------------------------------------------------------===// @@ -583,8 +658,8 @@ LogicalResult SimdLoopOp::verify() { << "simdlen clause and safelen clause are both present, but the " "simdlen value is not less than or equal to safelen value"; } - - return success(); + return verifyAlignedClause(*this, this->getAlignmentValues(), + this->getAlignedVars()); } //===----------------------------------------------------------------------===// |