Skip to content

Commit d02a5ae

Browse files
authored
[flang] Adding lowering of TEAMs features to PRIF in MIF Dialect (llvm#165573)
Support for multi-image features has begun to be integrated into LLVM with the MIF dialect. In this PR, you will find lowering and operations related to the TEAM features (`SYNC TEAM`, `GET_TEAM`, `FORM TEAM`, `CHANGE TEAM`, `TEAM_NUMBER`). Note regarding the operation for `CHANGE TEAM` : This operation is partial because it does not support the associated list of coarrays because the allocation of a coarray and the lowering of PRIF's `prif_alias_{create|destroy}` procedures are not yet supported in Flang. This will be integrated later. Any feedback is welcome.
1 parent 68a4af6 commit d02a5ae

File tree

24 files changed

+1229
-189
lines changed

24 files changed

+1229
-189
lines changed

flang/include/flang/Lower/AbstractConverter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,11 @@ class AbstractConverter {
351351

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

354+
/// Generate STAT and ERRMSG from a list of StatOrErrmsg
355+
virtual std::pair<mlir::Value, mlir::Value>
356+
genStatAndErrmsg(mlir::Location loc,
357+
const std::list<Fortran::parser::StatOrErrmsg> &) = 0;
358+
354359
AbstractConverter(const Fortran::lower::LoweringOptions &loweringOptions)
355360
: loweringOptions(loweringOptions) {}
356361
virtual ~AbstractConverter() = default;

flang/include/flang/Lower/Coarray.h renamed to flang/include/flang/Lower/MultiImageFortran.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
//===-- Lower/Coarray.h -- image related lowering ---------------*- C++ -*-===//
1+
//===-- Lower/MultiImageFortran.h -- image related lowering -----*- C++ -*-===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#ifndef FORTRAN_LOWER_COARRAY_H
10-
#define FORTRAN_LOWER_COARRAY_H
9+
#ifndef FORTRAN_LOWER_MULTIIMAGEFORTRAN_H
10+
#define FORTRAN_LOWER_MULTIIMAGEFORTRAN_H
1111

1212
#include "flang/Lower/AbstractConverter.h"
1313
#include "flang/Optimizer/Builder/BoxValue.h"
@@ -33,6 +33,18 @@ namespace pft {
3333
struct Evaluation;
3434
} // namespace pft
3535

36+
//===----------------------------------------------------------------------===//
37+
// Synchronization statements
38+
//===----------------------------------------------------------------------===//
39+
40+
void genSyncAllStatement(AbstractConverter &, const parser::SyncAllStmt &);
41+
42+
void genSyncImagesStatement(AbstractConverter &,
43+
const parser::SyncImagesStmt &);
44+
void genSyncMemoryStatement(AbstractConverter &,
45+
const parser::SyncMemoryStmt &);
46+
void genSyncTeamStatement(AbstractConverter &, const parser::SyncTeamStmt &);
47+
3648
//===----------------------------------------------------------------------===//
3749
// TEAM constructs
3850
//===----------------------------------------------------------------------===//
@@ -75,4 +87,4 @@ class CoarrayExprHelper {
7587
} // namespace lower
7688
} // namespace Fortran
7789

78-
#endif // FORTRAN_LOWER_COARRAY_H
90+
#endif // FORTRAN_LOWER_MULTIIMAGEFORTRAN_H

flang/include/flang/Lower/Runtime.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ void genEventWaitStatement(AbstractConverter &, const parser::EventWaitStmt &);
5757
void genLockStatement(AbstractConverter &, const parser::LockStmt &);
5858
void genFailImageStatement(AbstractConverter &);
5959
void genStopStatement(AbstractConverter &, const parser::StopStmt &);
60-
void genSyncAllStatement(AbstractConverter &, const parser::SyncAllStmt &);
61-
void genSyncImagesStatement(AbstractConverter &,
62-
const parser::SyncImagesStmt &);
63-
void genSyncMemoryStatement(AbstractConverter &,
64-
const parser::SyncMemoryStmt &);
65-
void genSyncTeamStatement(AbstractConverter &, const parser::SyncTeamStmt &);
6660
void genUnlockStatement(AbstractConverter &, const parser::UnlockStmt &);
6761
void genPauseStatement(AbstractConverter &, const parser::PauseStmt &);
6862

flang/include/flang/Optimizer/Builder/IntrinsicCall.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ struct IntrinsicLibrary {
270270
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
271271
mlir::Value genGetGID(mlir::Type resultType,
272272
llvm::ArrayRef<mlir::Value> args);
273+
mlir::Value genGetTeam(mlir::Type, llvm::ArrayRef<mlir::Value>);
273274
mlir::Value genGetUID(mlir::Type resultType,
274275
llvm::ArrayRef<mlir::Value> args);
275276
fir::ExtendedValue genHostnm(std::optional<mlir::Type> resultType,
@@ -425,6 +426,8 @@ struct IntrinsicLibrary {
425426
void genSystemClock(llvm::ArrayRef<fir::ExtendedValue>);
426427
mlir::Value genTand(mlir::Type, llvm::ArrayRef<mlir::Value>);
427428
mlir::Value genTanpi(mlir::Type, llvm::ArrayRef<mlir::Value>);
429+
fir::ExtendedValue genTeamNumber(mlir::Type,
430+
llvm::ArrayRef<fir::ExtendedValue>);
428431
mlir::Value genTime(mlir::Type, llvm::ArrayRef<mlir::Value>);
429432
mlir::Value genTrailz(mlir::Type, llvm::ArrayRef<mlir::Value>);
430433
fir::ExtendedValue genTransfer(mlir::Type,

flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ include "flang/Optimizer/Dialect/FIRAttr.td"
2121
class mif_Op<string mnemonic, list<Trait> traits>
2222
: Op<MIFDialect, mnemonic, traits>;
2323

24+
class region_Op<string mnemonic, list<Trait> traits = []>
25+
: mif_Op<mnemonic, !listconcat(traits, [RecursivelySpeculatable,
26+
RecursiveMemoryEffects])> {}
27+
2428
//===----------------------------------------------------------------------===//
2529
// Initialization and Finalization
2630
//===----------------------------------------------------------------------===//
@@ -174,6 +178,18 @@ def mif_SyncMemoryOp : mif_Op<"sync_memory", [AttrSizedOperandSegments]> {
174178
}];
175179
}
176180

181+
def mif_SyncTeamOp : mif_Op<"sync_team", [AttrSizedOperandSegments]> {
182+
let summary = "Performs a synchronization of the team, identified by `team`";
183+
184+
let arguments = (ins AnyRefOrBoxType:$team, Optional<AnyReferenceLike>:$stat,
185+
Optional<AnyRefOrBoxType>:$errmsg);
186+
let assemblyFormat = [{
187+
$team (`stat` $stat^ )?
188+
(`errmsg` $errmsg^ )?
189+
attr-dict `:` functional-type(operands, results)
190+
}];
191+
}
192+
177193
//===----------------------------------------------------------------------===//
178194
// Collective Operations
179195
//===----------------------------------------------------------------------===//
@@ -265,4 +281,148 @@ def mif_CoSumOp
265281
}];
266282
}
267283

