Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions flang/include/flang/Lower/AbstractConverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ class AbstractConverter {

virtual Fortran::lower::StatementContext &getFctCtx() = 0;

/// Generate STAT and ERRMSG from a list of StatOrErrmsg
virtual std::pair<mlir::Value, mlir::Value>
genStatAndErrmsg(mlir::Location loc,
const std::list<Fortran::parser::StatOrErrmsg> &) = 0;

AbstractConverter(const Fortran::lower::LoweringOptions &loweringOptions)
: loweringOptions(loweringOptions) {}
virtual ~AbstractConverter() = default;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//===-- Lower/Coarray.h -- image related lowering ---------------*- C++ -*-===//
//===-- Lower/MultiImageFortran.h -- image related lowering -----*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef FORTRAN_LOWER_COARRAY_H
#define FORTRAN_LOWER_COARRAY_H
#ifndef FORTRAN_LOWER_MULTI_IMAGE_FORTRAN_H
#define FORTRAN_LOWER_MULTI_IMAGE_FORTRAN_H

#include "flang/Lower/AbstractConverter.h"
#include "flang/Optimizer/Builder/BoxValue.h"
Expand All @@ -33,6 +33,18 @@ namespace pft {
struct Evaluation;
} // namespace pft

//===----------------------------------------------------------------------===//
// Synchronization statements
//===----------------------------------------------------------------------===//

void genSyncAllStatement(AbstractConverter &, const parser::SyncAllStmt &);

void genSyncImagesStatement(AbstractConverter &,
const parser::SyncImagesStmt &);
void genSyncMemoryStatement(AbstractConverter &,
const parser::SyncMemoryStmt &);
void genSyncTeamStatement(AbstractConverter &, const parser::SyncTeamStmt &);

//===----------------------------------------------------------------------===//
// TEAM constructs
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -75,4 +87,4 @@ class CoarrayExprHelper {
} // namespace lower
} // namespace Fortran

