aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/Dialect
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/Dialect')
-rw-r--r--flang/lib/Optimizer/Dialect/CMakeLists.txt1
-rw-r--r--flang/lib/Optimizer/Dialect/FIRType.cpp7
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/CMakeLists.txt24
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/MIFDialect.cpp24
-rw-r--r--flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp153
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();
+}