208 lines · cpp
1//===-- MIFOps.cpp - MIF dialect ops implementation -----------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "flang/Optimizer/Dialect/MIF/MIFOps.h"10#include "flang/Optimizer/Builder/Todo.h"11#include "flang/Optimizer/Dialect/FIRAttr.h"12#include "flang/Optimizer/Dialect/FIRType.h"13#include "flang/Optimizer/Dialect/MIF/MIFDialect.h"14#include "mlir/IR/Matchers.h"15#include "mlir/IR/PatternMatch.h"16#include "llvm/ADT/SmallVector.h"17 18//===----------------------------------------------------------------------===//19// NumImagesOp20//===----------------------------------------------------------------------===//21 22void mif::NumImagesOp::build(mlir::OpBuilder &builder,23 mlir::OperationState &result,24 mlir::Value teamArg) {25 bool isTeamNumber =26 teamArg && fir::unwrapPassByRefType(teamArg.getType()).isInteger();27 if (isTeamNumber)28 build(builder, result, teamArg, /*team*/ mlir::Value{});29 else30 build(builder, result, /*team_number*/ mlir::Value{}, teamArg);31}32 33llvm::LogicalResult mif::NumImagesOp::verify() {34 if (getTeam() && getTeamNumber())35 return emitOpError(36 "team and team_number must not be provided at the same time");37 return mlir::success();38}39 40//===----------------------------------------------------------------------===//41// ThisImageOp42//===----------------------------------------------------------------------===//43 44void mif::ThisImageOp::build(mlir::OpBuilder &builder,45 mlir::OperationState &result, mlir::Value coarray,46 mlir::Value team) {47 build(builder, result, coarray, /*dim*/ mlir::Value{}, team);48}49 50void mif::ThisImageOp::build(mlir::OpBuilder &builder,51 mlir::OperationState &result, mlir::Value team) {52 build(builder, result, /*coarray*/ mlir::Value{}, /*dim*/ mlir::Value{},53 team);54}55 56llvm::LogicalResult mif::ThisImageOp::verify() {57 if (getDim() && !getCoarray())58 return emitOpError(59 "`dim` must be provied at the same time as the `coarray` argument.");60 return mlir::success();61}62 63//===----------------------------------------------------------------------===//64// SyncImagesOp65//===----------------------------------------------------------------------===//66 67llvm::LogicalResult mif::SyncImagesOp::verify() {68 if (getImageSet()) {69 mlir::Type t = getImageSet().getType();70 fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(t);71 if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(72 boxTy.getElementOrSequenceType())) {73 if (seqTy.getDimension() != 0 && seqTy.getDimension() != 1)74 return emitOpError(75 "`image_set` must be a boxed integer expression of rank 1.");76 if (!fir::isa_integer(seqTy.getElementType()))77 return emitOpError("`image_set` must be a boxed array of integer.");78 } else if (!fir::isa_integer(boxTy.getElementType()))79 return emitOpError(80 "`image_set` must be a boxed scalar integer expression.");81 }82 return mlir::success();83}84 85//===----------------------------------------------------------------------===//86// CoBroadcastOp87//===----------------------------------------------------------------------===//88 89llvm::LogicalResult mif::CoBroadcastOp::verify() {90 fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());91 92 if (fir::isPolymorphicType(boxTy))93 return emitOpError("`A` cannot be polymorphic.");94 else if (auto recTy =95 mlir::dyn_cast<fir::RecordType>(boxTy.getElementType())) {96 for (auto component : recTy.getTypeList()) {97 if (fir::isPolymorphicType(component.second))98 TODO(getLoc(), "`A` with polymorphic subobject component.");99 }100 }101 return mlir::success();102}103 104//===----------------------------------------------------------------------===//105// CoMaxOp106//===----------------------------------------------------------------------===//107 108llvm::LogicalResult mif::CoMaxOp::verify() {109 fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());110 mlir::Type elemTy = boxTy.getElementOrSequenceType();111 if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))112 elemTy = seqTy.getElementType();113 114 if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&115 !fir::isa_char(elemTy))116 return emitOpError("`A` shall be of type integer, real or character.");117 return mlir::success();118}119 120//===----------------------------------------------------------------------===//121// CoMinOp122//===----------------------------------------------------------------------===//123 124llvm::LogicalResult mif::CoMinOp::verify() {125 fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());126 mlir::Type elemTy = boxTy.getElementOrSequenceType();127 if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))128 elemTy = seqTy.getElementType();129 130 if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&131 !fir::isa_char(elemTy))132 return emitOpError("`A` shall be of type integer, real or character.");133 return mlir::success();134}135 136//===----------------------------------------------------------------------===//137// CoSumOp138//===----------------------------------------------------------------------===//139 140llvm::LogicalResult mif::CoSumOp::verify() {141 fir::BoxType boxTy = mlir::dyn_cast<fir::BoxType>(getA().getType());142 mlir::Type elemTy = boxTy.getElementOrSequenceType();143 if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(elemTy))144 elemTy = seqTy.getElementType();145 146 if (!fir::isa_real(elemTy) && !fir::isa_integer(elemTy) &&147 !fir::isa_complex(elemTy))148 return emitOpError("`A` shall be of numeric type.");149 return mlir::success();150}151 152//===----------------------------------------------------------------------===//153// ChangeTeamOp154//===----------------------------------------------------------------------===//155 156void mif::ChangeTeamOp::build(mlir::OpBuilder &builder,157 mlir::OperationState &result, mlir::Value team,158 bool ensureTerminator,159 llvm::ArrayRef<mlir::NamedAttribute> attributes) {160 build(builder, result, team, /*stat*/ mlir::Value{}, /*errmsg*/ mlir::Value{},161 ensureTerminator, attributes);162}163 164void mif::ChangeTeamOp::build(mlir::OpBuilder &builder,165 mlir::OperationState &result, mlir::Value team,166 mlir::Value stat, mlir::Value errmsg,167 bool ensureTerminator,168 llvm::ArrayRef<mlir::NamedAttribute> attributes) {169 std::int32_t argStat = 0, argErrmsg = 0;170 result.addOperands(team);171 if (stat) {172 result.addOperands(stat);173 argStat++;174 }175 if (errmsg) {176 result.addOperands(errmsg);177 argErrmsg++;178 }179 180 mlir::Region *bodyRegion = result.addRegion();181 bodyRegion->push_back(new mlir::Block{});182 if (ensureTerminator)183 ChangeTeamOp::ensureTerminator(*bodyRegion, builder, result.location);184 185 result.addAttribute(getOperandSegmentSizeAttr(),186 builder.getDenseI32ArrayAttr({1, argStat, argErrmsg}));187 result.addAttributes(attributes);188}189 190static mlir::ParseResult parseChangeTeamOpBody(mlir::OpAsmParser &parser,191 mlir::Region &body) {192 if (parser.parseRegion(body))193 return mlir::failure();194 195 auto &builder = parser.getBuilder();196 mif::ChangeTeamOp::ensureTerminator(body, builder, builder.getUnknownLoc());197 return mlir::success();198}199 200static void printChangeTeamOpBody(mlir::OpAsmPrinter &p, mif::ChangeTeamOp op,201 mlir::Region &body) {202 p.printRegion(op.getRegion(), /*printEntryBlockArgs=*/true,203 /*printBlockTerminators=*/true);204}205 206#define GET_OP_CLASSES207#include "flang/Optimizer/Dialect/MIF/MIFOps.cpp.inc"208