diff options
Diffstat (limited to 'flang/lib/Optimizer/Dialect')
-rw-r--r-- | flang/lib/Optimizer/Dialect/CMakeLists.txt | 1 | ||||
-rw-r--r-- | flang/lib/Optimizer/Dialect/FIRType.cpp | 7 | ||||
-rw-r--r-- | flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt | 24 | ||||
-rw-r--r-- | flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp | 24 | ||||
-rw-r--r-- | flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp | 153 |
5 files changed, 209 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/Dialect/CMakeLists.txt b/flang/lib/Optimizer/Dialect/CMakeLists.txt index 4fd4d28..65d1f2c 100644 --- a/flang/lib/Optimizer/Dialect/CMakeLists.txt +++ b/flang/lib/Optimizer/Dialect/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(Support) add_subdirectory(CUF) add_subdirectory(FIRCG) +add_subdirectory(MIF) add_flang_library(FIRDialect FIRAttr.cpp diff --git a/flang/lib/Optimizer/Dialect/FIRType.cpp b/flang/lib/Optimizer/Dialect/FIRType.cpp index 48e1622..fe35b08 100644 --- a/flang/lib/Optimizer/Dialect/FIRType.cpp +++ b/flang/lib/Optimizer/Dialect/FIRType.cpp @@ -1427,6 +1427,13 @@ mlir::Type BaseBoxType::unwrapInnerType() const { return fir::unwrapInnerType(getEleTy()); } +mlir::Type BaseBoxType::getElementOrSequenceType() const { + mlir::Type eleTy = getEleTy(); + if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(eleTy)) + return seqTy; + return fir::unwrapRefType(eleTy); +} + static mlir::Type changeTypeShape(mlir::Type type, std::optional<fir::SequenceType::ShapeRef> newShape) { diff --git a/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt new file mode 100644 index 0000000..ed8463e --- /dev/null +++ b/flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt @@ -0,0 +1,24 @@ +add_flang_library(MIFDialect + MIFDialect.cpp + MIFOps.cpp + + DEPENDS + MIFOpsIncGen + + LINK_LIBS + FIRDialect + FIRDialectSupport + FIRSupport + + LINK_COMPONENTS + AsmParser + AsmPrinter + Remarks + + MLIR_DEPS + MLIRIR + + MLIR_LIBS + MLIRIR + MLIRTargetLLVMIRExport +) diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp new file mode 100644 index 0000000..edc723d --- /dev/null +++ b/flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp @@ -0,0 +1,24 @@ +//===- MIFDialect.cpp - MIF dialect implementation ------------------------===// +// +// 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 +// C +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Dialect/MIF/MIFDialect.h" +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/MIF/MIFOps.h" + +//===----------------------------------------------------------------------===// +/// Tablegen Definitions +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Dialect/MIF/MIFDialect.cpp.inc" + +void mif::MIFDialect::initialize() { + addOperations< +#define GET_OP_LIST +#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc" + >(); +} diff --git a/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp new file mode 100644 index 0000000..c6cc2e8 --- /dev/null +++ b/flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp @@ -0,0 +1,153 @@ +//===-- MIFOps.cpp - MIF dialect ops implementation -----------------------===// +// +// 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 "flang/Optimizer/Dialect/MIF/MIFOps.h" +#include "flang/Optimizer/Builder/Todo.h" +#include "flang/Optimizer/Dialect/FIRAttr.h" +#include "flang/Optimizer/Dialect/FIRType.h" +#include "flang/Optimizer/Dialect/MIF/MIFDialect.h" +#include "mlir/IR/Matchers.h" +#include "mlir/IR/PatternMatch.h" +#include "llvm/ADT/SmallVector.h" + +#define GET_OP_CLASSES +#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc" + +//===----------------------------------------------------------------------===// +// NumImagesOp +//===----------------------------------------------------------------------===// + +void mif::NumImagesOp::build(mlir::OpBuilder &builder, + mlir::OperationState &result, + mlir::Value teamArg) { + bool isTeamNumber = + teamArg && fir::unwrapPassByRefType(teamArg.getType()).isInteger(); + if (isTeamNumber) + build(builder, result, teamArg, /*team*/ mlir::Value{}); + else + build(builder, result, /*team_number*/ mlir::Value{}, teamArg); +} + +llvm::LogicalResult mif::NumImagesOp::verify() { + if (getTeam() && getTeamNumber()) + return emitOpError( + "team and team_number must not be provided at the same time"); + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// ThisImageOp +//===----------------------------------------------------------------------===// + +void mif::ThisImageOp::build(mlir::OpBuilder &builder, + mlir::OperationState &result, mlir::Value coarray, + mlir::Value team) { + build(builder, result, coarray, /*dim*/ mlir::Value{}, team); +} + +void mif::ThisImageOp::build(mlir::OpBuilder &builder, + mlir::OperationState &result, mlir::Value team) { + build(builder, result, /*coarray*/ mlir::Value{}, /*dim*/ mlir::Value{}, + team); +} + +llvm::LogicalResult mif::ThisImageOp::verify() { + if (getDim() && !getCoarray()) + return emitOpError( + "`dim` must be provied at the same time as the `coarray` argument."); + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// SyncImagesOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult mif::SyncImagesOp::verify() { + if (getImageSet()) { + mlir::Type t = getImageSet().getType(); + fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(t); + if (auto seqTy = mlir::dyn_cast<fir::SequenceType>( + boxTy.getElementOrSequenceType())) { + if (seqTy.getDimension() != 0 && seqTy.getDimension() != 1) + return emitOpError( + "`image_set` must be a boxed integer expression of rank 1."); + if (!fir::isa_integer(seqTy.getElementType())) + return emitOpError("`image_set` must be a boxed array of integer."); + } else if (!fir::isa_integer(boxTy.getElementType())) + return emitOpError( + "`image_set` must be a boxed scalar integer expression."); + } + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// CoBroadcastOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult mif::CoBroadcastOp::verify() { + fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType()); + + if (fir::isPolymorphicType(boxTy)) + return emitOpError("`A` cannot be polymorphic."); + else if (auto recTy = + mlir::dyn_cast<fir::RecordType>(boxTy.getElementType())) { + for (auto component : recTy.getTypeList()) { + if (fir::isPolymorphicType(component.second)) + TODO(getLoc(), "`A` with polymorphic subobject component."); + } + } + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// CoMaxOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult mif::CoMaxOp::verify() { + fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType()); + mlir::Type elemTy = boxTy.getElementOrSequenceType(); + if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy)) + elemTy = seqTy.getElementType(); + + if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) && + !fir::isa_char(elemTy)) + return emitOpError("`A` shall be of type integer, real or character."); + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// CoMinOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult mif::CoMinOp::verify() { + fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType()); + mlir::Type elemTy = boxTy.getElementOrSequenceType(); + if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy)) + elemTy = seqTy.getElementType(); + + if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) && + !fir::isa_char(elemTy)) + return emitOpError("`A` shall be of type integer, real or character."); + return mlir::success(); +} + +//===----------------------------------------------------------------------===// +// CoSumOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult mif::CoSumOp::verify() { + fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType()); + mlir::Type elemTy = boxTy.getElementOrSequenceType(); + if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy)) + elemTy = seqTy.getElementType(); + + if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) && + !fir::isa_complex(elemTy)) + return emitOpError("`A` shall be of numeric type."); + return mlir::success(); +} |