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