Skip to content

[flang] GETUID runtime and lowering intrinsics #71689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
2 changes: 1 addition & 1 deletion flang/docs/Intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ This phase currently supports all the intrinsic procedures listed above but the
| Coarray intrinsic functions | IMAGE_INDEX, COSHAPE |
| Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE |
| Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY|
| Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC |
| Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC, GETUID |
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK |
| Atomic intrinsic subroutines | ATOMIC_ADD |
| Collective intrinsic subroutines | CO_REDUCE |
Expand Down
2 changes: 2 additions & 0 deletions flang/include/flang/Optimizer/Builder/IntrinsicCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ struct IntrinsicLibrary {
void genGetCommand(mlir::ArrayRef<fir::ExtendedValue> args);
void genGetCommandArgument(mlir::ArrayRef<fir::ExtendedValue> args);
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genGetUID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args);
fir::ExtendedValue genIall(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
/// Lowering for the IAND intrinsic. The IAND intrinsic expects two arguments
/// in the llvm::ArrayRef.
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ namespace fir::runtime {
/// Generate call to COMMAND_ARGUMENT_COUNT intrinsic runtime routine.
mlir::Value genCommandArgumentCount(fir::FirOpBuilder &, mlir::Location);

/// Generate a call to the GetUID runtime function which implements the
/// GETUID intrinsic.
mlir::Value genGetUID(fir::FirOpBuilder &, mlir::Location);

/// Generate a call to the GetCommand runtime function which implements the
/// GET_COMMAND intrinsic.
/// \p command, \p length and \p errmsg must be fir.box that can be absent (but
Expand Down
8 changes: 8 additions & 0 deletions flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *);
/// standard type `i32` when `sizeof(int)` is 4.
template <typename T>
static constexpr TypeBuilderFunc getModel();

template <>
constexpr TypeBuilderFunc getModel<unsigned int>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
return mlir::IntegerType::get(context, 8 * sizeof(unsigned int));
};
}

template <>
constexpr TypeBuilderFunc getModel<short int>() {
return [](mlir::MLIRContext *context) -> mlir::Type {
Expand Down
10 changes: 10 additions & 0 deletions flang/include/flang/Runtime/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

#include <cstdint>

#ifdef _WIN32
typedef int uid_t;
#else
#include "sys/types.h" //uid_t
#endif

namespace Fortran::runtime {
class Descriptor;

Expand All @@ -23,6 +29,9 @@ extern "C" {
// integer kind.
std::int32_t RTNAME(ArgumentCount)();

// Calls getuid()
uid_t RTNAME(GetUID)();

// 16.9.82 GET_COMMAND
// Try to get the value of the whole command. All of the parameters are
// optional.
Expand All @@ -47,6 +56,7 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
bool trim_name = true, const Descriptor *errmsg = nullptr,
const char *sourceFile = nullptr, int line = 0);
}

} // namespace Fortran::runtime

#endif // FORTRAN_RUNTIME_COMMAND_H_
1 change: 1 addition & 0 deletions flang/lib/Evaluate/intrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{"gamma", {{"x", SameReal}}, SameReal},
{"get_team", {{"level", DefaultInt, Rank::scalar, Optionality::optional}},
TeamType, Rank::scalar, IntrinsicClass::transformationalFunction},
{"getuid", {}, DefaultInt},
{"huge",
{{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
common::Intent::In, {ArgFlag::canBeNull}}},
Expand Down
9 changes: 9 additions & 0 deletions flang/lib/Optimizer/Builder/IntrinsicCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ static constexpr IntrinsicHandler handlers[]{
{"trim_name", asAddr, handleDynamicOptional},
{"errmsg", asBox, handleDynamicOptional}}},
/*isElemental=*/false},
{"getuid", &I::genGetUID},
{"iachar", &I::genIchar},
{"iall",
&I::genIall,
Expand Down Expand Up @@ -2906,6 +2907,14 @@ mlir::Value IntrinsicLibrary::genFraction(mlir::Type resultType,
fir::runtime::genFraction(builder, loc, fir::getBase(args[0])));
}

// GETUID
mlir::Value IntrinsicLibrary::genGetUID(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {
assert(args.size() == 0 && "getuid takes no input");
return builder.createConvert(loc, resultType,
fir::runtime::genGetUID(builder, loc));
}

// GET_COMMAND
void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 4);
Expand Down
8 changes: 8 additions & 0 deletions flang/lib/Optimizer/Builder/Runtime/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,11 @@ mlir::Value fir::runtime::genGetEnvVariable(fir::FirOpBuilder &builder,
sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
}

mlir::Value fir::runtime::genGetUID(fir::FirOpBuilder &builder,
mlir::Location loc) {
auto runtimeFunc =
fir::runtime::getRuntimeFunc<mkRTKey(GetUID)>(loc, builder);

return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
}
11 changes: 11 additions & 0 deletions flang/runtime/command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@
#include <cstdlib>
#include <limits>

#ifdef _WIN32
inline uid_t getuid() {
assert(false && "Unimplemented on Windows OS");
return 0;
}
#else
#include <unistd.h>
#endif

namespace Fortran::runtime {
std::int32_t RTNAME(ArgumentCount)() {
int argc{executionEnvironment.argc};
Expand All @@ -25,6 +34,8 @@ std::int32_t RTNAME(ArgumentCount)() {
return 0;
}

uid_t RTNAME(GetUID)() { return getuid(); }

// Returns the length of the \p string. Assumes \p string is valid.
static std::int64_t StringLength(const char *string) {
std::size_t length{std::strlen(string)};
Expand Down
14 changes: 14 additions & 0 deletions flang/test/Lower/Intrinsics/getuid.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s

! CHECK-LABEL: func.func @_QPall_args() {
! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "uid", uniq_name = "_QFall_argsEuid"}
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %0 {uniq_name = "_QFall_argsEuid"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
! CHECK: %[[VAL_2:.*]] = fir.call @_FortranAGetUID() fastmath<contract> : () -> i32
! CHECK: hlfir.assign %[[VAL_2:.*]] to %[[VAL_1:.*]]#0 : i32, !fir.ref<i32>
! CHECK: return
! CHECK: }

subroutine all_args()
integer :: uid
uid = getuid()
end
7 changes: 7 additions & 0 deletions flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,10 @@ TEST_F(RuntimeCallTest, genGetEnvVariable) {
checkCallOp(result.getDefiningOp(), "_FortranAGetEnvVariable", /*nbArgs=*/5,
/*addLocArgs=*/true);
}

TEST_F(RuntimeCallTest, genGetUID) {
mlir::Location loc = firBuilder->getUnknownLoc();
mlir::Value result = fir::runtime::genGetUID(*firBuilder, loc);
checkCallOp(result.getDefiningOp(), "_FortranAGetUID", /*nbArgs=*/0,
/*addLocArgs=*/false);
}
6 changes: 6 additions & 0 deletions flang/unittests/Runtime/CommandTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ TEST_F(ZeroArguments, GetCommandArgument) {

TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }

TEST_F(ZeroArguments, GetUID) {
CheckMissingArgumentValue(-1);
CheckArgumentValue(commandOnlyArgv[0], 0);
CheckMissingArgumentValue(1);
}

static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
class OneArgument : public CommandFixture {
protected:
Expand Down