Michael Kruse 54f37133b7
[Flang][NFC] Move runtime library files to flang-rt (#110298)
Mostly mechanical changes in preparation of extracting the Flang-RT
"subproject" in #110217. This PR intends to only move pre-existing files
to the new folder structure, with no behavioral change. Common files
(headers, testing, cmake) shared by Flang-RT and Flang remain in
`flang/`.

Some cosmetic changes and files paths were necessary:
* Relative paths to the new path for the source files and
`add_subdirectory`.
 * Add the new location's include directory to `include_directories`
* The unittest/Evaluate directory has unitests for flang-rt and Flang. A
new `CMakeLists.txt` was introduced for the flang-rt tests.
 * Change the `#include` paths relative to the include directive
 * clang-format on the `#include` directives
* Since the paths are part if the copyright header and include guards, a
script was used to canonicalize those
* `test/Runtime` and runtime tests in `test/Driver` are moved, but the
lit.cfg.py mechanism to execute the will only be added in #110217.
2025-02-16 13:25:31 +01:00

215 lines
8.5 KiB
C++

//===-- lib/runtime/product.cpp ---------------------------------*- 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
//
//===----------------------------------------------------------------------===//
// Implements PRODUCT for all required operand types and shapes.
#include "flang-rt/runtime/reduction-templates.h"
#include "flang/Common/float128.h"
#include "flang/Runtime/reduction.h"
#include <cfloat>
#include <cinttypes>
#include <complex>
namespace Fortran::runtime {
template <typename INTERMEDIATE> class NonComplexProductAccumulator {
public:
explicit RT_API_ATTRS NonComplexProductAccumulator(const Descriptor &array)
: array_{array} {}
RT_API_ATTRS void Reinitialize() { product_ = 1; }
template <typename A>
RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
*p = static_cast<A>(product_);
}
template <typename A>
RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) {
product_ *= *array_.Element<A>(at);
return product_ != 0;
}
private:
const Descriptor &array_;
INTERMEDIATE product_{1};
};
template <typename PART> class ComplexProductAccumulator {
public:
explicit RT_API_ATTRS ComplexProductAccumulator(const Descriptor &array)
: array_{array} {}
RT_API_ATTRS void Reinitialize() { product_ = rtcmplx::complex<PART>{1, 0}; }
template <typename A>
RT_API_ATTRS void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
using ResultPart = typename A::value_type;
*p = {static_cast<ResultPart>(product_.real()),
static_cast<ResultPart>(product_.imag())};
}
template <typename A>
RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) {
product_ *= *array_.Element<A>(at);
return true;
}
private:
const Descriptor &array_;
rtcmplx::complex<PART> product_{1, 0};
};
extern "C" {
RT_EXT_API_GROUP_BEGIN
CppTypeFor<TypeCategory::Integer, 1> RTDEF(ProductInteger1)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 1>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Integer, 2> RTDEF(ProductInteger2)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 2>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Integer, 4> RTDEF(ProductInteger4)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 4>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Integer, 8> RTDEF(ProductInteger8)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 8>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Integer, 8>>{x},
"PRODUCT");
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Integer, 16> RTDEF(ProductInteger16)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 16>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Integer, 16>>{x},
"PRODUCT");
}
#endif
CppTypeFor<TypeCategory::Unsigned, 1> RTDEF(ProductUnsigned1)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Unsigned, 1>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Unsigned, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Unsigned, 2> RTDEF(ProductUnsigned2)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Unsigned, 2>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Unsigned, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Unsigned, 4> RTDEF(ProductUnsigned4)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Unsigned, 4>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Unsigned, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Unsigned, 8> RTDEF(ProductUnsigned8)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Unsigned, 8>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Unsigned, 8>>{x},
"PRODUCT");
}
#ifdef __SIZEOF_INT128__
CppTypeFor<TypeCategory::Unsigned, 16> RTDEF(ProductUnsigned16)(
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Unsigned, 16>(x, source, line, dim,
mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Unsigned, 16>>{x},
"PRODUCT");
}
#endif
// TODO: real/complex(2 & 3)
CppTypeFor<TypeCategory::Real, 4> RTDEF(ProductReal4)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 4>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 4>>{x},
"PRODUCT");
}
CppTypeFor<TypeCategory::Real, 8> RTDEF(ProductReal8)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 8>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
"PRODUCT");
}
#if HAS_FLOAT80
CppTypeFor<TypeCategory::Real, 10> RTDEF(ProductReal10)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 10>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
"PRODUCT");
}
#endif
#if HAS_LDBL128 || HAS_FLOAT128
CppTypeFor<TypeCategory::Real, 16> RTDEF(ProductReal16)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Real, 16>(x, source, line, dim, mask,
NonComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 16>>{x},
"PRODUCT");
}
#endif
void RTDEF(CppProductComplex4)(CppTypeFor<TypeCategory::Complex, 4> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
result = GetTotalReduction<TypeCategory::Complex, 4>(x, source, line, dim,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 4>>{x},
"PRODUCT");
}
void RTDEF(CppProductComplex8)(CppTypeFor<TypeCategory::Complex, 8> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
result = GetTotalReduction<TypeCategory::Complex, 8>(x, source, line, dim,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 8>>{x},
"PRODUCT");
}
#if HAS_FLOAT80
void RTDEF(CppProductComplex10)(CppTypeFor<TypeCategory::Complex, 10> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
result = GetTotalReduction<TypeCategory::Complex, 10>(x, source, line, dim,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 10>>{x},
"PRODUCT");
}
#endif
#if HAS_LDBL128 || HAS_FLOAT128
void RTDEF(CppProductComplex16)(CppTypeFor<TypeCategory::Complex, 16> &result,
const Descriptor &x, const char *source, int line, int dim,
const Descriptor *mask) {
result = GetTotalReduction<TypeCategory::Complex, 16>(x, source, line, dim,
mask, ComplexProductAccumulator<CppTypeFor<TypeCategory::Real, 16>>{x},
"PRODUCT");
}
#endif
void RTDEF(ProductDim)(Descriptor &result, const Descriptor &x, int dim,
const char *source, int line, const Descriptor *mask) {
TypedPartialNumericReduction<NonComplexProductAccumulator,
NonComplexProductAccumulator, ComplexProductAccumulator,
/*MIN_REAL_KIND=*/4>(result, x, dim, source, line, mask, "PRODUCT");
}
RT_EXT_API_GROUP_END
} // extern "C"
} // namespace Fortran::runtime