@@ -21,6 +21,10 @@ include "flang/Optimizer/Dialect/FIRAttr.td"
2121class 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
0 commit comments