[flang] renaming to focus scope on intrinsic runtime
authorJean Perier <jperier@nvidia.com>
Fri, 1 Mar 2019 17:20:12 +0000 (09:20 -0800)
committerGitHub <noreply@github.com>
Wed, 27 Mar 2019 17:16:07 +0000 (10:16 -0700)
Original-commit: flang-compiler/f18@7cfd33b178d3ea3502ea87cb9416720f6cce4ba9
Tree-same-pre-rewrite: false

flang/lib/evaluate/CMakeLists.txt
flang/lib/evaluate/common.h
flang/lib/evaluate/fold.cc
flang/lib/evaluate/intrinsics-library-templates.h [moved from flang/lib/evaluate/rte.h with 81% similarity]
flang/lib/evaluate/intrinsics-library.cc [moved from flang/lib/evaluate/rte.cc with 84% similarity]
flang/lib/evaluate/intrinsics-library.h [new file with mode: 0644]
flang/lib/evaluate/rte-interface.h [deleted file]

index c173f3a..0bded45 100644 (file)
@@ -29,7 +29,7 @@ add_library(FortranEvaluate
   tools.cc
   type.cc
   variable.cc
-  rte.cc
+  intrinsics-library.cc
 )
 
 target_link_libraries(FortranEvaluate
index 8dbf09d..d91da13 100644 (file)
@@ -15,6 +15,7 @@
 #ifndef FORTRAN_EVALUATE_COMMON_H_
 #define FORTRAN_EVALUATE_COMMON_H_
 
+#include "intrinsics-library.h"
 #include "../common/Fortran.h"
 #include "../common/enum-set.h"
 #include "../common/idioms.h"
@@ -22,7 +23,6 @@
 #include "../common/restorer.h"
 #include "../parser/char-block.h"
 #include "../parser/message.h"
-#include "rte-interface.h"
 #include <cinttypes>
 #include <map>
 
@@ -219,7 +219,9 @@ public:
   bool flushSubnormalsToZero() const { return flushSubnormalsToZero_; }
   bool bigEndian() const { return bigEndian_; }
   const semantics::DerivedTypeSpec *pdtInstance() const { return pdtInstance_; }
-  rte::HostRte &hostRte() { return hostRte_; }
+  HostIntrinsicProceduresLibrary &hostIntrinsicsLibrary() {
+    return hostIntrinsicsLibrary_;
+  }
 
   std::int64_t &StartImpliedDo(parser::CharBlock, std::int64_t = 1);
   std::optional<std::int64_t> GetImpliedDo(parser::CharBlock) const;
@@ -241,7 +243,7 @@ private:
   bool bigEndian_{false};
   const semantics::DerivedTypeSpec *pdtInstance_{nullptr};
   std::map<parser::CharBlock, std::int64_t> impliedDos_;
-  rte::HostRte hostRte_;
+  HostIntrinsicProceduresLibrary hostIntrinsicsLibrary_;
 };
 
 void RealFlagWarnings(FoldingContext &, const RealFlags &, const char *op);
index 17ef66a..742740c 100644 (file)
@@ -18,7 +18,7 @@
 #include "expression.h"
 #include "host.h"
 #include "int-power.h"
-#include "rte.h"
+#include "intrinsics-library-templates.h"
 #include "tools.h"
 #include "traversal.h"
 #include "type.h"
