aboutsummaryrefslogtreecommitdiff
path: root/flang/runtime
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2024-03-13 13:13:52 -0700
committerFangrui Song <i@maskray.me>2024-03-13 13:13:52 -0700
commit9ce8691dea8dadc1302abacf4302f3b805e1448d (patch)
treefdc2da3081156b4c9b80b0d417f090efadac946c /flang/runtime
parent795e3c3d94da0a664642d4580d87c82c02d5eca4 (diff)
parent744a23f24b08e8b988b176173c433d64761e66b3 (diff)
downloadllvm-users/MaskRay/spr/main.llvm-objcopy-add-compress-sections.zip
llvm-users/MaskRay/spr/main.llvm-objcopy-add-compress-sections.tar.gz
llvm-users/MaskRay/spr/main.llvm-objcopy-add-compress-sections.tar.bz2
[𝘀𝗽𝗿] changes introduced through rebaseusers/MaskRay/spr/main.llvm-objcopy-add-compress-sections
Created using spr 1.3.5-bogner [skip ci]
Diffstat (limited to 'flang/runtime')
-rw-r--r--flang/runtime/Float128Math/CMakeLists.txt2
-rw-r--r--flang/runtime/Float128Math/fma.cpp23
-rw-r--r--flang/runtime/Float128Math/math-entries.h3
-rw-r--r--flang/runtime/Float128Math/random.cpp23
-rw-r--r--flang/runtime/random-templates.h87
-rw-r--r--flang/runtime/random.cpp81
6 files changed, 144 insertions, 75 deletions
diff --git a/flang/runtime/Float128Math/CMakeLists.txt b/flang/runtime/Float128Math/CMakeLists.txt
index 9803561..a5f5bec 100644
--- a/flang/runtime/Float128Math/CMakeLists.txt
+++ b/flang/runtime/Float128Math/CMakeLists.txt
@@ -33,6 +33,7 @@ set(sources
exp.cpp
exponent.cpp
floor.cpp
+ fma.cpp
fraction.cpp
hypot.cpp
j0.cpp
@@ -48,6 +49,7 @@ set(sources
nearest.cpp
norm2.cpp
pow.cpp
+ random.cpp
round.cpp
rrspacing.cpp
scale.cpp
diff --git a/flang/runtime/Float128Math/fma.cpp b/flang/runtime/Float128Math/fma.cpp
new file mode 100644
index 0000000..ec67e8e
--- /dev/null
+++ b/flang/runtime/Float128Math/fma.cpp
@@ -0,0 +1,23 @@
+//===-- runtime/Float128Math/fma.cpp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "math-entries.h"
+
+namespace Fortran::runtime {
+extern "C" {
+
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+CppTypeFor<TypeCategory::Real, 16> RTDEF(FmaF128)(
+ CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> y,
+ CppTypeFor<TypeCategory::Real, 16> z) {
+ return Fma<true>::invoke(x, y, z);
+}
+#endif
+
+} // extern "C"
+} // namespace Fortran::runtime
diff --git a/flang/runtime/Float128Math/math-entries.h b/flang/runtime/Float128Math/math-entries.h
index 1eab7c8..13fdab2 100644
--- a/flang/runtime/Float128Math/math-entries.h
+++ b/flang/runtime/Float128Math/math-entries.h
@@ -77,6 +77,7 @@ DEFINE_FALLBACK_F128(Erf)
DEFINE_FALLBACK_F128(Erfc)
DEFINE_FALLBACK_F128(Exp)
DEFINE_FALLBACK_F128(Floor)
+DEFINE_FALLBACK_F128(Fma)
DEFINE_FALLBACK_F128(Frexp)
DEFINE_FALLBACK_F128(Hypot)
DEFINE_FALLBACK_I32(Ilogb)
@@ -124,6 +125,7 @@ DEFINE_SIMPLE_ALIAS(Erf, erfq)
DEFINE_SIMPLE_ALIAS(Erfc, erfcq)
DEFINE_SIMPLE_ALIAS(Exp, expq)
DEFINE_SIMPLE_ALIAS(Floor, floorq)
+DEFINE_SIMPLE_ALIAS(Fma, fmaq)
DEFINE_SIMPLE_ALIAS(Frexp, frexpq)
DEFINE_SIMPLE_ALIAS(Hypot, hypotq)
DEFINE_SIMPLE_ALIAS(Ilogb, ilogbq)
@@ -177,6 +179,7 @@ DEFINE_SIMPLE_ALIAS(Erf, std::erf)
DEFINE_SIMPLE_ALIAS(Erfc, std::erfc)
DEFINE_SIMPLE_ALIAS(Exp, std::exp)
DEFINE_SIMPLE_ALIAS(Floor, std::floor)
+DEFINE_SIMPLE_ALIAS(Fma, std::fma)
DEFINE_SIMPLE_ALIAS(Frexp, std::frexp)
DEFINE_SIMPLE_ALIAS(Hypot, std::hypot)
DEFINE_SIMPLE_ALIAS(Ilogb, std::ilogb)
diff --git a/flang/runtime/Float128Math/random.cpp b/flang/runtime/Float128Math/random.cpp
new file mode 100644
index 0000000..cda962b
--- /dev/null
+++ b/flang/runtime/Float128Math/random.cpp
@@ -0,0 +1,23 @@
+//===-- runtime/Float128Math/random.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "math-entries.h"
+#include "numeric-template-specs.h"
+#include "random-templates.h"
+
+using namespace Fortran::runtime::random;
+extern "C" {
+
+#if LDBL_MANT_DIG == 113 || HAS_FLOAT128
+void RTDEF(RandomNumber16)(
+ const Descriptor &harvest, const char *source, int line) {
+ return Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
+}
+#endif
+
+} // extern "C"
diff --git a/flang/runtime/random-templates.h b/flang/runtime/random-templates.h
new file mode 100644
index 0000000..ce64a94
--- /dev/null
+++ b/flang/runtime/random-templates.h
@@ -0,0 +1,87 @@
+//===-- runtime/random-templates.h ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_RUNTIME_RANDOM_TEMPLATES_H_
+#define FORTRAN_RUNTIME_RANDOM_TEMPLATES_H_
+
+#include "lock.h"
+#include "numeric-templates.h"
+#include "flang/Runtime/descriptor.h"
+#include <algorithm>
+#include <random>
+
+namespace Fortran::runtime::random {
+
+// Newer "Minimum standard", recommended by Park, Miller, and Stockmeyer in
+// 1993. Same as C++17 std::minstd_rand, but explicitly instantiated for
+// permanence.
+using Generator =
+ std::linear_congruential_engine<std::uint_fast32_t, 48271, 0, 2147483647>;
+
+using GeneratedWord = typename Generator::result_type;
+static constexpr std::uint64_t range{
+ static_cast<std::uint64_t>(Generator::max() - Generator::min() + 1)};
+static constexpr bool rangeIsPowerOfTwo{(range & (range - 1)) == 0};
+static constexpr int rangeBits{
+ 64 - common::LeadingZeroBitCount(range) - !rangeIsPowerOfTwo};
+
+extern Lock lock;
+extern Generator generator;
+extern std::optional<GeneratedWord> nextValue;
+
+// Call only with lock held
+static GeneratedWord GetNextValue() {
+ GeneratedWord result;
+ if (nextValue.has_value()) {
+ result = *nextValue;
+ nextValue.reset();
+ } else {
+ result = generator();
+ }
+ return result;
+}
+
+template <typename REAL, int PREC>
+inline void Generate(const Descriptor &harvest) {
+ static constexpr std::size_t minBits{
+ std::max<std::size_t>(PREC, 8 * sizeof(GeneratedWord))};
+ using Int = common::HostUnsignedIntType<minBits>;
+ static constexpr std::size_t words{
+ static_cast<std::size_t>(PREC + rangeBits - 1) / rangeBits};
+ std::size_t elements{harvest.Elements()};
+ SubscriptValue at[maxRank];
+ harvest.GetLowerBounds(at);
+ {
+ CriticalSection critical{lock};
+ for (std::size_t j{0}; j < elements; ++j) {
+ while (true) {
+ Int fraction{GetNextValue()};
+ if constexpr (words > 1) {
+ for (std::size_t k{1}; k < words; ++k) {
+ static constexpr auto rangeMask{
+ (GeneratedWord{1} << rangeBits) - 1};
+ GeneratedWord word{(GetNextValue() - generator.min()) & rangeMask};
+ fraction = (fraction << rangeBits) | word;
+ }
+ }
+ fraction >>= words * rangeBits - PREC;
+ REAL next{
+ LDEXPTy<REAL>::compute(static_cast<REAL>(fraction), -(PREC + 1))};
+ if (next >= 0.0 && next < 1.0) {
+ *harvest.Element<REAL>(at) = next;
+ break;
+ }
+ }
+ harvest.IncrementSubscripts(at);
+ }
+ }
+}
+
+} // namespace Fortran::runtime::random
+
+#endif // FORTRAN_RUNTIME_RANDOM_TEMPLATES_H_
diff --git a/flang/runtime/random.cpp b/flang/runtime/random.cpp
index 642091a0..13bed1f 100644
--- a/flang/runtime/random.cpp
+++ b/flang/runtime/random.cpp
@@ -11,85 +11,24 @@
#include "flang/Runtime/random.h"
#include "lock.h"
+#include "random-templates.h"
#include "terminator.h"
#include "flang/Common/float128.h"
#include "flang/Common/leading-zero-bit-count.h"
#include "flang/Common/uint128.h"
#include "flang/Runtime/cpp-type.h"
#include "flang/Runtime/descriptor.h"
-#include <algorithm>
#include <cmath>
#include <cstdint>
#include <limits>
#include <memory>
-#include <random>
#include <time.h>
-namespace Fortran::runtime {
+namespace Fortran::runtime::random {
-// Newer "Minimum standard", recommended by Park, Miller, and Stockmeyer in
-// 1993. Same as C++17 std::minstd_rand, but explicitly instantiated for
-// permanence.
-using Generator =
- std::linear_congruential_engine<std::uint_fast32_t, 48271, 0, 2147483647>;
-
-using GeneratedWord = typename Generator::result_type;
-static constexpr std::uint64_t range{
- static_cast<std::uint64_t>(Generator::max() - Generator::min() + 1)};
-static constexpr bool rangeIsPowerOfTwo{(range & (range - 1)) == 0};
-static constexpr int rangeBits{
- 64 - common::LeadingZeroBitCount(range) - !rangeIsPowerOfTwo};
-
-static Lock lock;
-static Generator generator;
-static std::optional<GeneratedWord> nextValue;
-
-// Call only with lock held
-static GeneratedWord GetNextValue() {
- GeneratedWord result;
- if (nextValue.has_value()) {
- result = *nextValue;
- nextValue.reset();
- } else {
- result = generator();
- }
- return result;
-}
-
-template <typename REAL, int PREC>
-inline void Generate(const Descriptor &harvest) {
- static constexpr std::size_t minBits{
- std::max<std::size_t>(PREC, 8 * sizeof(GeneratedWord))};
- using Int = common::HostUnsignedIntType<minBits>;
- static constexpr std::size_t words{
- static_cast<std::size_t>(PREC + rangeBits - 1) / rangeBits};
- std::size_t elements{harvest.Elements()};
- SubscriptValue at[maxRank];
- harvest.GetLowerBounds(at);
- {
- CriticalSection critical{lock};
- for (std::size_t j{0}; j < elements; ++j) {
- while (true) {
- Int fraction{GetNextValue()};
- if constexpr (words > 1) {
- for (std::size_t k{1}; k < words; ++k) {
- static constexpr auto rangeMask{
- (GeneratedWord{1} << rangeBits) - 1};
- GeneratedWord word{(GetNextValue() - generator.min()) & rangeMask};
- fraction = (fraction << rangeBits) | word;
- }
- }
- fraction >>= words * rangeBits - PREC;
- REAL next{std::ldexp(static_cast<REAL>(fraction), -(PREC + 1))};
- if (next >= 0.0 && next < 1.0) {
- *harvest.Element<REAL>(at) = next;
- break;
- }
- }
- harvest.IncrementSubscripts(at);
- }
- }
-}
+Lock lock;
+Generator generator;
+std::optional<GeneratedWord> nextValue;
extern "C" {
@@ -133,14 +72,6 @@ void RTNAME(RandomNumber)(
#endif
}
break;
- case 16:
- if constexpr (HasCppTypeFor<TypeCategory::Real, 16>) {
-#if LDBL_MANT_DIG == 113
- Generate<CppTypeFor<TypeCategory::Real, 16>, 113>(harvest);
- return;
-#endif
- }
- break;
}
terminator.Crash(
"not yet implemented: intrinsic: REAL(KIND=%d) in RANDOM_NUMBER", kind);
@@ -263,4 +194,4 @@ void RTNAME(RandomSeed)(const Descriptor *size, const Descriptor *put,
}
} // extern "C"
-} // namespace Fortran::runtime
+} // namespace Fortran::runtime::random