diff --git a/flang/include/flang/Common/static-multimap-view.h b/flang/include/flang/Common/static-multimap-view.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Common/static-multimap-view.h @@ -0,0 +1,85 @@ +//===-- include/flang/Common/static-multimap-view.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_COMMON_STATIC_MULTIMAP_VIEW_H_ +#define FORTRAN_COMMON_STATIC_MULTIMAP_VIEW_H_ +#include + +/// StaticMultimapView is a constexpr friendly multimap +/// implementation over sorted constexpr arrays. +/// As the View name suggests, it does not duplicate the +/// sorted array but only brings range and search concepts +/// over it. It provides compile time search and can also +/// provide dynamic search (currently linear, can be improved to +/// log(n) due to the sorted array property). + +namespace Fortran::common { + +template class StaticMultimapView { +public: + using Key = typename V::Key; + struct Range { + using const_iterator = const V *; + constexpr const_iterator begin() const { return startPtr; } + constexpr const_iterator end() const { return endPtr; } + constexpr bool empty() const { + return startPtr == nullptr || endPtr == nullptr || endPtr <= startPtr; + } + constexpr std::size_t size() const { + return empty() ? 0 : static_cast(endPtr - startPtr); + } + const V *startPtr{nullptr}; + const V *endPtr{nullptr}; + }; + using const_iterator = typename Range::const_iterator; + + template + constexpr StaticMultimapView(const V (&array)[N]) + : range_{&array[0], &array[0] + N} {} + constexpr const_iterator begin() const { return range_.begin(); } + constexpr const_iterator end() const { return range_.end(); } + + // Assume array is sorted. + // TODO make it a log(n) search based on sorted property + // std::equal_range will be constexpr in C++20 only. + constexpr Range getRange(const Key &key) const { + bool matched{false}; + const V *start{nullptr}, *end{nullptr}; + for (const auto &desc : range_) { + if (desc.key == key) { + if (!matched) { + start = &desc; + matched = true; + } + } else if (matched) { + end = &desc; + matched = false; + } + } + if (matched) { + end = range_.end(); + } + return Range{start, end}; + } + + constexpr std::pair equal_range( + const Key &key) const { + Range range{getRange(key)}; + return {range.begin(), range.end()}; + } + + constexpr typename Range::const_iterator find(Key key) const { + const Range subRange{getRange(key)}; + return subRange.size() == 1 ? subRange.begin() : end(); + } + +private: + Range range_{nullptr, nullptr}; +}; +} // namespace Fortran::common +#endif // FORTRAN_COMMON_STATIC_MULTIMAP_VIEW_H_ diff --git a/flang/include/flang/Evaluate/common.h b/flang/include/flang/Evaluate/common.h --- a/flang/include/flang/Evaluate/common.h +++ b/flang/include/flang/Evaluate/common.h @@ -9,7 +9,6 @@ #ifndef FORTRAN_EVALUATE_COMMON_H_ #define FORTRAN_EVALUATE_COMMON_H_ -#include "intrinsics-library.h" #include "flang/Common/Fortran.h" #include "flang/Common/default-kinds.h" #include "flang/Common/enum-set.h" @@ -237,9 +236,6 @@ bool flushSubnormalsToZero() const { return flushSubnormalsToZero_; } bool bigEndian() const { return bigEndian_; } const semantics::DerivedTypeSpec *pdtInstance() const { return pdtInstance_; } - const HostIntrinsicProceduresLibrary &hostIntrinsicsLibrary() const { - return hostIntrinsicsLibrary_; - } const evaluate::IntrinsicProcTable &intrinsics() const { return intrinsics_; } ConstantSubscript &StartImpliedDo(parser::CharBlock, ConstantSubscript = 1); @@ -264,7 +260,6 @@ bool bigEndian_{false}; const semantics::DerivedTypeSpec *pdtInstance_{nullptr}; std::map impliedDos_; - HostIntrinsicProceduresLibrary hostIntrinsicsLibrary_; }; void RealFlagWarnings(FoldingContext &, const RealFlags &, const char *op); diff --git a/flang/include/flang/Evaluate/intrinsics-library.h b/flang/include/flang/Evaluate/intrinsics-library.h --- a/flang/include/flang/Evaluate/intrinsics-library.h +++ b/flang/include/flang/Evaluate/intrinsics-library.h @@ -10,99 +10,35 @@ #define FORTRAN_EVALUATE_INTRINSICS_LIBRARY_H_ // Defines structures to be used in F18 for folding intrinsic function with host -// runtime libraries. To avoid unnecessary header circular dependencies, the -// actual implementation of the templatized member function are defined in -// intrinsics-library-templates.h The header at hand is meant to be included by -// files that need to define intrinsic runtime data structure but that do not -// use them directly. To actually use the runtime data structures, -// intrinsics-library-templates.h must be included. +// runtime libraries. #include -#include #include #include #include namespace Fortran::evaluate { class FoldingContext; - -using TypeCode = unsigned char; - -template using FuncPointer = TR (*)(TA...); -// This specific type signature prevents GCC complaining about function casts. -using GenericFunctionPointer = void (*)(void); - -enum class PassBy { Ref, Val }; -template struct ArgumentInfo { - using Type = TA; - static constexpr PassBy pass{Pass}; -}; - -template struct Signature { - // Note valid template argument are of form - //...> where TA and TR belong to RuntimeTypes. - // RuntimeTypes is a type union defined in intrinsics-library-templates.h to - // avoid circular dependencies. Argument of type void cannot be passed by - // value. So far TR cannot be a pointer. - const std::string name; -}; - -struct IntrinsicProcedureRuntimeDescription { - const std::string name; - const TypeCode returnType; - const std::vector argumentsType; - const std::vector argumentsPassedBy; - const bool isElemental; - const GenericFunctionPointer callable; - // Construct from description using host independent types (RuntimeTypes) - template - IntrinsicProcedureRuntimeDescription( - const Signature &signature, bool isElemental = false); -}; - -// HostRuntimeIntrinsicProcedure allows host runtime function to be called for -// constant folding. -struct HostRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription { - // Construct from runtime pointer with host types (float, double....) - template - HostRuntimeIntrinsicProcedure(const std::string &name, - FuncPointer func, bool isElemental = false); - HostRuntimeIntrinsicProcedure( - const IntrinsicProcedureRuntimeDescription &rteProc, - GenericFunctionPointer handle) - : IntrinsicProcedureRuntimeDescription{rteProc}, handle{handle} {} - GenericFunctionPointer handle; -}; - -// Defines a wrapper type that indirects calls to host runtime functions. -// Valid ConstantContainer are Scalar (only for elementals) and Constant. -template