diff --git a/flang/lib/evaluate/CMakeLists.txt b/flang/lib/evaluate/CMakeLists.txt index e06eb755b37a..e4b66d2d745d 100644 --- a/flang/lib/evaluate/CMakeLists.txt +++ b/flang/lib/evaluate/CMakeLists.txt @@ -37,9 +37,3 @@ target_link_libraries(FortranEvaluate FortranParser m ) - -IF(CMAKE_SYSTEM_NAME STREQUAL Linux) - target_link_libraries(FortranEvaluate - dl - ) -endif() diff --git a/flang/lib/evaluate/intrinsics-library-templates.h b/flang/lib/evaluate/intrinsics-library-templates.h index 74d3a3166225..3a14ecf7d0bb 100644 --- a/flang/lib/evaluate/intrinsics-library-templates.h +++ b/flang/lib/evaluate/intrinsics-library-templates.h @@ -168,12 +168,5 @@ HostIntrinsicProceduresLibrary::GetHostProcedureWrapper( return std::nullopt; } -template -TargetRuntimeIntrinsicProcedure::TargetRuntimeIntrinsicProcedure( - const Signature &signature, const std::string &symbolName, - bool isElemental) - : IntrinsicProcedureRuntimeDescription{signature, isElemental}, - symbol{symbolName} {} - } #endif // FORTRAN_EVALUATE_INTRINSICS_LIBRARY_TEMPLATES_H_ diff --git a/flang/lib/evaluate/intrinsics-library.cc b/flang/lib/evaluate/intrinsics-library.cc index 261f1fa498b7..c24ac568afd6 100644 --- a/flang/lib/evaluate/intrinsics-library.cc +++ b/flang/lib/evaluate/intrinsics-library.cc @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// 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. +// This file defines host runtimes functions that can be used for folding +// intrinsic functions. // The default HostIntrinsicProceduresLibrary is built with and // functions that are guaranteed to exist from the C++ standard. @@ -22,10 +22,6 @@ #include #include #include -#if defined(__APPLE__) || defined(__unix__) -#define IS_POSIX_COMPLIANT -#include -#endif namespace Fortran::evaluate { @@ -55,48 +51,7 @@ bool HostIntrinsicProceduresLibrary::HasEquivalentProcedure( return false; } -void HostIntrinsicProceduresLibrary::LoadTargetIntrinsicProceduresLibrary( - const TargetIntrinsicProceduresLibrary &lib) { - if (dynamicallyLoadedLibraries.find(lib.name) != - dynamicallyLoadedLibraries.end()) { - return; // already loaded - } -#ifdef IS_POSIX_COMPLIANT - void *handle = dlopen((lib.name + std::string{".so"}).c_str(), RTLD_LAZY); - if (!handle) { - return; - } - dynamicallyLoadedLibraries.insert(std::make_pair(lib.name, handle)); - for (const auto &sym : lib.procedures) { - void *func{dlsym(handle, sym.second.symbol.c_str())}; - auto error{dlerror()}; - if (error) { - } else { - // Note: below is the only reinterpret_cast from an object pointer to - // function pointer As per C++11 and later rules on reinterpret_cast, it - // 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(HostRuntimeIntrinsicProcedure{ - sym.second, reinterpret_cast>(func)}); - } - } -#else - // TODO: systems that do not support dlopen (e.g windows) -#endif -} - -HostIntrinsicProceduresLibrary::~HostIntrinsicProceduresLibrary() { - for (auto iter{dynamicallyLoadedLibraries.begin()}; - iter != dynamicallyLoadedLibraries.end(); ++iter) { -#ifdef IS_POSIX_COMPLIANT - (void)dlclose(iter->second); -#endif - } -} - -// Map numerical intrinsic to / functions (for host folding -// only) +// Map numerical intrinsic to / functions // TODO mapping to function to be tested. func takes // real arg for n @@ -148,92 +103,9 @@ void AddLibmComplexHostProcedure( } } -// define mapping between numerical intrinsics and libpgmath symbols - -enum class MathOption { Fast, Precise, Relaxed }; - -char constexpr inline EncodePgmMathOption(MathOption m) { - switch (m) { - case MathOption::Fast: return 'f'; - case MathOption::Precise: return 'p'; - case MathOption::Relaxed: return 'r'; - } - return '\0'; // unreachable. Silencing bogus g++ warning -} - -template struct EncodePgmTypeHelper {}; - -template<> struct EncodePgmTypeHelper> { - static constexpr char value{'s'}; -}; -template<> struct EncodePgmTypeHelper> { - static constexpr char value{'d'}; -}; -template<> struct EncodePgmTypeHelper> { - static constexpr char value{'c'}; -}; -template<> struct EncodePgmTypeHelper> { - static constexpr char value{'z'}; -}; - -template -static constexpr char EncodePgmType{EncodePgmTypeHelper::value}; - -template -static std::string MakeLibpgmathName(const std::string &name, MathOption m) { - std::ostringstream stream; - stream << "__" << EncodePgmMathOption(m) << EncodePgmType << "_" << name - << "_1"; - // TODO Take mask and vector length into account - return stream.str(); -} - -template -static void AddLibpgmathTargetSymbols( - TargetIntrinsicProceduresLibrary &lib, MathOption opt) { - using F = Signature>; - const std::string oneArgFuncs[]{"acos", "asin", "atan", "cos", "cosh", "exp", - "log", "log10", "sin", "sinh", "tan", "tanh"}; - for (const std::string &name : oneArgFuncs) { - lib.AddProcedure(TargetRuntimeIntrinsicProcedure{ - F{name}, MakeLibpgmathName(name, opt), true}); - } - - if constexpr (T::category == TypeCategory::Real) { - using F2 = Signature, - ArgumentInfo>; - lib.AddProcedure(TargetRuntimeIntrinsicProcedure{ - F2{"atan2"}, MakeLibpgmathName("acos", opt), true}); - } else { - const std::string oneArgCmplxFuncs[]{ - "div", "sqrt"}; // for scalar, only complex available - for (const std::string &name : oneArgCmplxFuncs) { - lib.AddProcedure(TargetRuntimeIntrinsicProcedure{ - F{name}, MakeLibpgmathName(name, opt), true}); - } - } -} - -TargetIntrinsicProceduresLibrary BuildLibpgmTargetIntrinsicProceduresLibrary( - MathOption opt) { - TargetIntrinsicProceduresLibrary lib{"libpgmath"}; - AddLibpgmathTargetSymbols>(lib, opt); - AddLibpgmathTargetSymbols>(lib, opt); - AddLibpgmathTargetSymbols>(lib, opt); - AddLibpgmathTargetSymbols>(lib, opt); - return lib; -} - // Defines which host runtime functions will be used for folding 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 - TargetIntrinsicProceduresLibrary libpgmath{ - BuildLibpgmTargetIntrinsicProceduresLibrary(MathOption::Precise)}; - LoadTargetIntrinsicProceduresLibrary(libpgmath); AddLibmRealHostProcedure(*this); AddLibmRealHostProcedure(*this); diff --git a/flang/lib/evaluate/intrinsics-library.h b/flang/lib/evaluate/intrinsics-library.h index 36afb91cef85..7575a0ecccaf 100644 --- a/flang/lib/evaluate/intrinsics-library.h +++ b/flang/lib/evaluate/intrinsics-library.h @@ -15,17 +15,13 @@ #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 +// 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 Note that -// intrinsics-library-templates.h includes the header at hand. +// intrinsics-library-templates.h must be included. #include #include @@ -62,38 +58,12 @@ struct IntrinsicProcedureRuntimeDescription { const std::vector argumentsPassedBy; const bool isElemental; const FuncPointer 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 IntrinsicProcedureRuntimeDescription( const Signature &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 - TargetRuntimeIntrinsicProcedure(const Signature &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 procedures; -}; - // HostRuntimeIntrinsicProcedure allows host runtime function to be called for // constant folding. struct HostRuntimeIntrinsicProcedure : IntrinsicProcedureRuntimeDescription { @@ -119,9 +89,7 @@ using HostProcedureWrapper = std::function( // 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. +// intrinsic was added to its data structure. struct HostIntrinsicProceduresLibrary { void AddProcedure(HostRuntimeIntrinsicProcedure &&sym) { const std::string name{sym.name}; @@ -130,18 +98,12 @@ struct HostIntrinsicProceduresLibrary { bool HasEquivalentProcedure( const IntrinsicProcedureRuntimeDescription &sym) const; HostIntrinsicProceduresLibrary() { DefaultInit(); } - ~HostIntrinsicProceduresLibrary(); - void DefaultInit(); // Try loading libpgmath functions and then load - // functions from and - void LoadTargetIntrinsicProceduresLibrary( - const TargetIntrinsicProceduresLibrary &lib); + void DefaultInit(); template typename ConstantContainer, typename TR, typename... TA> std::optional> GetHostProcedureWrapper(const std::string &name); std::multimap procedures; - std::map - dynamicallyLoadedLibraries; // keep the handles for dlclose }; }