From ca0261b2539a38e7d7d59d9e9d2adeabce03d75c Mon Sep 17 00:00:00 2001 From: Jean Perier Date: Thu, 21 Mar 2019 10:08:57 -0700 Subject: [PATCH] [flang] Removed dynamic loading feature for intrinsic folding After more reflexion, dynamic loading brings to much uncertainty regarding which library is actually being use for folding. It is removed to avoid pushing people to use it. A static linking to libpgmath will be provided in a later commit. Original-commit: flang-compiler/f18@2161627d2896f06e763848443f61ae9624f03db1 Tree-same-pre-rewrite: false --- flang/lib/evaluate/CMakeLists.txt | 6 - flang/lib/evaluate/intrinsics-library-templates.h | 7 -- flang/lib/evaluate/intrinsics-library.cc | 134 +--------------------- flang/lib/evaluate/intrinsics-library.h | 50 +------- 4 files changed, 9 insertions(+), 188 deletions(-) diff --git a/flang/lib/evaluate/CMakeLists.txt b/flang/lib/evaluate/CMakeLists.txt index e06eb75..e4b66d2 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 74d3a31..3a14ecf 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 261f1fa..c24ac56 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 36afb91c..7575a0e 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 }; } -- 2.7.4