[flang] [llvm] [flang-rt] Runtime implementation of extended intrinsic function SECNDS() (PR #152021)
Eugene Epshteyn via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 13:08:45 PDT 2025
https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/152021
>From 68a1a813d46719382da3a67a973eb310bccb6e2a Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 Aug 2025 16:00:56 -0400
Subject: [PATCH 1/5] [flang-rt] Runtime implementation of extended intrinsic
function SECNDS()
---
flang-rt/lib/runtime/command.cpp | 7 +++++
flang-rt/lib/runtime/extensions.cpp | 39 ++++++++++++++++++++++++
flang/include/flang/Runtime/command.h | 2 ++
flang/include/flang/Runtime/extensions.h | 3 ++
4 files changed, 51 insertions(+)
diff --git a/flang-rt/lib/runtime/command.cpp b/flang-rt/lib/runtime/command.cpp
index a4e8e31ad0274..40233392f2497 100644
--- a/flang-rt/lib/runtime/command.cpp
+++ b/flang-rt/lib/runtime/command.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Runtime/command.h"
+#include "flang/Runtime/extensions.h"
#include "flang-rt/runtime/descriptor.h"
#include "flang-rt/runtime/environment.h"
#include "flang-rt/runtime/stat.h"
@@ -309,6 +310,12 @@ std::int32_t RTNAME(Hostnm)(
return status;
}
+float RTNAME(Secnds)(float* refTime, const char *sourceFile, int line) {
+ Terminator terminator{sourceFile, line};
+ RUNTIME_CHECK(terminator, refTime != nullptr);
+ return FORTRAN_PROCEDURE_NAME(secnds)(refTime);
+}
+
std::int32_t RTNAME(PutEnv)(
const char *str, size_t str_length, const char *sourceFile, int line) {
Terminator terminator{sourceFile, line};
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index f6c39468d5655..4751fb24af849 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -303,6 +303,45 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
// PERROR(STRING)
void RTNAME(Perror)(const char *str) { perror(str); }
+// GNU extension function SECNDS(refTime)
+float FORTRAN_PROCEDURE_NAME(secnds)(float* refTime) {
+ constexpr float FAIL_SECNDS{1.0f};
+ if (!refTime) {
+ return FAIL_SECNDS;
+ }
+ std::time_t now{std::time(nullptr)};
+ if (now == std::time_t{-1}) {
+ return FAIL_SECNDS;
+ }
+ // In float result, we can only precisely store 2^24 seconds, which
+ // comes out to about 194 days. Thus, need to peek a starting point.
+ // Given the description of this function, midnight of the current
+ // day is the best starting point.
+ static time_t startingPoint{0};
+ if (!startingPoint) {
+ struct tm timeInfo;
+#ifdef _WIN32
+ if (localtime_s(&timeInfo, &now)) {
+ return FAIL_SECNDS;
+ }
+#else
+ if (!localtime_r(&now, &timeInfo)) {
+ return FAIL_SECNDS;
+ }
+#endif
+ // Back to midnight
+ timeInfo.tm_hour = 0;
+ timeInfo.tm_min = 0;
+ timeInfo.tm_sec = 0;
+ startingPoint = std::mktime(&timeInfo);
+ if (startingPoint == std::time_t(-1)) {
+ return FAIL_SECNDS;
+ }
+ }
+ double diffStartingPoint = std::difftime(now, startingPoint);
+ return static_cast<float>(diffStartingPoint) - *refTime;
+}
+
// GNU extension function TIME()
std::int64_t RTNAME(time)() { return time(nullptr); }
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 19b486094da17..21ca1fa8457ee 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -67,6 +67,8 @@ std::int32_t RTNAME(Hostnm)(
std::int32_t RTNAME(PutEnv)(
const char *str, size_t str_length, const char *sourceFile, int line);
+float RTNAME(Secnds)(float* refTime, const char *sourceFile, int line);
+
// Calls unlink()
std::int32_t RTNAME(Unlink)(
const char *path, size_t pathLength, const char *sourceFile, int line);
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index b350204714431..a5bfa8b535286 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -90,5 +90,8 @@ void RTNAME(Perror)(const char *str);
// MCLOCK -- returns accumulated time in ticks
int FORTRAN_PROCEDURE_NAME(mclock)();
+// GNU extension subroutine SECNDS(refTime)
+float FORTRAN_PROCEDURE_NAME(secnds)(float* refTime);
+
} // extern "C"
#endif // FORTRAN_RUNTIME_EXTENSIONS_H_
>From 716f82d03cb17a493891c2af761cdf4461e5e13a Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 Aug 2025 16:01:50 -0400
Subject: [PATCH 2/5] clang-format
---
flang-rt/lib/runtime/command.cpp | 4 ++--
flang-rt/lib/runtime/extensions.cpp | 2 +-
flang/include/flang/Runtime/command.h | 2 +-
flang/include/flang/Runtime/extensions.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/flang-rt/lib/runtime/command.cpp b/flang-rt/lib/runtime/command.cpp
index 40233392f2497..ade77e9dd8d0f 100644
--- a/flang-rt/lib/runtime/command.cpp
+++ b/flang-rt/lib/runtime/command.cpp
@@ -7,12 +7,12 @@
//===----------------------------------------------------------------------===//
#include "flang/Runtime/command.h"
-#include "flang/Runtime/extensions.h"
#include "flang-rt/runtime/descriptor.h"
#include "flang-rt/runtime/environment.h"
#include "flang-rt/runtime/stat.h"
#include "flang-rt/runtime/terminator.h"
#include "flang-rt/runtime/tools.h"
+#include "flang/Runtime/extensions.h"
#include <cerrno>
#include <cstdlib>
#include <limits>
@@ -310,7 +310,7 @@ std::int32_t RTNAME(Hostnm)(
return status;
}
-float RTNAME(Secnds)(float* refTime, const char *sourceFile, int line) {
+float RTNAME(Secnds)(float *refTime, const char *sourceFile, int line) {
Terminator terminator{sourceFile, line};
RUNTIME_CHECK(terminator, refTime != nullptr);
return FORTRAN_PROCEDURE_NAME(secnds)(refTime);
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index 4751fb24af849..a5642b628cbfe 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -304,7 +304,7 @@ void FORTRAN_PROCEDURE_NAME(qsort)(int *array, int *len, int *isize,
void RTNAME(Perror)(const char *str) { perror(str); }
// GNU extension function SECNDS(refTime)
-float FORTRAN_PROCEDURE_NAME(secnds)(float* refTime) {
+float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) {
constexpr float FAIL_SECNDS{1.0f};
if (!refTime) {
return FAIL_SECNDS;
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 21ca1fa8457ee..d22c2bc3956fe 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -67,7 +67,7 @@ std::int32_t RTNAME(Hostnm)(
std::int32_t RTNAME(PutEnv)(
const char *str, size_t str_length, const char *sourceFile, int line);
-float RTNAME(Secnds)(float* refTime, const char *sourceFile, int line);
+float RTNAME(Secnds)(float *refTime, const char *sourceFile, int line);
// Calls unlink()
std::int32_t RTNAME(Unlink)(
diff --git a/flang/include/flang/Runtime/extensions.h b/flang/include/flang/Runtime/extensions.h
index a5bfa8b535286..355808a846f13 100644
--- a/flang/include/flang/Runtime/extensions.h
+++ b/flang/include/flang/Runtime/extensions.h
@@ -91,7 +91,7 @@ void RTNAME(Perror)(const char *str);
int FORTRAN_PROCEDURE_NAME(mclock)();
// GNU extension subroutine SECNDS(refTime)
-float FORTRAN_PROCEDURE_NAME(secnds)(float* refTime);
+float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime);
} // extern "C"
#endif // FORTRAN_RUNTIME_EXTENSIONS_H_
>From 8bbe4ebb083f8a707e75318456ad520fdff3213f Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 Aug 2025 16:05:06 -0400
Subject: [PATCH 3/5] Fixed a typo
---
flang-rt/lib/runtime/extensions.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index a5642b628cbfe..a218456e0cbb4 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -314,7 +314,7 @@ float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) {
return FAIL_SECNDS;
}
// In float result, we can only precisely store 2^24 seconds, which
- // comes out to about 194 days. Thus, need to peek a starting point.
+ // comes out to about 194 days. Thus, need to pick a starting point.
// Given the description of this function, midnight of the current
// day is the best starting point.
static time_t startingPoint{0};
>From 5f671e74d65d406d3fd576da7fe29dfbcdb904a8 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 Aug 2025 16:06:22 -0400
Subject: [PATCH 4/5] Fixed init form
---
flang-rt/lib/runtime/extensions.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index a218456e0cbb4..cc3be56019b02 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -338,7 +338,7 @@ float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) {
return FAIL_SECNDS;
}
}
- double diffStartingPoint = std::difftime(now, startingPoint);
+ double diffStartingPoint{std::difftime(now, startingPoint)};
return static_cast<float>(diffStartingPoint) - *refTime;
}
>From 9c538783b3947458405912de0740d4497b548c40 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 4 Aug 2025 16:08:33 -0400
Subject: [PATCH 5/5] The failure code should be negative
---
flang-rt/lib/runtime/extensions.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang-rt/lib/runtime/extensions.cpp b/flang-rt/lib/runtime/extensions.cpp
index cc3be56019b02..01cd13dbf84d5 100644
--- a/flang-rt/lib/runtime/extensions.cpp
+++ b/flang-rt/lib/runtime/extensions.cpp
@@ -305,7 +305,7 @@ void RTNAME(Perror)(const char *str) { perror(str); }
// GNU extension function SECNDS(refTime)
float FORTRAN_PROCEDURE_NAME(secnds)(float *refTime) {
- constexpr float FAIL_SECNDS{1.0f};
+ constexpr float FAIL_SECNDS{-1.0f};
if (!refTime) {
return FAIL_SECNDS;
}
More information about the llvm-commits
mailing list