Skip to content

Conversation

@JDPailleux
Copy link
Contributor

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.

@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir labels Oct 29, 2025
@llvmbot
Copy link
Member

llvmbot commented Oct 29, 2025

@llvm/pr-subscribers-flang-fir-hlfir

Author: Jean-Didier PAILLEUX (JDPailleux)

Changes

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.


Patch is 78.85 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/165573.diff

18 Files Affected:

  • (modified) flang/include/flang/Optimizer/Builder/IntrinsicCall.h (+3)
  • (modified) flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td (+155)
  • (modified) flang/lib/Lower/Bridge.cpp (+20-3)
  • (modified) flang/lib/Lower/Coarray.cpp (+130-6)
  • (modified) flang/lib/Lower/Runtime.cpp (+19-2)
  • (modified) flang/lib/Optimizer/Builder/IntrinsicCall.cpp (+27)
  • (modified) flang/lib/Optimizer/Dialect/MIF/MIFOps.cpp (+107)
  • (modified) flang/lib/Optimizer/Transforms/MIFOpConversion.cpp (+248-11)
  • (added) flang/test/Fir/MIF/change_team.mlir (+53)
  • (added) flang/test/Fir/MIF/form_team.mlir (+58)
  • (added) flang/test/Fir/MIF/get_team.mlir (+70)
  • (added) flang/test/Fir/MIF/sync_team.mlir (+56)
  • (added) flang/test/Fir/MIF/team_number.mlir (+29)
  • (added) flang/test/Lower/MIF/change_team.f90 (+27)
  • (added) flang/test/Lower/MIF/form_team.f90 (+29)
  • (added) flang/test/Lower/MIF/get_team.f90 (+28)
  • (added) flang/test/Lower/MIF/sync_team.f90 (+25)
  • (added) flang/test/Lower/MIF/team_number.f90 (+19)
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index c3cd119b96174..bec33dccedcf1 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -292,6 +292,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, @@ -456,6 +457,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>); void genTMABulkCommitGroup(llvm::ArrayRef<fir::ExtendedValue>); void genTMABulkG2S(llvm::ArrayRef<fir::ExtendedValue>); diff --git a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td index 52471d3702b76..32055bd4a470b 100644 --- a/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td +++ b/flang/include/flang/Optimizer/Dialect/MIF/MIFOps.td @@ -21,6 +21,12 @@ 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])> { + let hasCustomAssemblyFormat = 1; +} + //===----------------------------------------------------------------------===// // Initialization and Finalization //===----------------------------------------------------------------------===// @@ -174,6 +180,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 //===----------------------------------------------------------------------===// @@ -265,4 +283,141 @@ 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">:$ensureTerminaison, + CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>, + OpBuilder<(ins "mlir::Value":$team, "mlir::Value":$stat, + "mlir::Value":$errmsg, CArg<"bool", "true">:$ensureTerminaison, + CArg<"llvm::ArrayRef<mlir::NamedAttribute>", "{}">:$attributes)>]; + + let extraClassDeclaration = [{ + /// Get the body of the CHANGE TEAM construct  + mlir::Block *getBody() { return &getRegion().front(); } + }]; +} + +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 diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index 6e729874eb5e6..daf8b6e6e243f 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -3950,13 +3950,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) { diff --git a/flang/lib/Lower/Coarray.cpp b/flang/lib/Lower/Coarray.cpp index a84f65a5c49e8..d0d986483ccbf 100644 --- a/flang/lib/Lower/Coarray.cpp +++ b/flang/lib/Lower/Coarray.cpp @@ -16,6 +16,7 @@ #include "flang/Lower/SymbolMap.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/Todo.h" +#include "flang/Optimizer/Dialect/MIF/MIFOps.h" #include "flang/Parser/parse-tree.h" #include "flang/Semantics/expression.h" @@ -33,21 +34,144 @@ void Fortran::lower::genChangeTeamConstruct( void Fortran::lower::genChangeTeamStmt( Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &, - const Fortran::parser::ChangeTeamStmt &) { - TODO(converter.getCurrentLocation(), "coarray: CHANGE TEAM statement"); + const Fortran::parser::ChangeTeamStmt &stmt) { + mlir::Location loc = converter.getCurrentLocation(); + converter.checkCoarrayEnabled(); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + + mlir::Value errMsgAddr, statAddr, team; + // Handle STAT and ERRMSG values + Fortran::lower::StatementContext stmtCtx; + const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList = + std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t); + for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) { + std::visit(Fortran::common::visitors{ + [&](const Fortran::parser::StatVariable &statVar) { + const auto *expr = Fortran::semantics::GetExpr(statVar); + statAddr = fir::getBase( + converter.genExprAddr(loc, *expr, stmtCtx)); + }, + [&](const Fortran::parser::MsgVariable &errMsgVar) { + const auto *expr = Fortran::semantics::GetExpr(errMsgVar); + errMsgAddr = fir::getBase( + converter.genExprBox(loc, *expr, stmtCtx)); + }, + }, + statOrErr.u); + } + + // TODO: Manage the list of coarrays associated in + // `std::list<CoarrayAssociation>`. According to the PRIF specification, it is + // necessary to call `prif_alias_{create|destroy}` for each coarray defined in + // this list. Support will be added once lowering to this procedure is + // possible. + const std::list<Fortran::parser::CoarrayAssociation> &coarrayAssocList = + std::get<std::list<Fortran::parser::CoarrayAssociation>>(stmt.t); + if (coarrayAssocList.size()) + mlir::emitWarning(loc, + "Coarrays provided in the association list are ignored."); + + // Handle TEAM-VALUE + const auto *teamExpr = + Fortran::semantics::GetExpr(std::get<Fortran::parser::TeamValue>(stmt.t)); + team = fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx)); + + mif::ChangeTeamOp changeOp = mif::ChangeTeamOp::create( + builder, loc, team, statAddr, errMsgAddr, /*terminator*/ false); + builder.setInsertionPointToStart(changeOp.getBody()); } void Fortran::lower::genEndChangeTeamStmt( Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &, - const Fortran::parser::EndChangeTeamStmt &) { - TODO(converter.getCurrentLocation(), "coarray: END CHANGE TEAM statement"); + const Fortran::parser::EndChangeTeamStmt &stmt) { + converter.checkCoarrayEnabled(); + mlir::Location loc = converter.getCurrentLocation(); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + + mlir::Value errMsgAddr, statAddr; + // Handle STAT and ERRMSG values + Fortran::lower::StatementContext stmtCtx; + const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList = + std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t); + for (const Fortran::parser::StatOrErrmsg &statOrErr : statOrErrList) { + std::visit(Fortran::common::visitors{ + [&](const Fortran::parser::StatVariable &statVar) { + const auto *expr = Fortran::semantics::GetExpr(statVar); + statAddr = fir::getBase( + converter.genExprAddr(loc, *expr, stmtCtx)); + }, + [&](const Fortran::parser::MsgVariable &errMsgVar) { + const auto *expr = Fortran::semantics::GetExpr(errMsgVar); + errMsgAddr = fir::getBase( + converter.genExprBox(loc, *expr, stmtCtx)); + }, + }, + statOrErr.u); + } + + mif::EndTeamOp endOp = + mif::EndTeamOp::create(builder, loc, statAddr, errMsgAddr); + builder.setInsertionPointAfter(endOp.getParentOp()); } void Fortran::lower::genFormTeamStatement( Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &, const Fortran::parser::FormTeamStmt &) { - TODO(converter.getCurrentLocation(), "coarray: FORM TEAM statement"); + Fortran::lower::pft::Evaluation &, + const Fortran::parser::FormTeamStmt &stmt) { + converter.checkCoarrayEnabled(); + mlir::Location loc = converter.getCurrentLocation(); + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + + mlir::Value errMsgAddr, statAddr, newIndex, teamNumber, team; + // Handle NEW_INDEX, STAT and ERRMSG + std::list<Fortran::parser::StatOrErrmsg> statOrErrList{}; + Fortran::lower::StatementContext stmtCtx; + const auto &formSpecList = + std::get<std::list<Fortran::parser::FormTeamStmt::FormTeamSpec>>(stmt.t); + for (const Fortran::parser::FormTeamStmt::FormTeamSpec &formSpec : + formSpecList) { + std::visit( + Fortran::common::visitors{ + [&](const Fortran::parser::StatOrErrmsg &statOrErr) { + std::visit( + Fortran::common::visitors{ + [&](const Fortran::parser::StatVariable &statVar) { + const auto *expr = Fortran::semantics::GetExpr(statVar); + statAddr = fir::getBase( + converter.genExprAddr(loc, *expr, stmtCtx)); + }, + [&](const Fortran::parser::MsgVariable &errMsgVar) { + const auto *expr = + Fortran::semantics::GetExpr(errMsgVar); + errMsgAddr = fir::getBase( + converter.genExprBox(loc, *expr, stmtCtx)); + }, + }, + statOrErr.u); + }, + [&](const Fortran::parser::ScalarIntExpr &intExpr) { + fir::ExtendedValue newIndexExpr = converter.genExprValue( + loc, Fortran::semantics::GetExpr(intExpr), stmtCtx); + newIndex = fir::getBase(newIndexExpr); + }, + }, + formSpec.u); + } + + // Handle TEAM-NUMBER + const auto *teamNumberExpr = Fortran::semantics::GetExpr( + std::get<Fortran::parser::ScalarIntExpr>(stmt.t)); + teamNumber = + fir::getBase(converter.genExprValue(loc, *teamNumberExpr, stmtCtx)); + + // Handle TEAM-VARIABLE + const auto *teamExpr = Fortran::semantics::GetExpr( + std::get<Fortran::parser::TeamVariable>(stmt.t)); + team = fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx)); + + mif::FormTeamOp::create(builder, loc, teamNumber, team, newIndex, statAddr, + errMsgAddr); } //===----------------------------------------------------------------------===// diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp index cb555249125f6..f8c5a72d0d66c 100644 --- a/flang/lib/Lower/Runtime.cpp +++ b/flang/lib/Lower/Runtime.cpp @@ -257,8 +257,25 @@ void Fortran::lower::genSyncMemoryStatement( void Fortran::lower::genSyncTeamStatement( Fortran::lower::AbstractConverter &converter, - const Fortran::parser::SyncTeamStmt &) { - TODO(converter.getCurrentLocation(), "coarray: SYNC TEAM runtime"); + const Fortran::parser::SyncTeamStmt &stmt) { + mlir::Location loc = converter.getCurrentLocation(); + converter.checkCoarrayEnabled(); + + // Handle TEAM + Fortran::lower::StatementContext stmtCtx; + const Fortran::parser::TeamValue &teamValue = + std::get<Fortran::parser::TeamValue>(stmt.t); + const SomeExpr *teamExpr = Fortran::semantics::GetExpr(teamValue); + mlir::Value team = + fir::getBase(converter.genExprBox(loc, *teamExpr, stmtCtx)); + + // Handle STAT and ERRMSG values + const std::list<Fortran::parser::StatOrErrmsg> &statOrErrList = + std::get<std::list<Fortran::parser::StatOrErrmsg>>(stmt.t); + auto [statAddr, errMsgAddr] = getStatAndErrmsg(converter, loc, statOrErrList); + + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + mif::SyncTeamOp::create(builder, loc, team, statAddr, errMsgAddr); } void Fortran::lower::genPauseStatement( diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 39bac818fe5d0..391128bfc5f99 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -553,6 +553,10 @@ static constexpr IntrinsicHandler handlers[]{ {"trim_name", asAddr, handleDynamicOptional}, {"errmsg", asBox, handleDynamicOptional}}}, /*isElemental=*/false}, + {"get_team", + &I::genGetTeam, + {{{"level", asValue, handleDynamicOptional}}}, + /*isElemental=*/false}, {"getcwd", &I::genGetCwd, {{{"c", asBox}, {"status", asAddr, handleDynamicOptional}}}, @@ -1012,6 +1016,10 @@ static constexpr IntrinsicHandler handlers[]{ /*isElemental=*/false}, {"tand", &I::genTand}, {"tanpi", &I::genTanpi}, + {"team_number", + &I::genTeamNumber, + {{{"team", asBox, handleDynamicOptional}}}, + /*isElemental=*/false}, {"this_grid", &I::genThisGrid, {}, /*isElemental=*/false}, {"this_image", &I::genThisImage, @@ -4543,6 +4551,15 @@ IntrinsicLibrary::genFtell(std::optional<mlir::Type> resultType, } } +// GET_TEAM +mlir::Value IntrinsicLibrary::genGetTeam(mlir::Type resultType, + llvm::ArrayRef<mlir::Value> args) { + converter->checkCoarrayEnabled(); + assert(args.size() == 1); + return mif::GetTeamOp::create(builder, loc, fir::BoxType::get(resultType), + /*level*/ args[0]); +} + // GETCWD fir::ExtendedValue IntrinsicLibrary::genGetCwd(std::optional<mlir::Type> resultType, @@ -8653,6 +8670,16 @@ IntrinsicLibrary::genThisImage(mlir::Type resultType, return builder.createConvert(loc, resultType, res); } ... [truncated] 
Copy link
Contributor

