[flang-commits] [flang] [flang] GETGID runtime and lowering intrinsics (PR #71553)

Yi Wu via flang-commits flang-commits at lists.llvm.org
Fri Nov 10 09:04:47 PST 2023


https://github.com/PAX-12-WU updated https://github.com/llvm/llvm-project/pull/71553

>From 4007c1e055d5562a3c086bb04dfe2026b491d493 Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Tue, 7 Nov 2023 15:58:30 +0000
Subject: [PATCH 1/2] GETGID runtime and lowering intrinsics

Returns the numerical group ID of the current process.
The value of GETGID is an INTEGER of the default kind.

On windows it returns a 0 as always.
Windows doesn't have getgid or anything Win32 equivalent, and it is also not supported in gfortran.
---
 flang/docs/Intrinsics.md                           |  2 +-
 .../flang/Optimizer/Builder/IntrinsicCall.h        |  2 ++
 .../flang/Optimizer/Builder/Runtime/Command.h      |  4 ++++
 .../flang/Optimizer/Builder/Runtime/RTBuilder.h    |  8 ++++++++
 flang/include/flang/Runtime/command.h              |  9 +++++++++
 flang/lib/Evaluate/intrinsics.cpp                  |  1 +
 flang/lib/Optimizer/Builder/IntrinsicCall.cpp      |  9 +++++++++
 flang/lib/Optimizer/Builder/Runtime/Command.cpp    |  8 ++++++++
 flang/runtime/command.cpp                          |  8 ++++++++
 flang/test/Lower/Intrinsics/getgid.f90             | 14 ++++++++++++++
 .../Optimizer/Builder/Runtime/CommandTest.cpp      |  7 +++++++
 flang/unittests/Runtime/CommandTest.cpp            |  6 ++++++
 12 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 flang/test/Lower/Intrinsics/getgid.f90

diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index ab0a940e53e5538..74eaff339be272d 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -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, GETGID |
 | 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 |
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 06db8cf9e9dc923..e200e2a5858d6ff 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -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 genGetGID(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.
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Command.h b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
index 9ecdba2c995b713..90da80eb16c5d2c 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Command.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
@@ -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 GetGID runtime function which implements the
+/// GETGID intrinsic.
+mlir::Value genGetGID(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
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
index b2774263e7a31a4..830df7ad006b54a 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h
@@ -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 {
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index ec6289390545479..d9a4d47420b5a1a 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -13,6 +13,12 @@
 
 #include <cstdint>
 
+#ifdef _WIN32
+typedef int gid_t;
+#else
+#include "sys/types.h" //gid_t
+#endif
+
 namespace Fortran::runtime {
 class Descriptor;
 
@@ -23,6 +29,9 @@ extern "C" {
 // integer kind.
 std::int32_t RTNAME(ArgumentCount)();
 
+// Calls getgid()
+gid_t RTNAME(GetGID)();
+
 // 16.9.82 GET_COMMAND
 // Try to get the value of the whole command. All of the parameters are
 // optional.
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index c711b4feaca4831..d311dc014113a46 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -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},
+    {"getgid", {}, DefaultInt},
     {"huge",
         {{"x", SameIntOrReal, Rank::anyOrAssumedRank, Optionality::required,
             common::Intent::In, {ArgFlag::canBeNull}}},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index fe40fd821f01013..a14b6de001bc095 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -253,6 +253,7 @@ static constexpr IntrinsicHandler handlers[]{
        {"trim_name", asAddr, handleDynamicOptional},
        {"errmsg", asBox, handleDynamicOptional}}},
      /*isElemental=*/false},
+    {"getgid", &I::genGetGID},
     {"iachar", &I::genIchar},
     {"iall",
      &I::genIall,
@@ -2906,6 +2907,14 @@ mlir::Value IntrinsicLibrary::genFraction(mlir::Type resultType,
       fir::runtime::genFraction(builder, loc, fir::getBase(args[0])));
 }
 
+// GETGID
+mlir::Value IntrinsicLibrary::genGetGID(mlir::Type resultType,
+                                        llvm::ArrayRef<mlir::Value> args) {
+  assert(args.size() == 0 && "getgid takes no input");
+  return builder.createConvert(loc, resultType,
+                               fir::runtime::genGetGID(builder, loc));
+}
+
 // GET_COMMAND
 void IntrinsicLibrary::genGetCommand(llvm::ArrayRef<fir::ExtendedValue> args) {
   assert(args.size() == 4);
diff --git a/flang/lib/Optimizer/Builder/Runtime/Command.cpp b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
index f56475a97487835..7ee3a70a9c9c5d5 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Command.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
@@ -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::genGetGID(fir::FirOpBuilder &builder,
+                                    mlir::Location loc) {
+  auto runtimeFunc =
+      fir::runtime::getRuntimeFunc<mkRTKey(GetGID)>(loc, builder);
+
+  return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index b81a0791c5e571b..33815801eab2c07 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -15,6 +15,12 @@
 #include <cstdlib>
 #include <limits>
 
+#ifdef _WIN32
+inline gid_t getgid() { return 0; }
+#else
+#include <unistd.h>
+#endif
+
 namespace Fortran::runtime {
 std::int32_t RTNAME(ArgumentCount)() {
   int argc{executionEnvironment.argc};
@@ -25,6 +31,8 @@ std::int32_t RTNAME(ArgumentCount)() {
   return 0;
 }
 
+gid_t RTNAME(GetGID)() { return getgid(); }
+
 // 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)};
diff --git a/flang/test/Lower/Intrinsics/getgid.f90 b/flang/test/Lower/Intrinsics/getgid.f90
new file mode 100644
index 000000000000000..5be1e096507859b
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/getgid.f90
@@ -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 = "gid", uniq_name = "_QFall_argsEgid"}
+! CHECK:         %[[VAL_1:.*]]:2 = hlfir.declare %0 {uniq_name = "_QFall_argsEgid"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK:         %[[VAL_2:.*]] = fir.call @_FortranAGetGID() fastmath<contract> : () -> i32
+! CHECK:         hlfir.assign %[[VAL_2:.*]] to %[[VAL_1:.*]]#0 : i32, !fir.ref<i32>
+! CHECK:         return
+! CHECK:       }
+
+subroutine all_args()
+  integer :: gid
+  gid = getgid()
+end
\ No newline at end of file
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index acc79ae63e9f698..1a5cace7f1b13e5 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -44,3 +44,10 @@ TEST_F(RuntimeCallTest, genGetEnvVariable) {
   checkCallOp(result.getDefiningOp(), "_FortranAGetEnvVariable", /*nbArgs=*/5,
       /*addLocArgs=*/true);
 }
+
+TEST_F(RuntimeCallTest, genGetGID) {
+  mlir::Location loc = firBuilder->getUnknownLoc();
+  mlir::Value result = fir::runtime::genGetGID(*firBuilder, loc);
+  checkCallOp(result.getDefiningOp(), "_FortranAGetGID", /*nbArgs=*/0,
+      /*addLocArgs=*/false);
+}
\ No newline at end of file
diff --git a/flang/unittests/Runtime/CommandTest.cpp b/flang/unittests/Runtime/CommandTest.cpp
index c3571c9684e4b07..a95a14b4d5b7146 100644
--- a/flang/unittests/Runtime/CommandTest.cpp
+++ b/flang/unittests/Runtime/CommandTest.cpp
@@ -227,6 +227,12 @@ TEST_F(ZeroArguments, GetCommandArgument) {
 
 TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
 
+TEST_F(ZeroArguments, GetGID) {
+  CheckMissingArgumentValue(-1);
+  CheckArgumentValue(commandOnlyArgv[0], 0);
+  CheckMissingArgumentValue(1);
+}
+
 static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
 class OneArgument : public CommandFixture {
 protected:

>From e6326a43bafeb1c37c5c833231da36bd916cb1d3 Mon Sep 17 00:00:00 2001
From: Yi Wu <yi.wu2 at arm.com>
Date: Fri, 10 Nov 2023 17:04:19 +0000
Subject: [PATCH 2/2] add assert false on windows, better to have compile
 waring in future, and format

Or replace by a printf? So the program won't be terminated by force.
---
 flang/runtime/command.cpp                                 | 5 ++++-
 flang/test/Lower/Intrinsics/getgid.f90                    | 2 +-
 flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index 33815801eab2c07..ca6908b35818607 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -16,7 +16,10 @@
 #include <limits>
 
 #ifdef _WIN32
-inline gid_t getgid() { return 0; }
+inline gid_t getgid() {
+  assert(false && "Unimplemented on Windows OS");
+  return 0;
+}
 #else
 #include <unistd.h>
 #endif
diff --git a/flang/test/Lower/Intrinsics/getgid.f90 b/flang/test/Lower/Intrinsics/getgid.f90
index 5be1e096507859b..059d6e95897f3ae 100644
--- a/flang/test/Lower/Intrinsics/getgid.f90
+++ b/flang/test/Lower/Intrinsics/getgid.f90
@@ -11,4 +11,4 @@
 subroutine all_args()
   integer :: gid
   gid = getgid()
-end
\ No newline at end of file
+end
diff --git a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
index 1a5cace7f1b13e5..de45ebe25f525da 100644
--- a/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
+++ b/flang/unittests/Optimizer/Builder/Runtime/CommandTest.cpp
@@ -50,4 +50,4 @@ TEST_F(RuntimeCallTest, genGetGID) {
   mlir::Value result = fir::runtime::genGetGID(*firBuilder, loc);
   checkCallOp(result.getDefiningOp(), "_FortranAGetGID", /*nbArgs=*/0,
       /*addLocArgs=*/false);
-}
\ No newline at end of file
+}



More information about the flang-commits mailing list