mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[flang] GETPID runtime and lower intrinsic implementation (#70442)
Runtime function GetPID calls the function getpid from unistd.h or process.h base on the OS.
This commit is contained in:
parent
b070629c10
commit
de58aa8372
@ -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, GETPID, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC |
|
||||
| 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 |
|
||||
|
@ -223,6 +223,8 @@ struct IntrinsicLibrary {
|
||||
mlir::Value genFraction(mlir::Type resultType,
|
||||
mlir::ArrayRef<mlir::Value> args);
|
||||
void genGetCommand(mlir::ArrayRef<fir::ExtendedValue> args);
|
||||
mlir::Value genGetPID(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args);
|
||||
void genGetCommandArgument(mlir::ArrayRef<fir::ExtendedValue> args);
|
||||
void genGetEnvironmentVariable(llvm::ArrayRef<fir::ExtendedValue>);
|
||||
fir::ExtendedValue genIall(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
|
||||
|
@ -31,6 +31,10 @@ mlir::Value genGetCommand(fir::FirOpBuilder &, mlir::Location,
|
||||
mlir::Value command, mlir::Value length,
|
||||
mlir::Value errmsg);
|
||||
|
||||
/// Generate a call to the GetPID runtime function which implements the
|
||||
/// GETPID intrinsic.
|
||||
mlir::Value genGetPID(fir::FirOpBuilder &, mlir::Location);
|
||||
|
||||
/// Generate a call to the GetCommandArgument runtime function which implements
|
||||
/// the GET_COMMAND_ARGUMENT intrinsic.
|
||||
/// \p value, \p length and \p errmsg must be fir.box that can be absent (but
|
||||
|
@ -25,8 +25,14 @@
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/MLIRContext.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
|
||||
#ifdef _WIN32
|
||||
// On Windows* OS GetCurrentProcessId returns DWORD aka uint32_t
|
||||
typedef std::uint32_t pid_t;
|
||||
#endif
|
||||
|
||||
// Incomplete type indicating C99 complex ABI in interfaces. Beware, _Complex
|
||||
// and std::complex are layout compatible, but not compatible in all ABI call
|
||||
// interfaces (e.g. X86 32 bits). _Complex is not standard C++, so do not use
|
||||
@ -62,6 +68,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 {
|
||||
|
@ -10,9 +10,15 @@
|
||||
#define FORTRAN_RUNTIME_COMMAND_H_
|
||||
|
||||
#include "flang/Runtime/entry-names.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#ifdef _WIN32
|
||||
// On Windows* OS GetCurrentProcessId returns DWORD aka uint32_t
|
||||
typedef std::uint32_t pid_t;
|
||||
#else
|
||||
#include "sys/types.h" //pid_t
|
||||
#endif
|
||||
|
||||
namespace Fortran::runtime {
|
||||
class Descriptor;
|
||||
|
||||
@ -23,6 +29,9 @@ extern "C" {
|
||||
// integer kind.
|
||||
std::int32_t RTNAME(ArgumentCount)();
|
||||
|
||||
// Calls getpid()
|
||||
pid_t RTNAME(GetPID)();
|
||||
|
||||
// 16.9.82 GET_COMMAND
|
||||
// Try to get the value of the whole command. All of the parameters are
|
||||
// optional.
|
||||
|
@ -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},
|
||||
{"getpid", {}, DefaultInt},
|
||||
{"huge",
|
||||
{{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
|
||||
common::Intent::In, {ArgFlag::canBeNull}}},
|
||||
|
@ -253,6 +253,7 @@ static constexpr IntrinsicHandler handlers[]{
|
||||
{"trim_name", asAddr, handleDynamicOptional},
|
||||
{"errmsg", asBox, handleDynamicOptional}}},
|
||||
/*isElemental=*/false},
|
||||
{"getpid", &I::genGetPID},
|
||||
{"iachar", &I::genIchar},
|
||||
{"iall",
|
||||
&I::genIall,
|
||||
@ -2944,6 +2945,14 @@ void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
}
|
||||
}
|
||||
|
||||
// GETPID
|
||||
mlir::Value IntrinsicLibrary::genGetPID(mlir::Type resultType,
|
||||
llvm::ArrayRef<mlir::Value> args) {
|
||||
assert(args.size() == 0 && "getpid takes no input");
|
||||
return builder.createConvert(loc, resultType,
|
||||
fir::runtime::genGetPID(builder, loc));
|
||||
}
|
||||
|
||||
// GET_COMMAND_ARGUMENT
|
||||
void IntrinsicLibrary::genGetCommandArgument(
|
||||
llvm::ArrayRef<fir::ExtendedValue> args) {
|
||||
|
@ -48,6 +48,14 @@ mlir::Value fir::runtime::genGetCommand(fir::FirOpBuilder &builder,
|
||||
return builder.create<fir::CallOp>(loc, runtimeFunc, args).getResult(0);
|
||||
}
|
||||
|
||||
mlir::Value fir::runtime::genGetPID(fir::FirOpBuilder &builder,
|
||||
mlir::Location loc) {
|
||||
auto runtimeFunc =
|
||||
fir::runtime::getRuntimeFunc<mkRTKey(GetPID)>(loc, builder);
|
||||
|
||||
return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
|
||||
}
|
||||
|
||||
mlir::Value fir::runtime::genGetCommandArgument(
|
||||
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Value number,
|
||||
mlir::Value value, mlir::Value length, mlir::Value errmsg) {
|
||||
|
@ -15,6 +15,18 @@
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
// On Windows GetCurrentProcessId returns a DWORD aka uint32_t
|
||||
#include <processthreadsapi.h>
|
||||
inline pid_t getpid() { return GetCurrentProcessId(); }
|
||||
#else
|
||||
#include <unistd.h> //getpid()
|
||||
#endif
|
||||
|
||||
namespace Fortran::runtime {
|
||||
std::int32_t RTNAME(ArgumentCount)() {
|
||||
int argc{executionEnvironment.argc};
|
||||
@ -25,6 +37,8 @@ std::int32_t RTNAME(ArgumentCount)() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t RTNAME(GetPID)() { return getpid(); }
|
||||
|
||||
// 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)};
|
||||
|
16
flang/test/Lower/Intrinsics/getpid.f90
Normal file
16
flang/test/Lower/Intrinsics/getpid.f90
Normal file
@ -0,0 +1,16 @@
|
||||
! RUN: bbc -emit-hlfir %s -o - | FileCheck %s
|
||||
|
||||
! CHECK-LABEL: func.func @_QPall_args() {
|
||||
! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "pid", uniq_name = "_QFall_argsEpid"}
|
||||
! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %0 {uniq_name = "_QFall_argsEpid"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
||||
! CHECK: %[[VAL_2:.*]] = fir.call @_FortranAGetPID() fastmath<contract> : () -> i32
|
||||
! CHECK: hlfir.assign %[[VAL_2:.*]] to %[[VAL_1:.*]]#0 : i32, !fir.ref<i32>
|
||||
! CHECK: return
|
||||
! CHECK: }
|
||||
|
||||
subroutine all_args()
|
||||
integer :: pid
|
||||
pid = getpid()
|
||||
end
|
||||
|
||||
|
@ -44,3 +44,10 @@ TEST_F(RuntimeCallTest, genGetEnvVariable) {
|
||||
checkCallOp(result.getDefiningOp(), "_FortranAGetEnvVariable", /*nbArgs=*/5,
|
||||
/*addLocArgs=*/true);
|
||||
}
|
||||
|
||||
TEST_F(RuntimeCallTest, genGetPID) {
|
||||
mlir::Location loc = firBuilder->getUnknownLoc();
|
||||
mlir::Value result = fir::runtime::genGetPID(*firBuilder, loc);
|
||||
checkCallOp(result.getDefiningOp(), "_FortranAGetPID", /*nbArgs=*/0,
|
||||
/*addLocArgs=*/false);
|
||||
}
|
@ -388,6 +388,11 @@ TEST_F(OnlyValidArguments, GetCommandShortLength) {
|
||||
CheckDescriptorEqInt<short>(length.get(), 51);
|
||||
}
|
||||
|
||||
TEST_F(ZeroArguments, GetPID) {
|
||||
// pid should always greater than 0, in both linux and windows
|
||||
EXPECT_GT(RTNAME(GetPID)(), 0);
|
||||
}
|
||||
|
||||
class EnvironmentVariables : public CommandFixture {
|
||||
protected:
|
||||
EnvironmentVariables() : CommandFixture(0, nullptr) {
|
||||
|
Loading…
Reference in New Issue
Block a user