Jean-Didier PAILLEUX 4ba30c6eb6
[flang][Multi-Image] Moving Mutli-image lowering to PRIF into the MIF dialect (#161179)
Support for multi-image features has begun to be integrated into LLVM. A
new dialect which simplifies lowering to PRIF wil be proposed in this
PR.
The initial definition of this dialect (MIF) is based only on operations
already upstreamed in LLVM and the current lowering will be moved to
this dialect.


---------

Co-authored-by: Dan Bonachea <dobonachea@lbl.gov>
Co-authored-by: Valentin Clement (バレンタイン クレメン) <clementval@gmail.com>
2025-10-20 08:00:52 +02:00

154 lines
5.9 KiB
C++

//===-- 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();
}