@bonachea bonachea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @JDPailleux for all this work, this looks like a great start on adding team features!

I've added some initial suggestions based on a quick skim of the code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the story with Fortran::lower::genChangeTeamConstruct() on line 27?

Is that just dead code that should be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the Fortran::lower::genChangeTeamConstruct(), I think this function was added when parsing was added to Flang for the construct CHANGE TEAM. However, I don't need it at the moment, but I will probably need it later when I will add support for CoarrayAssociationList.

Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

CHANGE TEAM have a partial support for coarray associated list. PRIF require to use prif_alias_{create|destroy} for each coarray in this list. It will upstream later, when coarray allocation and alias procedure will be added.
@ktras ktras requested a review from jeanPerier November 5, 2025 18:06
Copy link
Contributor

@jeanPerier jeanPerier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small nit, LGTM otherwise, thanks!

@JDPailleux
Copy link
Contributor Author

Thanks @jeanPerier :)

Copy link
Contributor

@ktras ktras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. I have verified through testing with Caffeine that this a flang built from this PR can produce executables with expected behavior when linked with a PRIF implementation.

Copy link
Contributor

@bonachea bonachea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as well. Thanks for all the improvements!

@JDPailleux
Copy link
Contributor Author

Thanks all :)

@JDPailleux JDPailleux merged commit d02a5ae into llvm:main Nov 12, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang Flang issues not falling into any other category

5 participants