brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.9 KiB · 5f68f3d Raw
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