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,65 @@ +//===-- 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 +#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 +/// mainly erases the array size from the type and ensures the array is sorted +/// at compile time. When C++20 brings std::span and constexpr std::is_sorted, +/// this can most likely be replaced by those. + +namespace Fortran::common { + +template class StaticMultimapView { +public: + using Key = typename V::Key; + using const_iterator = const V *; + + template + static constexpr StaticMultimapView Create() { + static_assert(StaticMultimapView{array}.Verify(), + "array must be sorted in increasing order"); + return StaticMultimapView{array}; + } + constexpr const_iterator begin() const { return begin_; } + constexpr const_iterator end() const { return end_; } + + // std::equal_range will be constexpr in C++20 only, so far there is actually + // no need for equal_range to be constexpr anyway. + std::pair equal_range(const Key &key) const { + return std::equal_range(begin_, end_, key); + } + +private: + template + constexpr StaticMultimapView(const V (&array)[N]) + : begin_{&array[0]}, end_{&array[0] + N} {} + + // Check that the array is sorted. This used to assert at compile time that + // the array is indeed sorted. When C++20 is required for flang, + // std::is_sorted can be used here since it will be constexpr. + constexpr bool Verify() const { + const V *lastSeen{begin_}; + for (const auto *x{begin_}; x != end_; ++x) { + if (x->key < lastSeen->key) { + return false; + } + lastSeen = x; + } + return true; + } + const_iterator begin_{nullptr}; + const_iterator end_{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,36 @@ #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