brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 745ca24 Raw
279 lines · cpp
1//===-- MultiImageFortran.cpp ---------------------------------------------===//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/// Implementation of the lowering of image related constructs and expressions.10/// Fortran images can form teams, communicate via coarrays, etc.11///12//===----------------------------------------------------------------------===//13 14#include "flang/Lower/MultiImageFortran.h"15#include "flang/Lower/AbstractConverter.h"16#include "flang/Lower/SymbolMap.h"17#include "flang/Optimizer/Builder/FIRBuilder.h"18#include "flang/Optimizer/Builder/Todo.h"19#include "flang/Optimizer/Dialect/MIF/MIFOps.h"20#include "flang/Parser/parse-tree.h"21#include "flang/Semantics/expression.h"22 23//===----------------------------------------------------------------------===//24// Synchronization statements25//===----------------------------------------------------------------------===//26 27void Fortran::lower::genSyncAllStatement(28    Fortran::lower::AbstractConverter &converter,29    const Fortran::parser::SyncAllStmt &stmt) {30  mlir::Location loc = converter.getCurrentLocation();31  converter.checkCoarrayEnabled();32 33  // Handle STAT and ERRMSG values34  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList = stmt.v;35  auto [statAddr, errMsgAddr] = converter.genStatAndErrmsg(loc, statOrErrList);36 37  fir::FirOpBuilder &builder = converter.getFirOpBuilder();38  mif::SyncAllOp::create(builder, loc, statAddr, errMsgAddr);39}40 41void Fortran::lower::genSyncImagesStatement(42    Fortran::lower::AbstractConverter &converter,43    const Fortran::parser::SyncImagesStmt &stmt) {44  mlir::Location loc = converter.getCurrentLocation();45  converter.checkCoarrayEnabled();46  fir::FirOpBuilder &builder = converter.getFirOpBuilder();47 48  // Handle STAT and ERRMSG values49  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList =50      std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t);51  auto [statAddr, errMsgAddr] = converter.genStatAndErrmsg(loc, statOrErrList);52 53  // SYNC_IMAGES(*) is passed as count == -1 while  SYNC IMAGES([]) has count54  // == 0. Note further that SYNC IMAGES(*) is not semantically equivalent to55  // SYNC ALL.56  Fortran::lower::StatementContext stmtCtx;57  mlir::Value imageSet;58  const Fortran::parser::SyncImagesStmt::ImageSet &imgSet =59      std::get<Fortran::parser::SyncImagesStmt::ImageSet>(stmt.t);60  std::visit(Fortran::common::visitors{61                 [&](const Fortran::parser::IntExpr &intExpr) {62                   const SomeExpr *expr = Fortran::semantics::GetExpr(intExpr);63                   imageSet =64                       fir::getBase(converter.genExprBox(loc, *expr, stmtCtx));65                 },66                 [&](const Fortran::parser::Star &) {67                   // Image set is not set.68                   imageSet = mlir::Value{};69                 }},70             imgSet.u);71 72  mif::SyncImagesOp::create(builder, loc, imageSet, statAddr, errMsgAddr);73}74 75void Fortran::lower::genSyncMemoryStatement(76    Fortran::lower::AbstractConverter &converter,77    const Fortran::parser::SyncMemoryStmt &stmt) {78  mlir::Location loc = converter.getCurrentLocation();79  converter.checkCoarrayEnabled();80 81  // Handle STAT and ERRMSG values82  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList = stmt.v;83  auto [statAddr, errMsgAddr] = converter.genStatAndErrmsg(loc, statOrErrList);84 85  fir::FirOpBuilder &builder = converter.getFirOpBuilder();86  mif::SyncMemoryOp::create(builder, loc, statAddr, errMsgAddr);87}88 89void Fortran::lower::genSyncTeamStatement(90    Fortran::lower::AbstractConverter &converter,91    const Fortran::parser::SyncTeamStmt &stmt) {92  mlir::Location loc = converter.getCurrentLocation();93  converter.checkCoarrayEnabled();94 95  // Handle TEAM96  Fortran::lower::StatementContext stmtCtx;97  const Fortran::parser::TeamValue &teamValue =98      std::get<Fortran::parser::TeamValue>(stmt.t);99  const SomeExpr *teamExpr = Fortran::semantics::GetExpr(teamValue);100  mlir::Value team =101      fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx));102 103  // Handle STAT and ERRMSG values104  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList =105      std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t);106  auto [statAddr, errMsgAddr] = converter.genStatAndErrmsg(loc, statOrErrList);107 108  fir::FirOpBuilder &builder = converter.getFirOpBuilder();109  mif::SyncTeamOp::create(builder, loc, team, statAddr, errMsgAddr);110}111 112//===----------------------------------------------------------------------===//113// TEAM statements and constructs114//===----------------------------------------------------------------------===//115 116void Fortran::lower::genChangeTeamConstruct(117    Fortran::lower::AbstractConverter &converter,118    Fortran::lower::pft::Evaluation &,119    const Fortran::parser::ChangeTeamConstruct &) {120  TODO(converter.getCurrentLocation(), "coarray: CHANGE TEAM construct");121}122 123void Fortran::lower::genChangeTeamStmt(124    Fortran::lower::AbstractConverter &converter,125    Fortran::lower::pft::Evaluation &,126    const Fortran::parser::ChangeTeamStmt &stmt) {127  mlir::Location loc = converter.getCurrentLocation();128  converter.checkCoarrayEnabled();129  fir::FirOpBuilder &builder = converter.getFirOpBuilder();130 131  mlir::Value errMsgAddr, statAddr, team;132  // Handle STAT and ERRMSG values133  Fortran::lower::StatementContext stmtCtx;134  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList =135      std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t);136  for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) {137    std::visit(Fortran::common::visitors{138                   [&](const Fortran::parser::StatVariable &statVar) {139                     const auto *expr = Fortran::semantics::GetExpr(statVar);140                     statAddr = fir::getBase(141                         converter.genExprAddr(loc, *expr, stmtCtx));142                   },143                   [&](const Fortran::parser::MsgVariable &errMsgVar) {144                     const auto *expr = Fortran::semantics::GetExpr(errMsgVar);145                     errMsgAddr = fir::getBase(146                         converter.genExprBox(loc, *expr, stmtCtx));147                   },148               },149               statOrErr.u);150  }151 152  // TODO: Manage the list of coarrays associated in153  // `std::list<CoarrayAssociation>`. According to the PRIF specification, it is154  // necessary to call `prif_alias_{create|destroy}` for each coarray defined in155  // this list. Support will be added once lowering to this procedure is156  // possible.157  const std::list<Fortran::parser::CoarrayAssociation> &coarrayAssocList =158      std::get<std::list<Fortran::parser::CoarrayAssociation>>(stmt.t);159  if (coarrayAssocList.size())160    TODO(loc, "Coarrays provided in the association list.");161 162  // Handle TEAM-VALUE163  const auto *teamExpr =164      Fortran::semantics::GetExpr(std::get<Fortran::parser::TeamValue>(stmt.t));165  team = fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx));166 167  mif::ChangeTeamOp changeOp = mif::ChangeTeamOp::create(168      builder, loc, team, statAddr, errMsgAddr, /*terminator*/ false);169  builder.setInsertionPointToStart(changeOp.getBody());170}171 172void Fortran::lower::genEndChangeTeamStmt(173    Fortran::lower::AbstractConverter &converter,174    Fortran::lower::pft::Evaluation &,175    const Fortran::parser::EndChangeTeamStmt &stmt) {176  converter.checkCoarrayEnabled();177  mlir::Location loc = converter.getCurrentLocation();178  fir::FirOpBuilder &builder = converter.getFirOpBuilder();179 180  mlir::Value errMsgAddr, statAddr;181  // Handle STAT and ERRMSG values182  Fortran::lower::StatementContext stmtCtx;183  const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList =184      std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t);185  for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) {186    std::visit(Fortran::common::visitors{187                   [&](const Fortran::parser::StatVariable &statVar) {188                     const auto *expr = Fortran::semantics::GetExpr(statVar);189                     statAddr = fir::getBase(190                         converter.genExprAddr(loc, *expr, stmtCtx));191                   },192                   [&](const Fortran::parser::MsgVariable &errMsgVar) {193                     const auto *expr = Fortran::semantics::GetExpr(errMsgVar);194                     errMsgAddr = fir::getBase(195                         converter.genExprBox(loc, *expr, stmtCtx));196                   },197               },198               statOrErr.u);199  }200 201  mif::EndTeamOp endOp =202      mif::EndTeamOp::create(builder, loc, statAddr, errMsgAddr);203  builder.setInsertionPointAfter(endOp.getParentOp());204}205 206void Fortran::lower::genFormTeamStatement(207    Fortran::lower::AbstractConverter &converter,208    Fortran::lower::pft::Evaluation &,209    const Fortran::parser::FormTeamStmt &stmt) {210  converter.checkCoarrayEnabled();211  mlir::Location loc = converter.getCurrentLocation();212  fir::FirOpBuilder &builder = converter.getFirOpBuilder();213 214  mlir::Value errMsgAddr, statAddr, newIndex, teamNumber, team;215  // Handle NEW_INDEX, STAT and ERRMSG216  std::list<Fortran::parser::StatOrErrmsg> statOrErrList{};217  Fortran::lower::StatementContext stmtCtx;218  const auto &formSpecList =219      std::get<std::list<Fortran::parser::FormTeamStmt::FormTeamSpec>>(stmt.t);220  for (const Fortran::parser::FormTeamStmt::FormTeamSpec &formSpec :221       formSpecList) {222    std::visit(223        Fortran::common::visitors{224            [&](const Fortran::parser::StatOrErrmsg &statOrErr) {225              std::visit(226                  Fortran::common::visitors{227                      [&](const Fortran::parser::StatVariable &statVar) {228                        const auto *expr = Fortran::semantics::GetExpr(statVar);229                        statAddr = fir::getBase(230                            converter.genExprAddr(loc, *expr, stmtCtx));231                      },232                      [&](const Fortran::parser::MsgVariable &errMsgVar) {233                        const auto *expr =234                            Fortran::semantics::GetExpr(errMsgVar);235                        errMsgAddr = fir::getBase(236                            converter.genExprBox(loc, *expr, stmtCtx));237                      },238                  },239                  statOrErr.u);240            },241            [&](const Fortran::parser::ScalarIntExpr &intExpr) {242              fir::ExtendedValue newIndexExpr = converter.genExprValue(243                  loc, Fortran::semantics::GetExpr(intExpr), stmtCtx);244              newIndex = fir::getBase(newIndexExpr);245            },246        },247        formSpec.u);248  }249 250  // Handle TEAM-NUMBER251  const auto *teamNumberExpr = Fortran::semantics::GetExpr(252      std::get<Fortran::parser::ScalarIntExpr>(stmt.t));253  teamNumber =254      fir::getBase(converter.genExprValue(loc, *teamNumberExpr, stmtCtx));255 256  // Handle TEAM-VARIABLE257  const auto *teamExpr = Fortran::semantics::GetExpr(258      std::get<Fortran::parser::TeamVariable>(stmt.t));259  team = fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx));260 261  mif::FormTeamOp::create(builder, loc, teamNumber, team, newIndex, statAddr,262                          errMsgAddr);263}264 265//===----------------------------------------------------------------------===//266// COARRAY expressions267//===----------------------------------------------------------------------===//268 269fir::ExtendedValue Fortran::lower::CoarrayExprHelper::genAddr(270    const Fortran::evaluate::CoarrayRef &expr) {271  (void)symMap;272  TODO(converter.getCurrentLocation(), "co-array address");273}274 275fir::ExtendedValue Fortran::lower::CoarrayExprHelper::genValue(276    const Fortran::evaluate::CoarrayRef &expr) {277  TODO(converter.getCurrentLocation(), "co-array value");278}279