Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
13 changes: 13 additions & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genNorm2(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genNot(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genNumImages(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
template <typename OpTy>
mlir::Value genNVVMTime(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genPack(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
Expand Down Expand Up @@ -449,6 +451,8 @@ struct IntrinsicLibrary {
fir::ExtendedValue genTranspose(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genThisGrid(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genThisImage(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genThisThreadBlock(mlir::Type, llvm::ArrayRef<mlir::Value>);
mlir::Value genThisWarp(mlir::Type, llvm::ArrayRef<mlir::Value>);
void genThreadFence(llvm::ArrayRef<fir::ExtendedValue>);
Expand Down Expand Up @@ -563,6 +567,15 @@ struct IntrinsicLibrary {

void setResultMustBeFreed() { resultMustBeFreed = true; }

// Check support of coarray features
void checkCoarrayEnabled() {
if (converter &&
!converter->getFoldingContext().languageFeatures().IsEnabled(
Fortran::common::LanguageFeature::Coarray))
fir::emitFatalError(loc, "Coarrays disabled, use '-fcoarray' to enable.",
Copy link
Contributor

Choose a reason for hiding this comment

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

If you could, please change this to something like:

not yet implemented: coarrays are experimental, use '-fcoarray' to enable
to keep the "not yet implemented" pattern in place. Thank you!

false);
}

fir::FirOpBuilder &builder;
mlir::Location loc;
bool resultMustBeFreed = false;
Expand Down
12 changes: 12 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/Coarray.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,17 @@ namespace fir::runtime {
/// Generate Call to runtime prif_init
mlir::Value genInitCoarray(fir::FirOpBuilder &builder, mlir::Location loc);

/// Generate Call to runtime prif_num_images
mlir::Value getNumImages(fir::FirOpBuilder &builder, mlir::Location loc);

/// Generate Call to runtime prif_num_images_with_team or
/// prif_num_images_with_team_number
mlir::Value getNumImagesWithTeam(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value team);

/// Generate Call to runtime prif_this_image_no_coarray
mlir::Value getThisImage(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value team = {});

} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COARRAY_H
45 changes: 45 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "flang/Optimizer/Builder/Runtime/Allocatable.h"
#include "flang/Optimizer/Builder/Runtime/CUDA/Descriptor.h"
#include "flang/Optimizer/Builder/Runtime/Character.h"
#include "flang/Optimizer/Builder/Runtime/Coarray.h"
#include "flang/Optimizer/Builder/Runtime/Command.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Exceptions.h"
Expand Down Expand Up @@ -778,6 +779,10 @@ static constexpr IntrinsicHandler handlers[]{
/*isElemental=*/false},
{"not", &I::genNot},
{"null", &I::genNull, {{{"mold", asInquired}}}, /*isElemental=*/false},
{"num_images",
&I::genNumImages,
{{{"team", asAddr}, {"team_number", asAddr}}},
/*isElemental*/ false},
{"pack",
&I::genPack,
{{{"array", asBox},
Expand Down Expand Up @@ -947,6 +952,12 @@ static constexpr IntrinsicHandler handlers[]{
{"tand", &I::genTand},
{"tanpi", &I::genTanpi},
{"this_grid", &I::genThisGrid, {}, /*isElemental=*/false},
{"this_image",
&I::genThisImage,
{{{"coarray", asBox},
{"dim", asAddr},
{"team", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"this_thread_block", &I::genThisThreadBlock, {}, /*isElemental=*/false},
{"this_warp", &I::genThisWarp, {}, /*isElemental=*/false},
{"threadfence", &I::genThreadFence, {}, /*isElemental=*/false},
Expand Down Expand Up @@ -7277,6 +7288,19 @@ IntrinsicLibrary::genNull(mlir::Type, llvm::ArrayRef<fir::ExtendedValue> args) {
return fir::MutableBoxValue(boxStorage, mold->nonDeferredLenParams(), {});
}

// NUM_IMAGES
fir::ExtendedValue
IntrinsicLibrary::genNumImages(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
checkCoarrayEnabled();
assert(args.size() == 0 || args.size() == 1);

if (args.size())
return fir::runtime::getNumImagesWithTeam(builder, loc,
fir::getBase(args[0]));
return fir::runtime::getNumImages(builder, loc);
}

// CLOCK, CLOCK64, GLOBALTIMER
template <typename OpTy>
mlir::Value IntrinsicLibrary::genNVVMTime(mlir::Type resultType,
Expand Down Expand Up @@ -8327,6 +8351,27 @@ mlir::Value IntrinsicLibrary::genThisGrid(mlir::Type resultType,
return res;
}

// THIS_IMAGE
fir::ExtendedValue
IntrinsicLibrary::genThisImage(mlir::Type resultType,
llvm::ArrayRef<fir::ExtendedValue> args) {
checkCoarrayEnabled();
assert(args.size() >= 1 && args.size() <= 3);
const bool coarrayIsAbsent = args.size() == 1;
mlir::Value team =
!isStaticallyAbsent(args, args.size() - 1)
? fir::getBase(args[args.size() - 1])
: builder
.create<fir::AbsentOp>(loc,
fir::BoxType::get(builder.getNoneType()))
.getResult();

if (!coarrayIsAbsent)
TODO(loc, "this_image with coarray argument.");
mlir::Value res = fir::runtime::getThisImage(builder, loc, team);
return builder.createConvert(loc, resultType, res);
}

// THIS_THREAD_BLOCK
mlir::Value
IntrinsicLibrary::genThisThreadBlock(mlir::Type resultType,
Expand Down
57 changes: 57 additions & 0 deletions flang/lib/Optimizer/Builder/Runtime/Coarray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,60 @@ mlir::Value fir::runtime::genInitCoarray(fir::FirOpBuilder &builder,
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}

/// Generate Call to runtime prif_num_images
mlir::Value fir::runtime::getNumImages(fir::FirOpBuilder &builder,
mlir::Location loc) {
mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
mlir::FunctionType ftype =
PRIF_FUNCTYPE(builder.getRefType(builder.getI32Type()));
mlir::func::FuncOp funcOp =
builder.createFunction(loc, PRIFNAME_SUB("num_images"), ftype);
llvm::SmallVector<mlir::Value> args =
fir::runtime::createArguments(builder, loc, ftype, result);
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}

/// Generate Call to runtime prif_num_images_with_{team|team_number}
mlir::Value fir::runtime::getNumImagesWithTeam(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value team) {
bool isTeamNumber = fir::unwrapPassByRefType(team.getType()).isInteger();
std::string numImagesName = isTeamNumber
? PRIFNAME_SUB("num_images_with_team_number")
: PRIFNAME_SUB("num_images_with_team");

mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
mlir::Type refTy = builder.getRefType(builder.getI32Type());
mlir::FunctionType ftype =
isTeamNumber
? PRIF_FUNCTYPE(builder.getRefType(builder.getI64Type()), refTy)
: PRIF_FUNCTYPE(fir::BoxType::get(builder.getNoneType()), refTy);
mlir::func::FuncOp funcOp = builder.createFunction(loc, numImagesName, ftype);

if (!isTeamNumber)
team = builder.createBox(loc, team);
llvm::SmallVector<mlir::Value> args =
fir::runtime::createArguments(builder, loc, ftype, team, result);
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}

/// Generate Call to runtime prif_this_image_no_coarray
mlir::Value fir::runtime::getThisImage(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value team) {
mlir::Type refTy = builder.getRefType(builder.getI32Type());
mlir::Type boxTy = fir::BoxType::get(builder.getNoneType());
mlir::FunctionType ftype = PRIF_FUNCTYPE(boxTy, refTy);
mlir::func::FuncOp funcOp =
builder.createFunction(loc, PRIFNAME_SUB("this_image_no_coarray"), ftype);

mlir::Value result = builder.createTemporary(loc, builder.getI32Type());
mlir::Value teamArg =
!team ? builder.create<fir::AbsentOp>(loc, boxTy) : team;
llvm::SmallVector<mlir::Value> args =
fir::runtime::createArguments(builder, loc, ftype, teamArg, result);
builder.create<fir::CallOp>(loc, funcOp, args);
return builder.create<fir::LoadOp>(loc, result);
}
18 changes: 18 additions & 0 deletions flang/test/Lower/Coarray/num_images.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s

program test
use iso_fortran_env
integer :: i
integer :: team_number
type(team_type) :: team

! CHECK: fir.call @_QMprifPprif_num_images
i = num_images()

! CHECK: fir.call @_QMprifPprif_num_images_with_team_number
i = num_images(TEAM_NUMBER=team_number)

! CHECK: fir.call @_QMprifPprif_num_images_with_team
i = num_images(TEAM=team)

end program
14 changes: 14 additions & 0 deletions flang/test/Lower/Coarray/this_image.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
! RUN: %flang_fc1 -emit-hlfir -fcoarray %s -o - | FileCheck %s

program test
use iso_fortran_env
integer :: i
type(team_type) :: team

! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
i = this_image()

! CHECK: fir.call @_QMprifPprif_this_image_no_coarray
i = this_image(TEAM=team)

end program