@@ -331,8 +331,8 @@ Expr<Type<TypeCategory::Real, KIND>> FoldOperation(FoldingContext &context,
     const std::string name{intrinsic->name};
     if (name == "acos" || name == "acosh" ||
         (name == "atan" && funcRef.arguments().size() == 1)) {
-      if (auto callable{
-              context.hostRte().GetHostProcedureWrapper<Scalar, T, T>(name)}) {
+      if (auto callable{context.hostIntrinsicsLibrary()
+                            .GetHostProcedureWrapper<Scalar, T, T>(name)}) {
         return FoldElementalIntrinsic<T, T>(
             context, std::move(funcRef), *callable);
       } else {
@@ -342,9 +342,8 @@ Expr<Type<TypeCategory::Real, KIND>> FoldOperation(FoldingContext &context,
       }
     }
     if (name == "atan") {
-      if (auto callable{
-              context.hostRte().GetHostProcedureWrapper<Scalar, T, T, T>(
-                  name)}) {
+      if (auto callable{context.hostIntrinsicsLibrary()
+                            .GetHostProcedureWrapper<Scalar, T, T, T>(name)}) {
         return FoldElementalIntrinsic<T, T, T>(
             context, std::move(funcRef), *callable);
       } else {
@@ -361,8 +360,8 @@ Expr<Type<TypeCategory::Real, KIND>> FoldOperation(FoldingContext &context,
               Fold(context, ConvertToType<Int8>(std::move(*n)));
         }
         if (auto callable{
-                context.hostRte().GetHostProcedureWrapper<Scalar, T, Int8, T>(
-                    name)}) {
+                context.hostIntrinsicsLibrary()
+                    .GetHostProcedureWrapper<Scalar, T, Int8, T>(name)}) {
           return FoldElementalIntrinsic<T, Int8, T>(
               context, std::move(funcRef), *callable);
         } else {
@@ -423,8 +422,8 @@ Expr<Type<TypeCategory::Complex, KIND>> FoldOperation(FoldingContext &context,
     const std::string name{intrinsic->name};
     if (name == "acos" || name == "acosh" || name == "asin" || name == "atan" ||
         name == "atanh") {
-      if (auto callable{
-              context.hostRte().GetHostProcedureWrapper<Scalar, T, T>(name)}) {
+      if (auto callable{context.hostIntrinsicsLibrary()
+                            .GetHostProcedureWrapper<Scalar, T, T>(name)}) {
         return FoldElementalIntrinsic<T, T>(
             context, std::move(funcRef), *callable);
       } else {
similarity index 81%
rename from flang/lib/evaluate/rte.h
rename to flang/lib/evaluate/intrinsics-library-templates.h
index f50c76a..74d3a31 100644 (file)
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef FORTRAN_EVALUATE_RTE_H_
-#define FORTRAN_EVALUATE_RTE_H_
+#ifndef FORTRAN_EVALUATE_INTRINSICS_LIBRARY_TEMPLATES_H_
+#define FORTRAN_EVALUATE_INTRINSICS_LIBRARY_TEMPLATES_H_
 
 // This header defines the actual implementation of the templatized member
-// function of the structures defined in rte-interface.h. It should only be
-// included if these member functions are used, else rte-interface.h is
+// function of the structures defined in intrinsics-library.h. It should only be
+// included if these member functions are used, else intrinsics-library.h is
 // sufficient. This is to avoid circular dependencies. The below implementation
 // cannot be defined in .cc file because it would be too cumbersome to decide
 // which version should be instantiated in a generic way.
 
 #include "host.h"
-#include "rte-interface.h"
+#include "intrinsics-library.h"
 #include "type.h"
 #include "../common/template.h"
 
 #include <tuple>
 #include <type_traits>
 
-namespace Fortran::evaluate::rte {
+namespace Fortran::evaluate {
 
 // Define meaningful types for the runtime
 // TODO: add the support for void and descriptor
-using RteTypes = evaluate::AllIntrinsicTypes;
+using RuntimeTypes = evaluate::AllIntrinsicTypes;
 
 template<typename T, typename... TT> struct IndexInTupleHelper {};
 template<typename T, typename... TT>
@@ -44,12 +44,14 @@ struct IndexInTupleHelper<T, std::tuple<TT...>> {
 };
 
 static_assert(
-    std::tuple_size_v<RteTypes> < std::numeric_limits<TypeCode>::max(),
+    std::tuple_size_v<RuntimeTypes> < std::numeric_limits<TypeCode>::max(),
     "TypeCode is too small");
 template<typename T>
-inline constexpr TypeCode typeCodeOf{IndexInTupleHelper<T, RteTypes>::value};
+inline constexpr TypeCode typeCodeOf{
+    IndexInTupleHelper<T, RuntimeTypes>::value};
 
-template<TypeCode n> using TypeOf = typename std::tuple_element_t<n, RteTypes>;
+template<TypeCode n>
+using RuntimeTypeOf = typename std::tuple_element_t<n, RuntimeTypes>;
 
 template<typename TA, PassBy Pass>
 using HostArgType = std::conditional_t<Pass == PassBy::Ref,
@@ -84,7 +86,7 @@ template<typename TR, typename... ArgInfo> struct CallableHostWrapper {
       hostFPE.CheckAndRestoreFloatingPointEnvironment(context);
       return host::CastHostToFortran<TR>(res);
     } else {
-      common::die("Internal error: Host does not supports rte functions types. "
+      common::die("Internal error: Host does not supports this function types."
                   "This should not have been called for folding");
       return Scalar<TR>{};  // unreachable
     }
@@ -93,7 +95,7 @@ template<typename TR, typename... ArgInfo> struct CallableHostWrapper {
 };
 
 template<typename TR, typename... ArgInfo>
-RteProcedureSymbol::RteProcedureSymbol(
+IntrinsicProcedureRuntimeDescription::IntrinsicProcedureRuntimeDescription(
     const Signature<TR, ArgInfo...> &signature, bool isElemental)
   : name{signature.name}, returnType{typeCodeOf<TR>},
     argumentsType{typeCodeOf<typename ArgInfo::Type>...},
@@ -119,16 +121,18 @@ using SignatureFromHostFuncPointer =
     Signature<host::FortranType<HostTR>, ArgInfoFromHostType<HostTA>...>;
 
 template<typename HostTR, typename... HostTA>
-HostRteProcedureSymbol::HostRteProcedureSymbol(const std::string &name,
-    FuncPointer<HostTR, HostTA...> func, bool isElemental)
-  : RteProcedureSymbol(
+HostRuntimeIntrinsicProcedure::HostRuntimeIntrinsicProcedure(
+    const std::string &name, FuncPointer<HostTR, HostTA...> func,
+    bool isElemental)
+  : IntrinsicProcedureRuntimeDescription(
         SignatureFromHostFuncPointer<HostTR, HostTA...>{name}, isElemental),
     handle{reinterpret_cast<FuncPointer<void *>>(func)} {}
 
 template<template<typename> typename ConstantContainer, typename TR,
     typename... TA>
 std::optional<HostProcedureWrapper<ConstantContainer, TR, TA...>>
-HostRte::GetHostProcedureWrapper(const std::string &name) {
+HostIntrinsicProceduresLibrary::GetHostProcedureWrapper(
+    const std::string &name) {
   if constexpr (host::HostTypeExists<TR, TA...>()) {
     auto rteProcRange{procedures.equal_range(name)};
     const TypeCode resTypeCode{typeCodeOf<TR>};
@@ -165,10 +169,11 @@ HostRte::GetHostProcedureWrapper(const std::string &name) {
 }
 
 template<typename TR, typename... ArgInfo>
-TargetRteProcedureSymbol::TargetRteProcedureSymbol(
+TargetRuntimeIntrinsicProcedure::TargetRuntimeIntrinsicProcedure(
     const Signature<TR, ArgInfo...> &signature, const std::string &symbolName,
     bool isElemental)
-  : RteProcedureSymbol{signature, isElemental}, symbol{symbolName} {}
+  : IntrinsicProcedureRuntimeDescription{signature, isElemental},
+    symbol{symbolName} {}
 
 }
-#endif  // FORTRAN_EVALUATE_RTE_H_
+#endif  // FORTRAN_EVALUATE_INTRINSICS_LIBRARY_TEMPLATES_H_
similarity index 84%
rename from flang/lib/evaluate/rte.cc
rename to flang/lib/evaluate/intrinsics-library.cc
index fcf96af..261f1fa 100644 (file)
 
 // This file defines the runtime libraries for the target as well as a default
 // set of host rte functions that can be used for folding.
-// The default HostRte is built with <cmath> and <complex> functions
-// that are guaranteed to exist from the C++ standard.
+// The default HostIntrinsicProceduresLibrary is built with <cmath> and
+// <complex> functions that are guaranteed to exist from the C++ standard.
 
-#include "rte.h"
+#include "intrinsics-library-templates.h"
 #include "../common/idioms.h"
 #include <cerrno>
 #include <cfenv>
 #include <dlfcn.h>
 #endif
 
-namespace Fortran::evaluate::rte {
+namespace Fortran::evaluate {
 
 using namespace Fortran::parser::literals;
 // Note: argument passing is ignored in equivalence
-bool HostRte::HasEquivalentProcedure(const RteProcedureSymbol &sym) const {
+bool HostIntrinsicProceduresLibrary::HasEquivalentProcedure(
+    const IntrinsicProcedureRuntimeDescription &sym) const {
   const auto rteProcRange{procedures.equal_range(sym.name)};
   const size_t nargs{sym.argumentsType.size()};
   for (auto iter{rteProcRange.first}; iter != rteProcRange.second; ++iter) {
@@ -54,7 +55,8 @@ bool HostRte::HasEquivalentProcedure(const RteProcedureSymbol &sym) const {
   return false;
 }
 
-void HostRte::LoadTargetRteLibrary(const TargetRteLibrary &lib) {
+void HostIntrinsicProceduresLibrary::LoadTargetIntrinsicProceduresLibrary(
+    const TargetIntrinsicProceduresLibrary &lib) {
   if (dynamicallyLoadedLibraries.find(lib.name) !=
       dynamicallyLoadedLibraries.end()) {
     return;  // already loaded
@@ -75,7 +77,7 @@ void HostRte::LoadTargetRteLibrary(const TargetRteLibrary &lib) {
       // is implementation defined whether this is supported. POSIX mandates
       // that such cast from function pointers to void* are defined. Hence this
       // reinterpret_cast is and MUST REMAIN inside ifdef related to POSIX.
-      AddProcedure(HostRteProcedureSymbol{
+      AddProcedure(HostRuntimeIntrinsicProcedure{
           sym.second, reinterpret_cast<FuncPointer<void *>>(func)});
     }
   }
@@ -84,7 +86,7 @@ void HostRte::LoadTargetRteLibrary(const TargetRteLibrary &lib) {
 #endif
 }
 
-HostRte::~HostRte() {
+HostIntrinsicProceduresLibrary::~HostIntrinsicProceduresLibrary() {
   for (auto iter{dynamicallyLoadedLibraries.begin()};
        iter != dynamicallyLoadedLibraries.end(); ++iter) {
 #ifdef IS_POSIX_COMPLIANT
@@ -105,10 +107,12 @@ template<typename HostT> static HostT Bessel_yn(std::int64_t n, HostT x) {
   return std::cyl_neumann(static_cast<HostT>(n), x);
 }
 
-template<typename HostT> void AddLibmRealHostProcedure(HostRte &hostRte) {
+template<typename HostT>
+void AddLibmRealHostProcedure(
+    HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
   using F = FuncPointer<HostT, HostT>;
   using F2 = FuncPointer<HostT, HostT, HostT>;
-  HostRteProcedureSymbol libmSymbols[]{{"acos", F{std::acos}, true},
+  HostRuntimeIntrinsicProcedure libmSymbols[]{{"acos", F{std::acos}, true},
       {"acosh", F{std::acosh}, true}, {"asin", F{std::asin}, true},
       {"asinh", F{std::asinh}, true}, {"atan", F{std::atan}, true},
       {"atan", F2{std::atan2}, true}, {"atanh", F{std::atanh}, true},
@@ -119,15 +123,17 @@ template<typename HostT> void AddLibmRealHostProcedure(HostRte &hostRte) {
       {"tan", F{std::tan}, true}, {"tanh", F{std::tanh}, true}};
 
   for (auto sym : libmSymbols) {
-    if (!hostRte.HasEquivalentProcedure(sym)) {
-      hostRte.AddProcedure(std::move(sym));
+    if (!hostIntrinsicLibrary.HasEquivalentProcedure(sym)) {
+      hostIntrinsicLibrary.AddProcedure(std::move(sym));
     }
   }
 }
 
-template<typename HostT> void AddLibmComplexHostProcedure(HostRte &hostRte) {
+template<typename HostT>
+void AddLibmComplexHostProcedure(
+    HostIntrinsicProceduresLibrary &hostIntrinsicLibrary) {
   using F = FuncPointer<std::complex<HostT>, const std::complex<HostT> &>;
-  HostRteProcedureSymbol libmSymbols[]{{"acos", F{std::acos}, true},
+  HostRuntimeIntrinsicProcedure libmSymbols[]{{"acos", F{std::acos}, true},
       {"acosh", F{std::acosh}, true}, {"asin", F{std::asin}, true},
       {"asinh", F{std::asinh}, true}, {"atan", F{std::atan}, true},
       {"atanh", F{std::atanh}, true}, {"cos", F{std::cos}, true},
@@ -136,8 +142,8 @@ template<typename HostT> void AddLibmComplexHostProcedure(HostRte &hostRte) {
       {"tan", F{std::tan}, true}, {"tanh", F{std::tanh}, true}};
 
   for (auto sym : libmSymbols) {
-    if (!hostRte.HasEquivalentProcedure(sym)) {
-      hostRte.AddProcedure(std::move(sym));
+    if (!hostIntrinsicLibrary.HasEquivalentProcedure(sym)) {
+      hostIntrinsicLibrary.AddProcedure(std::move(sym));
     }
   }
 }
@@ -183,32 +189,34 @@ static std::string MakeLibpgmathName(const std::string &name, MathOption m) {
 }
 
 template<typename T>
-static void AddLibpgmathTargetSymbols(TargetRteLibrary &lib, MathOption opt) {
+static void AddLibpgmathTargetSymbols(
+    TargetIntrinsicProceduresLibrary &lib, MathOption opt) {
   using F = Signature<T, ArgumentInfo<T, PassBy::Val>>;
   const std::string oneArgFuncs[]{"acos", "asin", "atan", "cos", "cosh", "exp",
       "log", "log10", "sin", "sinh", "tan", "tanh"};
   for (const std::string &name : oneArgFuncs) {
-    lib.AddProcedure(TargetRteProcedureSymbol{
+    lib.AddProcedure(TargetRuntimeIntrinsicProcedure{
         F{name}, MakeLibpgmathName<T>(name, opt), true});
   }
 
   if constexpr (T::category == TypeCategory::Real) {
     using F2 = Signature<T, ArgumentInfo<T, PassBy::Val>,
         ArgumentInfo<T, PassBy::Val>>;
-    lib.AddProcedure(TargetRteProcedureSymbol{
+    lib.AddProcedure(TargetRuntimeIntrinsicProcedure{
         F2{"atan2"}, MakeLibpgmathName<T>("acos", opt), true});
   } else {
     const std::string oneArgCmplxFuncs[]{
         "div", "sqrt"};  // for scalar, only complex available
     for (const std::string &name : oneArgCmplxFuncs) {
-      lib.AddProcedure(TargetRteProcedureSymbol{
+      lib.AddProcedure(TargetRuntimeIntrinsicProcedure{
           F{name}, MakeLibpgmathName<T>(name, opt), true});
     }
   }
 }
 
-TargetRteLibrary BuildLibpgmTargetRteLibrary(MathOption opt) {
-  TargetRteLibrary lib{"libpgmath"};
+TargetIntrinsicProceduresLibrary BuildLibpgmTargetIntrinsicProceduresLibrary(
+    MathOption opt) {
+  TargetIntrinsicProceduresLibrary lib{"libpgmath"};
   AddLibpgmathTargetSymbols<Type<TypeCategory::Real, 4>>(lib, opt);
   AddLibpgmathTargetSymbols<Type<TypeCategory::Real, 8>>(lib, opt);
   AddLibpgmathTargetSymbols<Type<TypeCategory::Complex, 4>>(lib, opt);
@@ -218,13 +226,14 @@ TargetRteLibrary BuildLibpgmTargetRteLibrary(MathOption opt) {
 
 // Defines which host runtime functions will be used for folding
 
-void HostRte::DefaultInit() {
+void HostIntrinsicProceduresLibrary::DefaultInit() {
   // TODO: when linkage information is available, this needs to be modified to
   // load runtime accordingly. For now, try loading libpgmath (libpgmath.so
   // needs to be in a directory from LD_LIBRARY_PATH) and then add libm symbols
   // when no equivalent symbols were already loaded
-  TargetRteLibrary libpgmath{BuildLibpgmTargetRteLibrary(MathOption::Precise)};
-  LoadTargetRteLibrary(libpgmath);
+  TargetIntrinsicProceduresLibrary libpgmath{
+      BuildLibpgmTargetIntrinsicProceduresLibrary(MathOption::Precise)};
+  LoadTargetIntrinsicProceduresLibrary(libpgmath);
 
   AddLibmRealHostProcedure<float>(*this);
   AddLibmRealHostProcedure<double>(*this);
diff --git a/flang/lib/evaluate/intrinsics-library.h b/flang/lib/evaluate/intrinsics-library.h
new file mode 100644 (file)
index 0000000..36afb91
--- /dev/null
@@ -0,0 +1,148 @@
+// Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef FORTRAN_EVALUATE_INTRINSICS_LIBRARY_H_
+#define FORTRAN_EVALUATE_INTRINSICS_LIBRARY_H_
+
+// Defines structures to be used in F18 when dealing with the intrinsic
+// procedures runtime. It abstracts both:
+//  - the target intrinsic procedure runtime to be used for code generation
+//  - the host intrinsic runtime to be used for constant folding purposes.
+// 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 Note that
+// intrinsics-library-templates.h includes the header at hand.
+
+#include <functional>
+#include <map>
+#include <optional>
+#include <string>
+#include <vector>
+
+namespace Fortran::evaluate {
+class FoldingContext;
+
+using TypeCode = unsigned char;
+
+template<typename TR, typename... TA> using FuncPointer = TR (*)(TA...);
+
+enum class PassBy { Ref, Val };
+template<typename TA, PassBy Pass = PassBy::Ref> struct ArgumentInfo {
+  using Type = TA;
+  static constexpr PassBy pass{Pass};
+};
+
+template<typename TR, typename... ArgInfo> struct Signature {
+  // Note valid template argument are of form
+  //<TR, ArgumentInfo<TA, PassBy>...> 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<TypeCode> argumentsType;
+  const std::vector<PassBy> argumentsPassedBy;
+  const bool isElemental;
+  const FuncPointer<void *> callable;
+  // callable only usable by HostRuntimeIntrinsicProcedure but need to be
+  // created in case TargetRuntimeIntrinsicProcedure is dynamically loaded
+  // because creating it dynamically would be too complex
+
+  // Construct from description using host independent types (RuntimeTypes)
+  template<typename TR, typename... ArgInfo>
+  IntrinsicProcedureRuntimeDescription(
+      const Signature<TR, ArgInfo...> &signature, bool isElemental = false);
+};
+
+// TargetRuntimeIntrinsicProcedure holds target runtime information
+// for an intrinsics procedure.
+struct TargetRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription {
+  // Construct from description using host independent types (RuntimeTypes)
+  // Note: passing ref/val also needs to be passed by template to build
+  // the callable
+  template<typename TR, typename... ArgInfo>
+  TargetRuntimeIntrinsicProcedure(const Signature<TR, ArgInfo...> &signature,
+      const std::string &symbolName, bool isElemental = false);
+  const std::string symbol;
+};
+
+struct TargetIntrinsicProceduresLibrary {
+  TargetIntrinsicProceduresLibrary(const std::string &name) : name{name} {}
+  void AddProcedure(TargetRuntimeIntrinsicProcedure &&sym) {
+    const std::string name{sym.name};
+    procedures.insert(std::make_pair(name, std::move(sym)));
+  }
+  const std::string name;
+  std::multimap<std::string, const TargetRuntimeIntrinsicProcedure> procedures;
+};
+
+// HostRuntimeIntrinsicProcedure allows host runtime function to be called for
+// constant folding.
+struct HostRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription {
+  // Construct from runtime pointer with host types (float, double....)
+  template<typename HostTR, typename... HostTA>
+  HostRuntimeIntrinsicProcedure(const std::string &name,
+      FuncPointer<HostTR, HostTA...> func, bool isElemental = false);
+  HostRuntimeIntrinsicProcedure(
+      const IntrinsicProcedureRuntimeDescription &rteProc,
+      FuncPointer<void *> handle)
+    : IntrinsicProcedureRuntimeDescription{rteProc}, handle{handle} {}
+  const FuncPointer<void *> handle;
+};
+
+// Defines a wrapper type that indirects calls to host runtime functions.
+// Valid ConstantContainer are Scalar (only for elementals) and Constant.
+template<template<typename> typename ConstantContainer, typename TR,
+    typename... TA>
+using HostProcedureWrapper = std::function<ConstantContainer<TR>(
+    FoldingContext &, ConstantContainer<TA>...)>;
+
+// HostIntrinsicProceduresLibrary is a data structure that holds
+// HostRuntimeIntrinsicProcedure elements. It is meant for constant folding.
+// When queried for an intrinsic procedure, it can return a callable object that
+// implements this intrinsic if a host runtime function pointer for this
+// intrinsic was added to its data structure. It can also dynamically load
+// function pointer from a TargetIntrinsicProceduresLibrary if the related
+// library is available on the host.
+struct HostIntrinsicProceduresLibrary {
+  void AddProcedure(HostRuntimeIntrinsicProcedure &&sym) {
+    const std::string name{sym.name};
+    procedures.insert(std::make_pair(name, std::move(sym)));
+  }
+  bool HasEquivalentProcedure(
+      const IntrinsicProcedureRuntimeDescription &sym) const;
+  HostIntrinsicProceduresLibrary() { DefaultInit(); }
+  ~HostIntrinsicProceduresLibrary();
+  void DefaultInit();  // Try loading libpgmath functions and then load
+                       // functions from <cmath> and <complex>
+  void LoadTargetIntrinsicProceduresLibrary(
+      const TargetIntrinsicProceduresLibrary &lib);
+  template<template<typename> typename ConstantContainer, typename TR,
+      typename... TA>
+  std::optional<HostProcedureWrapper<ConstantContainer, TR, TA...>>
+  GetHostProcedureWrapper(const std::string &name);
+  std::multimap<std::string, const HostRuntimeIntrinsicProcedure> procedures;
+  std::map<std::string, void *>
+      dynamicallyLoadedLibraries;  // keep the handles for dlclose
+};
+
+}
+#endif  // FORTRAN_EVALUATE_INTRINSICS_LIBRARY_H_
diff --git a/flang/lib/evaluate/rte-interface.h b/flang/lib/evaluate/rte-interface.h
deleted file mode 100644 (file)
index bacaa2e..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef FORTRAN_EVALUATE_RTE_INTERFACE_H_
-#define FORTRAN_EVALUATE_RTE_INTERFACE_H_
-
-// Defines the structure that must be used in F18 when dealing with the
-// runtime, either with the target runtime or with the host runtime for
-// folding purposes
-// To avoid unnecessary header circular dependencies, the actual implementation
-// of the templatized member function are defined in rte.h
-// The header at hand must be included in order to add the rte interface data
-// structure as a member of some structure.
-// To actually use the rte interface, rte.h must be included. Note that rte.h
-// includes the header at hand.
-
-#include <functional>
-#include <map>
-#include <optional>
-#include <string>
-#include <vector>
-
-namespace Fortran::evaluate {
-class FoldingContext;
-namespace rte {
-
-using TypeCode = unsigned char;
-
-template<typename TR, typename... TA> using FuncPointer = TR (*)(TA...);
-
-enum class PassBy { Ref, Val };
-template<typename TA, PassBy Pass = PassBy::Ref> struct ArgumentInfo {
-  using Type = TA;
-  static constexpr PassBy pass{Pass};
-};
-
-template<typename TR, typename... ArgInfo> struct Signature {
-  // Note valid template argument are of form
-  //<TR, ArgumentInfo<TA, PassBy>...> where TA and TR belong to RteTypes.
-  // RteTypes is a type union defined in rte.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 RteProcedureSymbol {
-  const std::string name;
-  const TypeCode returnType;
-  const std::vector<TypeCode> argumentsType;
-  const std::vector<PassBy> argumentsPassedBy;
-  const bool isElemental;
-  const FuncPointer<void *> callable;
-  // callable only usable by HostRteProcedureSymbol but need to be created in
-  // case TargetRteProcedureSymbol is dynamically loaded because creating it
-  // dynamically would be too complex
-
-  // Construct from description using host independent types (RteTypes)
-  template<typename TR, typename... ArgInfo>
-  RteProcedureSymbol(
-      const Signature<TR, ArgInfo...> &signature, bool isElemental = false);
-};
-
-// For target rte library info
-struct TargetRteProcedureSymbol : RteProcedureSymbol {
-  // Construct from description using host independent types (RteTypes)
-  // Note: passing ref/val also needs to be passed by template to build
-  // the callable
-  template<typename TR, typename... ArgInfo>
-  TargetRteProcedureSymbol(const Signature<TR, ArgInfo...> &signature,
-      const std::string &symbolName, bool isElemental = false);
-  const std::string symbol;
-};
-
-struct TargetRteLibrary {
-  TargetRteLibrary(const std::string &name) : name{name} {}
-  void AddProcedure(TargetRteProcedureSymbol &&sym) {
-    const std::string name{sym.name};
-    procedures.insert(std::make_pair(name, std::move(sym)));
-  }
-  const std::string name;
-  std::multimap<std::string, const TargetRteProcedureSymbol> procedures;
-};
-
-// To use host runtime for folding
-struct HostRteProcedureSymbol : RteProcedureSymbol {
-  // Construct from runtime pointer with host types (float, double....)
-  template<typename HostTR, typename... HostTA>
-  HostRteProcedureSymbol(const std::string &name,
-      FuncPointer<HostTR, HostTA...> func, bool isElemental = false);
-  HostRteProcedureSymbol(
-      const RteProcedureSymbol &rteProc, FuncPointer<void *> handle)
-    : RteProcedureSymbol{rteProc}, handle{handle} {}
-  const FuncPointer<void *> handle;
-};
-
-// valid ConstantContainer are Scalar (only for elementals) and Constant
-template<template<typename> typename ConstantContainer, typename TR,
-    typename... TA>
-using HostProcedureWrapper = std::function<ConstantContainer<TR>(
-    FoldingContext &, ConstantContainer<TA>...)>;
-
-struct HostRte {
-  void AddProcedure(HostRteProcedureSymbol &&sym) {
-    const std::string name{sym.name};
-    procedures.insert(std::make_pair(name, std::move(sym)));
-  }
-  bool HasEquivalentProcedure(const RteProcedureSymbol &sym) const;
-  HostRte() { DefaultInit(); }
-  ~HostRte();
-  void DefaultInit();  // load functions from <cmath> and <complex>
-  void LoadTargetRteLibrary(const TargetRteLibrary &lib);  // TODO
-  template<template<typename> typename ConstantContainer, typename TR,
-      typename... TA>
-  std::optional<HostProcedureWrapper<ConstantContainer, TR, TA...>>
-  GetHostProcedureWrapper(const std::string &name);
-  // some data structure of HostRteProcedureSymbol
-  std::multimap<std::string, const HostRteProcedureSymbol> procedures;
-  std::map<std::string, void *>
-      dynamicallyLoadedLibraries;  // keep the handles for dlclose
-};
-
-}
-}
-#endif  // FORTRAN_EVALUATE_RTE_INTERFACE_H_