#endif // FORTRAN_LOWER_COARRAY_H
#endif // FORTRAN_LOWER_MULTI_IMAGE_FORTRAN_H
6 changes: 0 additions & 6 deletions flang/include/flang/Lower/Runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &);
void genLockStatement(AbstractConverter &, const parser::LockStmt &);
void genFailImageStatement(AbstractConverter &);
void genStopStatement(AbstractConverter &, const parser::StopStmt &);
void genSyncAllStatement(AbstractConverter &, const parser::SyncAllStmt &);
void genSyncImagesStatement(AbstractConverter &,
const parser::SyncImagesStmt &);
void genSyncMemoryStatement(AbstractConverter &,
const parser::SyncMemoryStmt &);
void genSyncTeamStatement(AbstractConverter &, const parser::SyncTeamStmt &);
void genUnlockStatement(AbstractConverter &, const parser::UnlockStmt &);
void genPauseStatement(AbstractConverter &, const parser::PauseStmt &);

Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ struct IntrinsicLibrary {
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genGetGID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
mlir::Value genGetTeam(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genGetUID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
fir::ExtendedValue genHostnm(std::optional<mlir::Type> resultType,
Expand Down Expand Up @@ -425,6 +426,8 @@ struct IntrinsicLibrary {
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genTand(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genTanpi(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genTeamNumber(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genTime(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genTransfer(mlir::Type,
Expand Down
160 changes: 160 additions & 0 deletions flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ include "flang/Optimizer/Dialect/FIRAttr.td"
class mif_Op<string mnemonic, list<Trait> traits>
: Op<MIFDialect, mnemonic, traits>;

class region_Op<string mnemonic, list<Trait> traits = []>
: mif_Op<mnemonic, !listconcat(traits, [RecursivelySpeculatable,
RecursiveMemoryEffects])> {}

//===----------------------------------------------------------------------===//
// Initialization and Finalization
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -174,6 +178,18 @@ def mif_SyncMemoryOp : mif_Op<"sync_memory", [AttrSizedOperandSegments]> {
}];
}

def mif_SyncTeamOp : mif_Op<"sync_team", [AttrSizedOperandSegments]> {
let summary = "Performs a synchronization of the team, identified by `team`";

let arguments = (ins AnyRefOrBoxType:$team, Optional<AnyReferenceLike>:$stat,
Optional<AnyRefOrBoxType>:$errmsg);
let assemblyFormat = [{
$team (`stat` $stat^ )?
(`errmsg` $errmsg^ )?
attr-dict `:` functional-type(operands, results)
}];
}

//===----------------------------------------------------------------------===//
// Collective Operations
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -265,4 +281,148 @@ def mif_CoSumOp
}];
}

//===----------------------------------------------------------------------===//
// Teams
//===----------------------------------------------------------------------===//

def mif_FormTeamOp : mif_Op<"form_team", [AttrSizedOperandSegments]> {
let summary =
"Create a set of sibling teams whose parent team is the current team.";
let description = [{
Create a new team for each unique `team_number` value specified.
Each executing image will belong to the team whose `team_number` is equal
to the value of team-number on that image, and `team_var` becomes defined
with a value that identifies that team.

If `new_index` is specified, the image index of the executing image will take
this index in its new team. Otherwise, the new image index is processor
dependent.

Arguments:
- `team_number`: Shall be a positive integer.
- `team_var` : Shall be a variable of type TEAM_TYPE from the intrinsic
module ISO_FORTRAN_ENV.
- `new_index`(optional): Shall be an integer that correspond to the index that
the calling image will have in the new team.
}];

let arguments = (ins AnyIntegerType:$team_number,
Arg<fir_BoxType, "", [MemWrite]>:$team_var,
Optional<AnyIntegerType>:$new_index,
Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);

let assemblyFormat = [{
`team_number` $team_number `team_var` $team_var
(`new_index` $new_index^ )?
(`stat` $stat^ )?
(`errmsg` $errmsg^ )?
attr-dict `:` functional-type(operands, results)
}];
}

def mif_EndTeamOp : mif_Op<"end_team", [AttrSizedOperandSegments, Terminator,
ParentOneOf<["ChangeTeamOp"]>]> {
let summary = "Changes the current team to the parent team.";
let description = [{
The END TEAM operation completes the CHANGE TEAM construct and
restores the current team to the team that was current before
the CHANGE TEAM construct.
}];

let arguments = (ins Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
let builders = [OpBuilder<(ins), [{ /* do nothing */ }]>];

let assemblyFormat = [{
(`stat` $stat^ )? (`errmsg` $errmsg^ )?
attr-dict `:` functional-type(operands, results)
}];
}

//===----------------------------------------------------------------------===//
// NOTE: The CHANGE TEAM region will take a coarray association list in
// argument. However, coarray management and coarray alias creation are not
// yet supported by the dialect. The argument is therefore not yet supported by
// this operation and will be added later.
//===----------------------------------------------------------------------===//
def mif_ChangeTeamOp
: region_Op<"change_team", [AttrSizedOperandSegments,
SingleBlockImplicitTerminator<"EndTeamOp">]> {
let summary = "Changes the current team.";
let description = [{
The CHANGE TEAM construct changes the current team to the specified new
team, which must be a child team of the current team.

```
mif.change_team %team {
%x = fir.convert %i : (index) -> i32
...
mif.end_team
}
}];

let arguments = (ins AnyRefOrBoxType:$team,
Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
let regions = (region SizedRegion<1>:$region);

let skipDefaultBuilders = 1;
let builders =
[OpBuilder<(ins "mlir::Value":$team,
CArg<"bool", "true">:$ensureTermination,
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>,
OpBuilder<(ins "mlir::Value":$team, "mlir::Value":$stat,
"mlir::Value":$errmsg, CArg<"bool", "true">:$ensureTermination,
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>];

let extraClassDeclaration = [{
/// Get the body of the CHANGE TEAM construct
mlir::Block *getBody() { return &getRegion().front(); }
}];

let assemblyFormat = [{
$team (`stat` $stat^)?
(`errmsg` $errmsg^)?
attr-dict `:` `(` type(operands) `)`
custom<ChangeTeamOpBody>($region)
}];
}

def mif_GetTeamOp : mif_Op<"get_team", []> {
let summary = "Get the team value for the current or ancestor team.";
let description = [{
This operation gets the team value for the current or an ancestor team.
`level`(optional): If provided, must equal one of the following constants :
`INITIAL_TEAM`, `PARENT_TEAM` or `CURRENT_TEAM` from the module ISO_FORTRAN_ENV.
If `level` isn't present or has the value `CURRENT_TEAM` the returned
value is the current team.
}];

let arguments = (ins Optional<AnyIntegerType>:$level);
let results = (outs fir_BoxType:$team);

let assemblyFormat = [{
(`level` $level^ )?
attr-dict `:` functional-type(operands, results)
}];
}

def mif_TeamNumberOp : mif_Op<"team_number", []> {
let summary = "Get the team number";
let description = [{
Argument: `team` is optional and shall be a scalar of type TEAM_TYPE from
module ISO_FORTRAN_ENV and the value identifies the current or an ancestor team.
If `team` is absent, the team specified is the current team.
}];

let arguments = (ins Optional<AnyRefOrBoxType>:$team);
let results = (outs I64);

let assemblyFormat = [{
(`team` $team^ )?
attr-dict `:` functional-type(operands, results)
}];
}

#endif // FORTRAN_DIALECT_MIF_MIF_OPS
53 changes: 49 additions & 4 deletions flang/lib/Lower/Bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "flang/Lower/Allocatable.h"
#include "flang/Lower/CUDA.h"
#include "flang/Lower/CallInterface.h"
#include "flang/Lower/Coarray.h"
#include "flang/Lower/ConvertCall.h"
#include "flang/Lower/ConvertExpr.h"
#include "flang/Lower/ConvertExprToHLFIR.h"
Expand All @@ -26,6 +25,7 @@
#include "flang/Lower/IO.h"
#include "flang/Lower/IterationSpace.h"
#include "flang/Lower/Mangler.h"
#include "flang/Lower/MultiImageFortran.h"
#include "flang/Lower/OpenACC.h"
#include "flang/Lower/OpenMP.h"
#include "flang/Lower/PFTBuilder.h"
Expand Down Expand Up @@ -1111,6 +1111,34 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return bridge.fctCtx();
}

/// Initializes values for STAT and ERRMSG
std::pair<mlir::Value, mlir::Value>
genStatAndErrmsg(mlir::Location loc,
const std::list<Fortran::parser::StatOrErrmsg>
&statOrErrList) override final {
Fortran::lower::StatementContext stmtCtx;

mlir::Value errMsgExpr, statExpr;
for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) {
std::visit(Fortran::common::visitors{
[&](const Fortran::parser::StatVariable &statVar) {
const Fortran::semantics::SomeExpr *expr =
Fortran::semantics::GetExpr(statVar);
statExpr =
fir::getBase(genExprAddr(*expr, stmtCtx, &loc));
},
[&](const Fortran::parser::MsgVariable &errMsgVar) {
const Fortran::semantics::SomeExpr *expr =
Fortran::semantics::GetExpr(errMsgVar);
errMsgExpr =
fir::getBase(genExprBox(loc, *expr, stmtCtx));
}},
statOrErr.u);
}

return {statExpr, errMsgExpr};
}

mlir::Value hostAssocTupleValue() override final { return hostAssocTuple; }

/// Record a binding for the ssa-value of the tuple for this function.
Expand Down Expand Up @@ -3950,13 +3978,30 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}

void genFIR(const Fortran::parser::ChangeTeamConstruct &construct) {
TODO(toLocation(), "coarray: ChangeTeamConstruct");
Fortran::lower::StatementContext stmtCtx;
pushActiveConstruct(getEval(), stmtCtx);

for (Fortran::lower::pft::Evaluation &e :
getEval().getNestedEvaluations()) {
if (e.getIf<Fortran::parser::ChangeTeamStmt>()) {
maybeStartBlock(e.block);
setCurrentPosition(e.position);
genFIR(e);
} else if (e.getIf<Fortran::parser::EndChangeTeamStmt>()) {
maybeStartBlock(e.block);
setCurrentPosition(e.position);
genFIR(e);
} else {
genFIR(e);
}
}
popActiveConstruct();
}
void genFIR(const Fortran::parser::ChangeTeamStmt &stmt) {
TODO(toLocation(), "coarray: ChangeTeamStmt");
genChangeTeamStmt(*this, getEval(), stmt);
}
void genFIR(const Fortran::parser::EndChangeTeamStmt &stmt) {
TODO(toLocation(), "coarray: EndChangeTeamStmt");
genEndChangeTeamStmt(*this, getEval(), stmt);
}

void genFIR(const Fortran::parser::CriticalConstruct &criticalConstruct) {
Expand Down
2 changes: 1 addition & 1 deletion flang/lib/Lower/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ add_flang_library(FortranLower
Allocatable.cpp
Bridge.cpp
CallInterface.cpp
Coarray.cpp
ComponentPath.cpp
ConvertArrayConstructor.cpp
ConvertCall.cpp
Expand All @@ -23,6 +22,7 @@ add_flang_library(FortranLower
IterationSpace.cpp
LoweringOptions.cpp
Mangler.cpp
MultiImageFortran.cpp
OpenACC.cpp
OpenMP/Atomic.cpp
OpenMP/ClauseProcessor.cpp
Expand Down
Loading