284+
//===----------------------------------------------------------------------===//
285+
// Teams
286+
//===----------------------------------------------------------------------===//
287+
288+
def mif_FormTeamOp : mif_Op<"form_team", [AttrSizedOperandSegments]> {
289+
let summary =
290+
"Create a set of sibling teams whose parent team is the current team.";
291+
let description = [{
292+
Create a new team for each unique `team_number` value specified.
293+
Each executing image will belong to the team whose `team_number` is equal
294+
to the value of team-number on that image, and `team_var` becomes defined
295+
with a value that identifies that team.
296+
297+
If `new_index` is specified, the image index of the executing image will take
298+
this index in its new team. Otherwise, the new image index is processor
299+
dependent.
300+
301+
Arguments:
302+
- `team_number`: Shall be a positive integer.
303+
- `team_var` : Shall be a variable of type TEAM_TYPE from the intrinsic
304+
module ISO_FORTRAN_ENV.
305+
- `new_index`(optional): Shall be an integer that correspond to the index that
306+
the calling image will have in the new team.
307+
}];
308+
309+
let arguments = (ins AnyIntegerType:$team_number,
310+
Arg<fir_BoxType, "", [MemWrite]>:$team_var,
311+
Optional<AnyIntegerType>:$new_index,
312+
Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
313+
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
314+
315+
let assemblyFormat = [{
316+
`team_number` $team_number `team_var` $team_var
317+
(`new_index` $new_index^ )?
318+
(`stat` $stat^ )?
319+
(`errmsg` $errmsg^ )?
320+
attr-dict `:` functional-type(operands, results)
321+
}];
322+
}
323+
324+
def mif_EndTeamOp : mif_Op<"end_team", [AttrSizedOperandSegments, Terminator,
325+
ParentOneOf<["ChangeTeamOp"]>]> {
326+
let summary = "Changes the current team to the parent team.";
327+
let description = [{
328+
The END TEAM operation completes the CHANGE TEAM construct and
329+
restores the current team to the team that was current before
330+
the CHANGE TEAM construct.
331+
}];
332+
333+
let arguments = (ins Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
334+
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
335+
let builders = [OpBuilder<(ins), [{ /* do nothing */ }]>];
336+
337+
let assemblyFormat = [{
338+
(`stat` $stat^ )? (`errmsg` $errmsg^ )?
339+
attr-dict `:` functional-type(operands, results)
340+
}];
341+
}
342+
343+
//===----------------------------------------------------------------------===//
344+
// NOTE: The CHANGE TEAM region will take a coarray association list in
345+
// argument. However, coarray management and coarray alias creation are not
346+
// yet supported by the dialect. The argument is therefore not yet supported by
347+
// this operation and will be added later.
348+
//===----------------------------------------------------------------------===//
349+
def mif_ChangeTeamOp
350+
: region_Op<"change_team", [AttrSizedOperandSegments,
351+
SingleBlockImplicitTerminator<"EndTeamOp">]> {
352+
let summary = "Changes the current team.";
353+
let description = [{
354+
The CHANGE TEAM construct changes the current team to the specified new
355+
team, which must be a child team of the current team.
356+
357+
```
358+
mif.change_team %team {
359+
%x = fir.convert %i : (index) -> i32
360+
...
361+
mif.end_team
362+
}
363+
}];
364+
365+
let arguments = (ins AnyRefOrBoxType:$team,
366+
Arg<Optional<AnyReferenceLike>, "", [MemWrite]>:$stat,
367+
Arg<Optional<AnyRefOrBoxType>, "", [MemWrite]>:$errmsg);
368+
let regions = (region SizedRegion<1>:$region);
369+
370+
let skipDefaultBuilders = 1;
371+
let builders =
372+
[OpBuilder<(ins "mlir::Value":$team,
373+
CArg<"bool", "true">:$ensureTermination,
374+
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>,
375+
OpBuilder<(ins "mlir::Value":$team, "mlir::Value":$stat,
376+
"mlir::Value":$errmsg, CArg<"bool", "true">:$ensureTermination,
377+
CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>];
378+
379+
let extraClassDeclaration = [{
380+
/// Get the body of the CHANGE TEAM construct
381+
mlir::Block *getBody() { return &getRegion().front(); }
382+
}];
383+
384+
let assemblyFormat = [{
385+
$team (`stat` $stat^)?
386+
(`errmsg` $errmsg^)?
387+
attr-dict `:` `(` type(operands) `)`
388+
custom<ChangeTeamOpBody>($region)
389+
}];
390+
}
391+
392+
def mif_GetTeamOp : mif_Op<"get_team", []> {
393+
let summary = "Get the team value for the current or ancestor team.";
394+
let description = [{
395+
This operation gets the team value for the current or an ancestor team.
396+
`level`(optional): If provided, must equal one of the following constants :
397+
`INITIAL_TEAM`, `PARENT_TEAM` or `CURRENT_TEAM` from the module ISO_FORTRAN_ENV.
398+
If `level` isn't present or has the value `CURRENT_TEAM` the returned
399+
value is the current team.
400+
}];
401+
402+
let arguments = (ins Optional<AnyIntegerType>:$level);
403+
let results = (outs fir_BoxType:$team);
404+
405+
let assemblyFormat = [{
406+
(`level` $level^ )?
407+
attr-dict `:` functional-type(operands, results)
408+
}];
409+
}
410+
411+
def mif_TeamNumberOp : mif_Op<"team_number", []> {
412+
let summary = "Get the team number";
413+
let description = [{
414+
Argument: `team` is optional and shall be a scalar of type TEAM_TYPE from
415+
module ISO_FORTRAN_ENV and the value identifies the current or an ancestor team.
416+
If `team` is absent, the team specified is the current team.
417+
}];
418+
419+
let arguments = (ins Optional<AnyRefOrBoxType>:$team);
420+
let results = (outs I64);
421+
422+
let assemblyFormat = [{
423+
(`team` $team^ )?
424+
attr-dict `:` functional-type(operands, results)
425+
}];
426+
}
427+
268428
#endif // FORTRAN_DIALECT_MIF_MIF_OPS

flang/lib/Lower/Bridge.cpp

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "flang/Lower/Allocatable.h"
1616
#include "flang/Lower/CUDA.h"
1717
#include "flang/Lower/CallInterface.h"
18-
#include "flang/Lower/Coarray.h"
1918
#include "flang/Lower/ConvertCall.h"
2019
#include "flang/Lower/ConvertExpr.h"
2120
#include "flang/Lower/ConvertExprToHLFIR.h"
@@ -26,6 +25,7 @@
2625
#include "flang/Lower/IO.h"
2726
#include "flang/Lower/IterationSpace.h"
2827
#include "flang/Lower/Mangler.h"
28+
#include "flang/Lower/MultiImageFortran.h"
2929
#include "flang/Lower/OpenACC.h"
3030
#include "flang/Lower/OpenMP.h"
3131
#include "flang/Lower/PFTBuilder.h"
@@ -1111,6 +1111,34 @@ class FirConverter : public Fortran::lower::AbstractConverter {
11111111
return bridge.fctCtx();
11121112
}
11131113

1114+
/// Initializes values for STAT and ERRMSG
1115+
std::pair<mlir::Value, mlir::Value>
1116+
genStatAndErrmsg(mlir::Location loc,
1117+
const std::list<Fortran::parser::StatOrErrmsg>
1118+
&statOrErrList) override final {
1119+
Fortran::lower::StatementContext stmtCtx;
1120+
1121+
mlir::Value errMsgExpr, statExpr;
1122+
for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) {
1123+
std::visit(Fortran::common::visitors{
1124+
[&](const Fortran::parser::StatVariable &statVar) {
1125+
const Fortran::semantics::SomeExpr *expr =
1126+
Fortran::semantics::GetExpr(statVar);
1127+
statExpr =
1128+
fir::getBase(genExprAddr(*expr, stmtCtx, &loc));
1129+
},
1130+
[&](const Fortran::parser::MsgVariable &errMsgVar) {
1131+
const Fortran::semantics::SomeExpr *expr =
1132+
Fortran::semantics::GetExpr(errMsgVar);
1133+
errMsgExpr =
1134+
fir::getBase(genExprBox(loc, *expr, stmtCtx));
1135+
}},
1136+
statOrErr.u);
1137+
}
1138+
1139+
return {statExpr, errMsgExpr};
1140+
}
1141+
11141142
mlir::Value hostAssocTupleValue() override final { return hostAssocTuple; }
11151143

11161144
/// Record a binding for the ssa-value of the tuple for this function.
@@ -3953,13 +3981,30 @@ class FirConverter : public Fortran::lower::AbstractConverter {
39533981
}
39543982

39553983
void genFIR(const Fortran::parser::ChangeTeamConstruct &construct) {
3956-
TODO(toLocation(), "coarray: ChangeTeamConstruct");
3984+
Fortran::lower::StatementContext stmtCtx;
3985+
pushActiveConstruct(getEval(), stmtCtx);
3986+
3987+
for (Fortran::lower::pft::Evaluation &e :
3988+
getEval().getNestedEvaluations()) {
3989+
if (e.getIf<Fortran::parser::ChangeTeamStmt>()) {
3990+
maybeStartBlock(e.block);
3991+
setCurrentPosition(e.position);
3992+
genFIR(e);
3993+
} else if (e.getIf<Fortran::parser::EndChangeTeamStmt>()) {
3994+
maybeStartBlock(e.block);
3995+
setCurrentPosition(e.position);
3996+
genFIR(e);
3997+
} else {
3998+
genFIR(e);
3999+
}
4000+
}
4001+
popActiveConstruct();
39574002
}
39584003
void genFIR(const Fortran::parser::ChangeTeamStmt &stmt) {
3959-
TODO(toLocation(), "coarray: ChangeTeamStmt");
4004+
genChangeTeamStmt(*this, getEval(), stmt);
39604005
}
39614006
void genFIR(const Fortran::parser::EndChangeTeamStmt &stmt) {
3962-
TODO(toLocation(), "coarray: EndChangeTeamStmt");
4007+
genEndChangeTeamStmt(*this, getEval(), stmt);
39634008
}
39644009

39654010
void genFIR(const Fortran::parser::CriticalConstruct &criticalConstruct) {

flang/lib/Lower/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ add_flang_library(FortranLower
55
Allocatable.cpp
66
Bridge.cpp
77
CallInterface.cpp
8-
Coarray.cpp
98
ComponentPath.cpp
109
ConvertArrayConstructor.cpp
1110
ConvertCall.cpp
@@ -23,6 +22,7 @@ add_flang_library(FortranLower
2322
IterationSpace.cpp
2423
LoweringOptions.cpp
2524
Mangler.cpp
25+
MultiImageFortran.cpp
2626
OpenACC.cpp
2727
OpenMP/Atomic.cpp
2828
OpenMP/ClauseProcessor.cpp

0 commit comments

Comments
 (0)