diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 631eb0b98df7..55c94823376b 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -846,7 +846,7 @@ void AMDGPUToolChain::addClangTargetOptions( // TODO: remove the SPIR-V bypass once it can encode (hidden) visibility. if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat) && - !getEffectiveTriple().isSPIRV()) { + !getEffectiveTriple().isSPIRV() && !getDriver().IsFlangMode()) { CC1Args.push_back("-fvisibility=hidden"); CC1Args.push_back("-fapply-global-visibility-to-externs"); } diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp index 9211803aa6a2..98be4861276f 100644 --- a/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -261,7 +261,7 @@ void HIPAMDToolChain::addClangTargetOptions( // TODO: remove the SPIR-V bypass once it can encode (hidden) visibility. if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ, options::OPT_fvisibility_ms_compat) && - !getEffectiveTriple().isSPIRV()) { + !getEffectiveTriple().isSPIRV() && !getDriver().IsFlangMode()) { CC1Args.append({"-fvisibility=hidden"}); CC1Args.push_back("-fapply-global-visibility-to-externs"); } diff --git a/flang-rt/CMakeLists.txt b/flang-rt/CMakeLists.txt index ab905cd46655..0d9696e32725 100644 --- a/flang-rt/CMakeLists.txt +++ b/flang-rt/CMakeLists.txt @@ -69,6 +69,7 @@ include(GetToolchainDirs) include(FlangCommon) include(HandleCompilerRT) include(ExtendPath) +include(FlangRTIntrospection) ############################ @@ -112,6 +113,11 @@ else () option(FLANG_RT_ENABLE_SHARED "Build Flang-RT as a shared library." OFF) endif () +# Enable building Fortran modules if Fortran is enabled +option(FLANG_RT_FORTRAN_MODULES "Build Flang-RT modules" "${RUNTIMES_FORTRAN_MODULES}") +if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED AND NOT FLANG_RT_FORTRAN_MODULES) + message(WARNING "LLVM_ENABLE_RUNTIMES=flang-rt, but not building anything") +endif () # TODO: Support tests for the GPU target. set(FLANG_RT_INCLUDE_TESTS_default ${LLVM_INCLUDE_TESTS}) @@ -181,6 +187,10 @@ check_cxx_source_compiles( " HAVE_DECL_STRERROR_S) +# Look for support of REAL(16), if not already defined via command +# line via -DFORTRAN_SUPPORTS_REAL16=YES/NO +check_fortran_quadmath_support() + # Search for clang_rt.builtins library. Need in addition to msvcrt. if (WIN32) find_compiler_rt_library(builtins FLANG_RT_BUILTINS_LIBRARY) @@ -194,7 +204,7 @@ if (UNIX AND CMAKE_SYSTEM_NAME MATCHES "AIX") endif () # Indicates REAL(16) support via an external library (e.g. libquadmath). -add_compile_definitions(FLANG_RT_SUPPORTS_REAL16=$) +add_compile_definitions(FLANG_RT_SUPPORTS_REAL16=$) # Check whether the compiler can undefine a macro using the "-Wp,-U" flag. # Aternatively, we could use diff --git a/flang-rt/cmake/modules/AddFlangRT.cmake b/flang-rt/cmake/modules/AddFlangRT.cmake index 871524b47e0e..265725ddec3d 100644 --- a/flang-rt/cmake/modules/AddFlangRT.cmake +++ b/flang-rt/cmake/modules/AddFlangRT.cmake @@ -94,6 +94,10 @@ function (add_flangrt_library name) set(build_object ON) elseif (build_static AND build_shared) set(build_object ON) + elseif (NOT build_static AND NOT build_shared) + # If not building a library, still build the object files + # Needed to generate the .mod files as byproduct + set(build_object ON) endif () # srctargets: targets that contain source files @@ -172,14 +176,18 @@ function (add_flangrt_library name) if (BUILD_SHARED_LIBS) if (build_shared) set(default_target "${name_shared}") - else () + elseif (build_static) set(default_target "${name_static}") + else () + set(default_target "${name_object}") endif () else () if (build_static) set(default_target "${name_static}") - else () + elseif (build_shared) set(default_target "${name_shared}") + else () + set(default_target "${name_object}") endif () endif () add_library(${name}.default ALIAS "${default_target}") @@ -194,6 +202,15 @@ function (add_flangrt_library name) endif () endif () + # An alias for the target that compiles the sources. When building a shared + # and static library at the same time, the sources are compiled in an object + # library, so there can be only one. + # Can be used to introspect and change the real target's properties, like: + # + # get_target_property(compile_target ${name}.compile ALIASED_TARGET) + # target_sources(${compile_target} more_sources.c) + add_library(${name}.compile ALIAS "${srctargets}") + foreach (tgtname IN LISTS libtargets) if (NOT WIN32) # Use same stem name for .a and .so. Common in UNIX environments. @@ -223,6 +240,16 @@ function (add_flangrt_library name) # Minimum required C++ version for Flang-RT, even if CMAKE_CXX_STANDARD is defined to something else. target_compile_features(${tgtname} PRIVATE cxx_std_17) + if (CMAKE_Fortran_COMPILER_ID MATCHES "LLVM") + target_compile_options(${tgtname} PRIVATE + # Always enable preprocessor regardless of file extension + "$<$:-cpp>" + + # Missing type descriptors are expected for intrinsic modules + "$<$:SHELL:-mmlir;SHELL:-ignore-missing-type-desc>" + ) + endif () + # When building the flang runtime if LTO is enabled the archive file # contains LLVM IR rather than object code. Currently flang is not # LTO aware so cannot link this file to compiled Fortran code. @@ -230,6 +257,10 @@ function (add_flangrt_library name) target_compile_options(${tgtname} PRIVATE -fno-lto) endif () + if (FORTRAN_SUPPORTS_REAL16) + target_compile_definitions(${tgtname} PRIVATE FLANG_SUPPORT_R16=1) + endif () + # Use compiler-specific options to disable exceptions and RTTI. if (LLVM_COMPILER_IS_GCC_COMPATIBLE) target_compile_options(${tgtname} PRIVATE diff --git a/flang-rt/cmake/modules/FlangRTIntrospection.cmake b/flang-rt/cmake/modules/FlangRTIntrospection.cmake new file mode 100644 index 000000000000..6ffa41e08cd7 --- /dev/null +++ b/flang-rt/cmake/modules/FlangRTIntrospection.cmake @@ -0,0 +1,30 @@ +include(CMakePushCheckState) +include(CheckFortranSourceCompiles) + +# Check whether the Fortran compiler supports real(16)/quadmath types +# +# Implementation notes: +# +# * FORTRAN_SUPPORTS_REAL16 can be set externally in a bootstrapping-runtimes +# build to ensure consistency of real(16) support between compiler and +# runtime. +# +# * cmake_push_check_state/cmake_pop_check_state is insufficient to isolate +# a compiler introspection environment, see +# https://gitlab.kitware.com/cmake/cmake/-/issues/27419 +# Additionally wrap it in a function namespace. +# +function (check_fortran_quadmath_support) + cmake_push_check_state(RESET) + set(CMAKE_REQUIRED_FLAGS "-ffree-form") + set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") # Skip link step + check_fortran_source_compiles([[ + subroutine test_quadmath + real(16) :: var1 + end + ]] + FORTRAN_SUPPORTS_REAL16 + ) + cmake_pop_check_state() +endfunction () + diff --git a/flang-rt/lib/CMakeLists.txt b/flang-rt/lib/CMakeLists.txt index 8738ae7b9c4b..58a7a24c19e0 100644 --- a/flang-rt/lib/CMakeLists.txt +++ b/flang-rt/lib/CMakeLists.txt @@ -12,7 +12,7 @@ if (FLANG_RT_ENABLE_STATIC OR FLANG_RT_ENABLE_SHARED) if (FLANG_RT_INCLUDE_CUF) add_subdirectory(cuda) endif() -else () +elseif (FLANG_RT_FORTRAN_MODULES) # Generate modules files only, skip the libraries add_subdirectory(runtime) endif () diff --git a/flang-rt/lib/runtime/CMakeLists.txt b/flang-rt/lib/runtime/CMakeLists.txt index f596bbed6f47..20aa3effeec9 100644 --- a/flang-rt/lib/runtime/CMakeLists.txt +++ b/flang-rt/lib/runtime/CMakeLists.txt @@ -12,6 +12,30 @@ find_package(Backtrace) set(HAVE_BACKTRACE ${Backtrace_FOUND}) set(BACKTRACE_HEADER ${Backtrace_HEADER}) +# Module sources that are required by other modules +set(intrinsics_sources + __fortran_builtins.f90 + __cuda_builtins.f90 +) + +# Fortran sources for builtin .mod files +set(module_sources + __fortran_ieee_exceptions.f90 + __fortran_type_info.f90 + flang_debug.f90 + iso_fortran_env.f90 + iso_fortran_env_impl.f90 + ieee_arithmetic.f90 + ieee_exceptions.f90 + ieee_features.f90 + iso_c_binding.f90 + + __cuda_device.f90 + cooperative_groups.f90 + cuda_runtime_api.f90 + cudadevice.f90 +) + # List of files that are buildable for all devices. set(supported_sources ${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp @@ -190,6 +214,25 @@ file(GLOB_RECURSE private_headers "${FLANG_SOURCE_DIR}/lib/Common/*.h" ) +if (LLVM_TARGET_TRIPLE MATCHES "^ppc|^powerpc") + list(APPEND intrinsics_sources + __ppc_types.f90 + ) + list(APPEND module_sources + __ppc_intrinsics.f90 + mma.f90 + ) +endif () + +# Compile as CUDA-Fortran, not directly supported by CMake +set_property(SOURCE + __cuda_device.f90 + cooperative_groups.f90 + cuda_runtime_api.f90 + cudadevice.f90 + APPEND PROPERTY + COMPILE_OPTIONS --offload-host-only -xcuda +) # Import changes from flang_rt.quadmath set(f128_sources "") @@ -220,6 +263,56 @@ if (TARGET FortranFloat128MathILib) endif () endif () + +# When a target depends on an object library, CMake seems to try to only build +# the object files that the target actual needs. If we are only interested +# in the module files, nothing get is built at all. To ensure that the module +# files are built, insert a custom target that is opaque to CMake so it cannot +# apply this optimization. Dependees on module files must depend on this +# barrier instead. An actual COMMAND (that does nothing) seems to be necessary +# on Windows to work. +function (add_module_barrier barriername objlib) + add_custom_target(${barriername} + COMMAND ${CMAKE_COMMAND} -E true + ) + add_dependencies(${barriername} ${objlib}) +endfunction () + + +# Build module files if requested. +# The object files written by Flang for these are unused. In the future parts +# of flang-rt may itself be implemented in Fortran in which case these Fortran +# sources need to be added to ${sources} to be included in +# libflang_rt.runtime{.a/.so}. If they also provide an importable .mod, add them +# to flang_module_target(... PUBLIC). +if (FLANG_RT_FORTRAN_MODULES) + # CMake ignores intrinsic USE dependencies + # CMake has an option Fortran_BUILDING_INSTRINSIC_MODULES/Fortran_BUILDING_INTRINSIC_MODULES + # to disable this behavior, unfortunately it does not work with Ninja + # (https://gitlab.kitware.com/cmake/cmake/-/issues/26803) + # As a workaround, we build those intrinsic modules first such that the main + # runtime can depend on it. + add_flangrt_library(flang_rt.mod.intrinsics OBJECT + ${intrinsics_sources} + ) + flang_module_target(flang_rt.mod.intrinsics PUBLIC) + add_module_barrier(flang_rt.mod.intrinsics.barrier flang_rt.mod.intrinsics) + + # The modules themselves + add_flangrt_library(flang_rt.mod OBJECT + ${module_sources} + ) + add_dependencies(flang_rt.mod flang_rt.mod.intrinsics.barrier) + flang_module_target(flang_rt.mod PUBLIC) + add_module_barrier(flang-rt-mod flang_rt.mod) +endif () + + +# Skip building libraries if not requested +if (NOT FLANG_RT_ENABLE_STATIC AND NOT FLANG_RT_ENABLE_SHARED) + return () +endif () + if ("${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^amdgcn|^nvptx") set(sources ${gpu_sources}) elseif(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA") diff --git a/flang/module/__cuda_builtins.f90 b/flang-rt/lib/runtime/__cuda_builtins.f90 similarity index 100% rename from flang/module/__cuda_builtins.f90 rename to flang-rt/lib/runtime/__cuda_builtins.f90 diff --git a/flang/module/__cuda_device.f90 b/flang-rt/lib/runtime/__cuda_device.f90 similarity index 100% rename from flang/module/__cuda_device.f90 rename to flang-rt/lib/runtime/__cuda_device.f90 diff --git a/flang/module/__fortran_builtins.f90 b/flang-rt/lib/runtime/__fortran_builtins.f90 similarity index 99% rename from flang/module/__fortran_builtins.f90 rename to flang-rt/lib/runtime/__fortran_builtins.f90 index c63c0f03214f..4f9874a9bef2 100644 --- a/flang/module/__fortran_builtins.f90 +++ b/flang-rt/lib/runtime/__fortran_builtins.f90 @@ -6,7 +6,7 @@ ! !===------------------------------------------------------------------------===! -#include '../include/flang/Runtime/magic-numbers.h' +#include '../../../flang/include/flang/Runtime/magic-numbers.h' ! These naming shenanigans prevent names from Fortran intrinsic modules ! from being usable on INTRINSIC statements, and force the program diff --git a/flang/module/__fortran_ieee_exceptions.f90 b/flang-rt/lib/runtime/__fortran_ieee_exceptions.f90 similarity index 98% rename from flang/module/__fortran_ieee_exceptions.f90 rename to flang-rt/lib/runtime/__fortran_ieee_exceptions.f90 index 3ac9b993186a..ff5c6b44317f 100644 --- a/flang/module/__fortran_ieee_exceptions.f90 +++ b/flang-rt/lib/runtime/__fortran_ieee_exceptions.f90 @@ -11,7 +11,7 @@ ! here under another name so that IEEE_ARITHMETIC can USE it and export its ! declarations without clashing with a non-intrinsic module in a program. -#include '../include/flang/Runtime/magic-numbers.h' +#include '../../../flang/include/flang/Runtime/magic-numbers.h' module __fortran_ieee_exceptions use __fortran_builtins, only: & diff --git a/flang/module/__fortran_type_info.f90 b/flang-rt/lib/runtime/__fortran_type_info.f90 similarity index 100% rename from flang/module/__fortran_type_info.f90 rename to flang-rt/lib/runtime/__fortran_type_info.f90 diff --git a/flang/module/__ppc_intrinsics.f90 b/flang-rt/lib/runtime/__ppc_intrinsics.f90 similarity index 100% rename from flang/module/__ppc_intrinsics.f90 rename to flang-rt/lib/runtime/__ppc_intrinsics.f90 diff --git a/flang/module/__ppc_types.f90 b/flang-rt/lib/runtime/__ppc_types.f90 similarity index 100% rename from flang/module/__ppc_types.f90 rename to flang-rt/lib/runtime/__ppc_types.f90 diff --git a/flang/module/cooperative_groups.f90 b/flang-rt/lib/runtime/cooperative_groups.f90 similarity index 96% rename from flang/module/cooperative_groups.f90 rename to flang-rt/lib/runtime/cooperative_groups.f90 index 8bb4af3afa79..5ca0c3aa1f3a 100644 --- a/flang/module/cooperative_groups.f90 +++ b/flang-rt/lib/runtime/cooperative_groups.f90 @@ -11,6 +11,7 @@ module cooperative_groups use, intrinsic :: __fortran_builtins, only: c_devptr => __builtin_c_devptr +use :: cudadevice ! implicit dependency, made explicit for CMake implicit none diff --git a/flang/module/cuda_runtime_api.f90 b/flang-rt/lib/runtime/cuda_runtime_api.f90 similarity index 100% rename from flang/module/cuda_runtime_api.f90 rename to flang-rt/lib/runtime/cuda_runtime_api.f90 diff --git a/flang/module/cudadevice.f90 b/flang-rt/lib/runtime/cudadevice.f90 similarity index 100% rename from flang/module/cudadevice.f90 rename to flang-rt/lib/runtime/cudadevice.f90 diff --git a/flang/module/flang_debug.f90 b/flang-rt/lib/runtime/flang_debug.f90 similarity index 100% rename from flang/module/flang_debug.f90 rename to flang-rt/lib/runtime/flang_debug.f90 diff --git a/flang/module/ieee_arithmetic.f90 b/flang-rt/lib/runtime/ieee_arithmetic.f90 similarity index 99% rename from flang/module/ieee_arithmetic.f90 rename to flang-rt/lib/runtime/ieee_arithmetic.f90 index 4e938a2daaa9..02cfae2dc6b1 100644 --- a/flang/module/ieee_arithmetic.f90 +++ b/flang-rt/lib/runtime/ieee_arithmetic.f90 @@ -8,7 +8,7 @@ ! Fortran 2018 Clause 17 -#include '../include/flang/Runtime/magic-numbers.h' +#include '../../../flang/include/flang/Runtime/magic-numbers.h' module ieee_arithmetic ! F18 Clause 17.1p1: diff --git a/flang/module/ieee_exceptions.f90 b/flang-rt/lib/runtime/ieee_exceptions.f90 similarity index 100% rename from flang/module/ieee_exceptions.f90 rename to flang-rt/lib/runtime/ieee_exceptions.f90 diff --git a/flang/module/ieee_features.f90 b/flang-rt/lib/runtime/ieee_features.f90 similarity index 100% rename from flang/module/ieee_features.f90 rename to flang-rt/lib/runtime/ieee_features.f90 diff --git a/flang/module/iso_c_binding.f90 b/flang-rt/lib/runtime/iso_c_binding.f90 similarity index 100% rename from flang/module/iso_c_binding.f90 rename to flang-rt/lib/runtime/iso_c_binding.f90 diff --git a/flang/module/iso_fortran_env.f90 b/flang-rt/lib/runtime/iso_fortran_env.f90 similarity index 98% rename from flang/module/iso_fortran_env.f90 rename to flang-rt/lib/runtime/iso_fortran_env.f90 index 3729b95a339f..2dc38bd1acfe 100644 --- a/flang/module/iso_fortran_env.f90 +++ b/flang-rt/lib/runtime/iso_fortran_env.f90 @@ -8,7 +8,7 @@ ! See Fortran 2023, subclause 16.10.2 -#include '../include/flang/Runtime/magic-numbers.h' +#include '../../../flang/include/flang/Runtime/magic-numbers.h' module iso_fortran_env diff --git a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp index 144662f1262a..70230d0f16c7 100644 --- a/flang-rt/lib/runtime/iso_fortran_env_impl.cpp +++ b/flang-rt/lib/runtime/iso_fortran_env_impl.cpp @@ -109,15 +109,15 @@ static constexpr std::int32_t selectedBfloat16{3}; static constexpr std::int32_t selectedReal32{4}; static constexpr std::int32_t selectedReal64{8}; -#if HAS_FLOAT80 -static constexpr std::int32_t selectedReal80{10}; -#elif HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16 +#if FLANG_RT_SUPPORTS_REAL16 static constexpr std::int32_t selectedReal80{16}; +#elif HAS_FLOAT80 +static constexpr std::int32_t selectedReal80{10}; #else static constexpr std::int32_t selectedReal80{-3}; #endif -#if HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16 +#if FLANG_RT_SUPPORTS_REAL16 static constexpr std::int32_t selectedReal64x2{16}; static constexpr std::int32_t selectedReal128{16}; #elif HAS_FLOAT80 @@ -245,7 +245,7 @@ extern const std::int32_t FORTRAN_NAMED_CONST(__builtin_real_kinds)[]{ #if HAS_FLOAT80 10, #endif -#if HAS_LDBL128 || FLANG_RT_SUPPORTS_REAL16 +#if FLANG_RT_SUPPORTS_REAL16 16, #endif }; diff --git a/flang/module/iso_fortran_env_impl.f90 b/flang-rt/lib/runtime/iso_fortran_env_impl.f90 similarity index 100% rename from flang/module/iso_fortran_env_impl.f90 rename to flang-rt/lib/runtime/iso_fortran_env_impl.f90 diff --git a/flang/module/mma.f90 b/flang-rt/lib/runtime/mma.f90 similarity index 100% rename from flang/module/mma.f90 rename to flang-rt/lib/runtime/mma.f90 diff --git a/flang-rt/test/CMakeLists.txt b/flang-rt/test/CMakeLists.txt index 054798d6ff53..1cf6269686bb 100644 --- a/flang-rt/test/CMakeLists.txt +++ b/flang-rt/test/CMakeLists.txt @@ -10,10 +10,12 @@ # for use by Lit, and delegates to LLVM's lit test handlers. llvm_canonicalize_cmake_booleans( + FLANG_RT_FORTRAN_MODULES FLANG_STANDALONE_BUILD LLVM_BUILD_EXAMPLES LLVM_BYE_LINK_INTO_TOOLS LLVM_ENABLE_PLUGINS + LLVM_TREE_AVAILABLE ) configure_lit_site_cfg( diff --git a/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90 b/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90 index 8fbc1091f0e6..8e17fe4e8891 100644 --- a/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90 +++ b/flang-rt/test/Driver/compare_iso_fortran_env_symbols.f90 @@ -1,6 +1,7 @@ ! UNSUPPORTED: offload-cuda, system-windows +! REQUIRES: fortran-modules -! RUN: %flang -c -funsigned %include/../module/iso_fortran_env_impl.f90 -o %t.f90.o +! RUN: %flang -c -funsigned %S/../../lib/runtime/iso_fortran_env_impl.f90 -o %t.f90.o ! Extract defined symbol names and sizes from the Fortran object and the ! already-built runtime library (which was compiled with the correct CMake flags). diff --git a/flang-rt/test/Driver/iso_fortran_env_impl.f90 b/flang-rt/test/Driver/iso_fortran_env_impl.f90 index f9dac6f0a20b..d856a9595ec4 100644 --- a/flang-rt/test/Driver/iso_fortran_env_impl.f90 +++ b/flang-rt/test/Driver/iso_fortran_env_impl.f90 @@ -2,6 +2,8 @@ ! (iso_fortran_env_impl.cpp) match the Fortran module definitions. ! UNSUPPORTED: offload-cuda +! REQUIRES: fortran-modules + ! RUN: %flang %isysroot -L"%libdir" %s -o %t ! RUN: env LD_LIBRARY_PATH="$LD_LIBRARY_PATH:%libdir" %t | FileCheck %s diff --git a/flang-rt/test/lit.cfg.py b/flang-rt/test/lit.cfg.py index 067ca5e5f114..5769943285a5 100644 --- a/flang-rt/test/lit.cfg.py +++ b/flang-rt/test/lit.cfg.py @@ -78,10 +78,17 @@ if config.osx_sysroot: isysroot_flag = ["-isysroot", config.osx_sysroot] config.substitutions.append(("%isysroot", " ".join(isysroot_flag))) +flang_args = [] +if not config.llvm_tree_available: + flang_args.append( + f"-fintrinsic-modules-path={config.flang_rt_output_resource_mod_dir}" + ) + tools = [ ToolSubst( "%flang", command=config.flang, + extra_args=flang_args, unresolved="fatal", ), ToolSubst( @@ -107,3 +114,6 @@ config.substitutions.append(("%libdir", config.flang_rt_output_resource_lib_dir) # For CUDA offloading, additional steps (device linking) and libraries (cudart) are needed. if config.flang_rt_experimental_offload_support == "CUDA": config.available_features.add("offload-cuda") + +if config.flang_rt_fortran_modules: + config.available_features.add("fortran-modules") diff --git a/flang-rt/test/lit.site.cfg.py.in b/flang-rt/test/lit.site.cfg.py.in index db7132b73192..8e3c902d4a3a 100644 --- a/flang-rt/test/lit.site.cfg.py.in +++ b/flang-rt/test/lit.site.cfg.py.in @@ -3,11 +3,14 @@ import sys config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" +config.llvm_tree_available = @LLVM_TREE_AVAILABLE@ config.flang_source_dir = "@FLANG_SOURCE_DIR@" config.flang_rt_source_dir = "@FLANG_RT_SOURCE_DIR@" config.flang_rt_binary_test_dir = os.path.dirname(__file__) config.flang_rt_output_resource_lib_dir = "@RUNTIMES_OUTPUT_RESOURCE_LIB_DIR@" +config.flang_rt_output_resource_mod_dir = "@RUNTIMES_OUTPUT_RESOURCE_MOD_DIR@" config.flang_rt_experimental_offload_support = "@FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT@" +config.flang_rt_fortran_modules = @FLANG_RT_FORTRAN_MODULES@ config.cc = "@CMAKE_C_COMPILER@" config.flang = "@CMAKE_Fortran_COMPILER@" config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@") diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt index be0b1f3d9b27..a8bd5e266aef 100644 --- a/flang/CMakeLists.txt +++ b/flang/CMakeLists.txt @@ -273,7 +273,6 @@ set(FLANG_TOOLS_INSTALL_DIR "${CMAKE_INSTALL_BINDIR}" CACHE PATH "Path for binary subdirectory (defaults to '${CMAKE_INSTALL_BINDIR}')") mark_as_advanced(FLANG_TOOLS_INSTALL_DIR) -set(FLANG_INTRINSIC_MODULES_DIR ${CMAKE_BINARY_DIR}/include/flang) set(FLANG_INCLUDE_DIR ${FLANG_BINARY_DIR}/include) # TODO: Remove when libclangDriver is lifted out of Clang diff --git a/flang/lib/Semantics/semantics.cpp b/flang/lib/Semantics/semantics.cpp index 8bca853f01a2..cde714c584d9 100644 --- a/flang/lib/Semantics/semantics.cpp +++ b/flang/lib/Semantics/semantics.cpp @@ -660,12 +660,15 @@ bool Semantics::Perform() { const auto *frontModule{std::get_if>( &program_.v.front().u)}; if (frontModule && - (std::get>(frontModule->value().t) - .statement.v.source == "__fortran_builtins" || - std::get>( - frontModule->value().t) - .statement.v.source == "__ppc_types")) { + std::get>(frontModule->value().t) + .statement.v.source == "__fortran_builtins") { // Don't try to read the builtins module when we're actually building it. + } else if (frontModule && + std::get>(frontModule->value().t) + .statement.v.source == "__ppc_types") { + // Don't try to read the UsePPCBuiltinTypesModule() we are currently + // building, but __fortran_builtins is needed to build it. + context_.UseFortranBuiltinsModule(); } else if (frontModule && (std::get>(frontModule->value().t) .statement.v.source == "__ppc_intrinsics" || diff --git a/flang/module/.clang-format b/flang/module/.clang-format deleted file mode 100644 index e3845288a2ae..000000000000 --- a/flang/module/.clang-format +++ /dev/null @@ -1 +0,0 @@ -DisableFormat: true diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt index d3da00c755cf..f1b492ee6cdc 100644 --- a/flang/test/CMakeLists.txt +++ b/flang/test/CMakeLists.txt @@ -2,11 +2,31 @@ # for use by Lit, and delegates to LLVM's lit test handlers. add_subdirectory(lib) +set(FLANG_TEST_Fortran_FLAGS "" CACHE STRING "Additional Fortran flags for running tests, such as -fintrinsic-modules-path=") + +if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES) + set(FLANG_TEST_ENABLE_MODULES_default ON) +else () + set(FLANG_TEST_ENABLE_MODULES_default OFF) +endif () +option(FLANG_TEST_ENABLE_MODULES "Force-enable tests that require intrinsic modules from Flang-RT" "${FLANG_TEST_ENABLE_MODULES_default}") + + +if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND FLANG_TEST_ENABLE_MODULES AND NOT FLANG_STANDALONE_BUILD) + set(FLANG_TEST_ENABLE_OPENMP_default ON) +else () + set(FLANG_TEST_ENABLE_OPENMP_default OFF) +endif () +option(FLANG_TEST_ENABLE_OPENMP "Force-enable tests that require modules from OpenMP" "${FLANG_TEST_ENABLE_OPENMP_default}") + + llvm_canonicalize_cmake_booleans( FLANG_STANDALONE_BUILD LLVM_BYE_LINK_INTO_TOOLS LLVM_ENABLE_PLUGINS LLVM_INCLUDE_EXAMPLES + FLANG_TEST_ENABLE_MODULES + FLANG_TEST_ENABLE_OPENMP ) set(FLANG_TOOLS_DIR ${FLANG_BINARY_DIR}/bin) @@ -59,7 +79,6 @@ set(FLANG_TEST_PARAMS set(FLANG_TEST_DEPENDS flang - module_files fir-opt tco bbc @@ -101,8 +120,14 @@ if (LLVM_INCLUDE_EXAMPLES) ) endif () -if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND NOT FLANG_STANDALONE_BUILD) - list(APPEND FLANG_TEST_DEPENDS "libomp-mod") +if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES AND NOT FLANG_STANDALONE_BUILD) + # For intrinsic module files (in flang-rt/) + list(APPEND FLANG_TEST_DEPENDS "flang-rt-mod") + + if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES) + # For omplib.mod and omplib_kinds.mod (in openmp/) + list(APPEND FLANG_TEST_DEPENDS "libomp-mod") + endif () endif () add_custom_target(flang-test-depends DEPENDS ${FLANG_TEST_DEPENDS}) diff --git a/flang/test/Driver/Inputs/resource_dir_with_per_target_subdir/finclude/flang/x86_64-unknown-linux-gnu/.keep b/flang/test/Driver/Inputs/resource_dir_with_per_target_subdir/finclude/flang/x86_64-unknown-linux-gnu/.keep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/flang/test/Driver/intrinsic-module-path_per_target.f90 b/flang/test/Driver/intrinsic-module-path_per_target.f90 index c32ff0c3185c..b0a2ac9c7c6b 100644 --- a/flang/test/Driver/intrinsic-module-path_per_target.f90 +++ b/flang/test/Driver/intrinsic-module-path_per_target.f90 @@ -1,5 +1,4 @@ ! Ensure argument -fintrinsic-modules-path works as expected. -! REQUIRES: x86-registered-target !----------------------------------------- ! FLANG DRIVER @@ -8,15 +7,15 @@ ! or lower priority than -fintrinsic-modules-path added here. Using ! basictestmoduleone.mod from Inputs/module-dir/ will trigger an error. -! RUN: %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -### 2>&1 | FileCheck %s --check-prefix=DEFAULTPATH +! RUN: %flang -fsyntax-only %s -### 2>&1 | FileCheck %s --check-prefix=DEFAULTPATH -! RUN: %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_DEFAULT -! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE 2>&1 | FileCheck %s --check-prefix=NOINPUTONE -! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTTWO 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO -! RUN: %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -! RUN: %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/module-dir-one/ -! RUN: %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir-one/ -fintrinsic-modules-path=%S/Inputs/module-dir/ -! RUN: not %flang -fsyntax-only --target=x86_64-unknown-linux-gnu -resource-dir %S/Inputs/resource_dir_with_per_target_subdir %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -fintrinsic-modules-path=%S/Inputs/module-dir-one/ 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE +! RUN: %flang -fsyntax-only %s -cpp -DINTRINSICS_DEFAULT +! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE 2>&1 | FileCheck %s --check-prefix=NOINPUTONE +! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTTWO 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO +! RUN: %flang -fsyntax-only %s -cpp -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ +! RUN: %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/module-dir-one/ +! RUN: %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir-one/ -fintrinsic-modules-path=%S/Inputs/module-dir/ +! RUN: not %flang -fsyntax-only %s -cpp -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -fintrinsic-modules-path=%S/Inputs/module-dir-one/ 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE !----------------------------------------- @@ -42,8 +41,8 @@ !----------------------------------------- -! DEFAULTPATH: -fc1 -! DEFAULTPATH-SAME: -fintrinsic-modules-path" "{{.*(\\\\|/)}}resource_dir_with_per_target_subdir{{(\\\\|/)}}finclude{{(\\\\|/)}}flang{{(\\\\|/)}}x86_64-unknown-linux-gnu" +! DEFAULTPATH: "-fc1" +! DEFAULTPATH-SAME: "-fintrinsic-modules-path" "{{.*(\\\\|/)}}finclude{{(\\\\|/)}}flang{{(\\\\|/)}}{{[^/\]+}}" ! NOINPUTONE: Source file 'basictestmoduleone.mod' was not found ! NOINPUTTWO: Source file 'basictestmoduletwo.mod' was not found diff --git a/flang/test/Driver/pp-fixed-form.f90 b/flang/test/Driver/pp-fixed-form.f90 index bb869cd3341a..bdeb80497c31 100644 --- a/flang/test/Driver/pp-fixed-form.f90 +++ b/flang/test/Driver/pp-fixed-form.f90 @@ -8,12 +8,12 @@ FIXED-NEXT: "-fc1" {{.*}} "-ffixed-form" {{.*}} "-x" "f95-cpp-input" "fixed-form !RUN: %flang -save-temps -### -ffree-form %S/Inputs/free-form-test.f90 2>&1 | FileCheck %s --check-prefix=FREE-FLAG FREE-FLAG: "-fc1" {{.*}} "-o" "free-form-test.i" {{.*}} "-x" "f95" "{{.*}}/free-form-test.f90" -FREE-FLAG-NEXT: "-fc1" {{.*}} "-emit-llvm-bc" "-ffree-form" +FREE-FLAG-NEXT: "-fc1" {{.*}} "-emit-llvm-bc"{{.*}}"-ffree-form" FREE-FLAG-NOT: "-ffixed-form" FREE-FLAG-SAME: "-x" "f95-cpp-input" "free-form-test.i" !RUN: %flang -save-temps -### -ffixed-form %S/Inputs/fixed-form-test.f 2>&1 | FileCheck %s --check-prefix=FIXED-FLAG FIXED-FLAG: "-fc1" {{.*}} "-o" "fixed-form-test.i" {{.*}} "-x" "f95" "{{.*}}/fixed-form-test.f" -FIXED-FLAG-NEXT: "-fc1" {{.*}} "-emit-llvm-bc" "-ffixed-form" +FIXED-FLAG-NEXT: "-fc1" {{.*}} "-emit-llvm-bc"{{.*}}"-ffixed-form" FIXED-FLAG-NOT: "-ffixed-form" FIXED-FLAG-SAME: "-x" "f95-cpp-input" "fixed-form-test.i" diff --git a/flang/test/Lower/OpenMP/simd_aarch64.f90 b/flang/test/Lower/OpenMP/simd_aarch64.f90 index 735237223bcb..20dd50d3ac91 100644 --- a/flang/test/Lower/OpenMP/simd_aarch64.f90 +++ b/flang/test/Lower/OpenMP/simd_aarch64.f90 @@ -1,6 +1,10 @@ -! Tests for 2.9.3.1 Simd and target dependent defult alignment for AArch64 +! Tests for 2.9.3.1 Simd and target dependent default alignment for AArch64 ! The default alignment for AARCH64 is 0 so we do not emit aligned clause ! REQUIRES: aarch64-registered-target + +! Requires aarch64 iso_c_binding.mod which currently is only available if your host is also aarch64 +! REQUIRES: aarch64-host + ! RUN: %flang_fc1 -triple aarch64-unknown-linux-gnu -emit-hlfir -fopenmp %s -o - | FileCheck %s subroutine simdloop_aligned_cptr(A) use iso_c_binding diff --git a/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 b/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 index d3f287addc2e..1bd49333b306 100644 --- a/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 +++ b/flang/test/Lower/OpenMP/target-enter-data-default-openmp52.f90 @@ -1,7 +1,7 @@ ! This test checks the lowering and application of default map types for the target enter/exit data constructs and map clauses -!RUN: %flang -fc1 -emit-fir -fopenmp -fopenmp-version=52 -o - %s | FileCheck %s --check-prefix=CHECK-52 -!RUN: not %flang -fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-51 +!RUN: %flang_fc1 -emit-fir -fopenmp -fopenmp-version=52 -o - %s | FileCheck %s --check-prefix=CHECK-52 +!RUN: not %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1| FileCheck %s --check-prefix=CHECK-51 module test real, allocatable :: A diff --git a/flang/test/Lower/where-loc.f90 b/flang/test/Lower/where-loc.f90 index 75d1452da9df..033a6fc74c86 100644 --- a/flang/test/Lower/where-loc.f90 +++ b/flang/test/Lower/where-loc.f90 @@ -1,5 +1,5 @@ ! Test line location lowering of WHERE statements. -! RUN: %flang -fc1 -emit-hlfir -mmlir -mlir-print-debuginfo -mmlir --mlir-print-local-scope -o - %s | FileCheck %s +! RUN: %flang_fc1 -emit-hlfir -mmlir -mlir-print-debuginfo -mmlir --mlir-print-local-scope -o - %s | FileCheck %s ! CHECK-LABEL: func.func @_QPtest_where_construct subroutine test_where_construct(mask, m2, x, y) diff --git a/flang/test/Parser/bug2280.f90 b/flang/test/Parser/bug2280.f90 index d24b26ddeb0d..2de644e159bd 100644 --- a/flang/test/Parser/bug2280.f90 +++ b/flang/test/Parser/bug2280.f90 @@ -1,4 +1,4 @@ -!RUN: %flang -fc1 -fdebug-unparse %s | FileCheck %s +!RUN: %flang_fc1 -fdebug-unparse %s | FileCheck %s !CHECK: 1 FORMAT(1X) 1 format(1x) !CHECK: 2 FORMAT(1X) diff --git a/flang/test/Preprocessing/fixed-free.f b/flang/test/Preprocessing/fixed-free.f index 95f63a4d71e4..7140bc6aec36 100644 --- a/flang/test/Preprocessing/fixed-free.f +++ b/flang/test/Preprocessing/fixed-free.f @@ -1,5 +1,5 @@ !RUN: %flang -E %s 2>&1 | FileCheck %s -!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s !CHECK-NOT: dir$ !CHECK-NOT: error: !dir$ fixed diff --git a/flang/test/Preprocessing/no-pp-if.f90 b/flang/test/Preprocessing/no-pp-if.f90 index 3e49df3deb25..ab08a4f838a9 100644 --- a/flang/test/Preprocessing/no-pp-if.f90 +++ b/flang/test/Preprocessing/no-pp-if.f90 @@ -1,4 +1,4 @@ -!RUN: %flang -fc1 -fdebug-unparse %s 2>&1 | FileCheck %s +!RUN: %flang_fc1 -fdebug-unparse %s 2>&1 | FileCheck %s !CHECK-NOT: ERROR STOP !CHECK: CONTINUE #if defined UNDEFINED diff --git a/flang/test/Semantics/bug163242.f90 b/flang/test/Semantics/bug163242.f90 index 5e020aeb4dc0..3c0a2b6b3222 100644 --- a/flang/test/Semantics/bug163242.f90 +++ b/flang/test/Semantics/bug163242.f90 @@ -1,4 +1,4 @@ -!RUN: %flang -fc1 -fsyntax-only %s | FileCheck --allow-empty %s +!RUN: %flang_fc1 -fsyntax-only %s | FileCheck --allow-empty %s !CHECK-NOT: error: character(0), allocatable :: ch allocate(character(-1) :: ch) diff --git a/flang/test/Semantics/bug164303.f90 b/flang/test/Semantics/bug164303.f90 index c356c0739257..39af27e91424 100644 --- a/flang/test/Semantics/bug164303.f90 +++ b/flang/test/Semantics/bug164303.f90 @@ -1,4 +1,4 @@ -!RUN: %flang -fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +!RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s module foo_mod use, intrinsic :: iso_fortran_env use, intrinsic :: iso_c_binding diff --git a/flang/test/Semantics/bug2021.f90 b/flang/test/Semantics/bug2021.f90 index f5214bce946a..4d914f34e9a5 100644 --- a/flang/test/Semantics/bug2021.f90 +++ b/flang/test/Semantics/bug2021.f90 @@ -1,4 +1,4 @@ -!RUN: %flang -fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s +!RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s !CHECK-NOT: warning: Value of uninitialized local variable 'b' is used but never defined [-Wused-undefined-variable] real :: a, b pointer(p,a) diff --git a/flang/test/lit.cfg.py b/flang/test/lit.cfg.py index 3a87f9ea0680..92278a220cec 100644 --- a/flang/test/lit.cfg.py +++ b/flang/test/lit.cfg.py @@ -140,18 +140,92 @@ config.substitutions.append(("%isysroot", " ".join(isysroot_flag))) if config.default_sysroot: config.available_features.add("default_sysroot") +host_triple = config.host_triple.split("-") +config.available_features.add(f"{host_triple[0]}-host") + +flang_exe = lit.util.which("flang", config.flang_llvm_tools_dir) +if not flang_exe: + lit_config.fatal(f"Could not identify flang executable") + +# Intrinsic paths that are added implicitly by the `flang` driver, but have to be added manually when invoking the frontend `flang -fc1`. +flang_driver_search_args = [] + +# Intrinsic paths that are added to `flang` as well as `flang -fc1`. +flang_extra_search_args = list(config.flang_test_fortran_flags) + + +def get_resource_module_intrinsic_dir(modfile): + # Determine the intrinsic module search path that is added by the driver. If + # skipping the driver using -fc1, we need to append the path manually. + flang_intrinsics_dir = subprocess.check_output( + [flang_exe, *config.flang_test_fortran_flags, f"-print-file-name={modfile}"], + text=True, + ).strip() + flang_intrinsics_dir = os.path.dirname(flang_intrinsics_dir) + return flang_intrinsics_dir or None + + +intrinsics_mod_path = get_resource_module_intrinsic_dir("__fortran_builtins.mod") +if intrinsics_mod_path: + flang_driver_search_args += [f"-fintrinsic-modules-path={intrinsics_mod_path}"] + +openmp_mod_path = get_resource_module_intrinsic_dir("omp_lib.mod") +if openmp_mod_path and openmp_mod_path != intrinsics_mod_path: + flang_driver_search_args += [f"-fintrinsic-modules-path={openmp_mod_path}"] + + +# If intrinsic modules are not available, disable tests unless they are marked as 'module-independent'. +config.available_features.add("module-independent") +if config.flang_test_enable_modules or intrinsics_mod_path: + config.available_features.add("flangrt-modules") +else: + lit_config.warning( + f"Intrinsic modules not in driver default paths: disabling most tests; Use FLANG_TEST_ENABLE_MODULES=ON to force-enable" + ) + config.limit_to_features.add("module-independent") + +# Determine if OpenMP runtime was built (enable OpenMP tests via REQUIRES in test file) +if config.flang_test_enable_openmp or openmp_mod_path: + config.available_features.add("openmp_runtime") + + # Search path for omp_lib.h with LLVM_ENABLE_RUNTIMES=openmp + # FIXME: In a bootstrapping build, openmp should write this file into a + # shared directory + flang_extra_search_args += [ + "-I", + f"{config.flang_obj_root}/../../runtimes/runtimes-bins/openmp/runtime/src", + ] +else: + lit_config.warning( + f"OpenMP modules found not in driver default paths: OpenMP tests disabled; Use FLANG_TEST_ENABLE_OPENMP=ON to force-enable" + ) + + +lit_config.note(f"using flang: {flang_exe}") +lit_config.note( + f"using flang implicit search paths: {' '.join(flang_driver_search_args)}" +) +lit_config.note(f"using flang extra search paths: {' '.join(flang_extra_search_args)}") + # For each occurrence of a flang tool name, replace it with the full path to # the build directory holding that tool. tools = [ + ToolSubst( + "bbc", + command=FindTool("bbc"), + extra_args=flang_driver_search_args + flang_extra_search_args, + unresolved="fatal", + ), ToolSubst( "%flang", - command=FindTool("flang"), + command=flang_exe, + extra_args=flang_extra_search_args, unresolved="fatal", ), ToolSubst( "%flang_fc1", - command=FindTool("flang"), - extra_args=["-fc1"], + command=flang_exe, + extra_args=["-fc1"] + flang_driver_search_args + flang_extra_search_args, unresolved="fatal", ), ] @@ -194,16 +268,7 @@ result = lit_config.params.get("LIBPGMATH") if result: config.environment["LIBPGMATH"] = True -# Determine if OpenMP runtime was built (enable OpenMP tests via REQUIRES in test file) -openmp_flags_substitution = "-fopenmp" -if config.have_openmp_rtl: - config.available_features.add("openmp_runtime") - # For the enabled OpenMP tests, add a substitution that is needed in the tests to find - # the omp_lib.{h,mod} files, depending on whether the OpenMP runtime was built as a - # project or runtime. - if config.openmp_module_dir: - openmp_flags_substitution += f" -J {config.openmp_module_dir}" -config.substitutions.append(("%openmp_flags", openmp_flags_substitution)) +config.substitutions.append(("%openmp_flags", "-fopenmp")) # Add features and substitutions to test F128 math support. # %f128-lib substitution may be used to generate check prefixes diff --git a/flang/test/lit.site.cfg.py.in b/flang/test/lit.site.cfg.py.in index 2b66dd64b8c1..74c3e07e0a40 100644 --- a/flang/test/lit.site.cfg.py.in +++ b/flang/test/lit.site.cfg.py.in @@ -13,10 +13,12 @@ config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@" config.flang_obj_root = "@FLANG_BINARY_DIR@" config.flang_tools_dir = lit_config.substitute("@FLANG_TOOLS_DIR@") -config.flang_intrinsic_modules_dir = "@FLANG_INTRINSIC_MODULES_DIR@" config.flang_headers_dir = "@HEADER_BINARY_DIR@" config.flang_llvm_tools_dir = "@CMAKE_BINARY_DIR@/bin" config.flang_test_triple = "@FLANG_TEST_TARGET_TRIPLE@" +config.flang_test_fortran_flags = "@FLANG_TEST_Fortran_FLAGS@".split() +config.flang_test_enable_modules = @FLANG_TEST_ENABLE_MODULES@ +config.flang_test_enable_openmp = @FLANG_TEST_ENABLE_OPENMP@ config.flang_examples = @LLVM_INCLUDE_EXAMPLES@ config.python_executable = "@PYTHON_EXECUTABLE@" config.flang_standalone_build = @FLANG_STANDALONE_BUILD@ @@ -25,11 +27,6 @@ config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@ config.osx_sysroot = path(r"@CMAKE_OSX_SYSROOT@") config.targets_to_build = "@TARGETS_TO_BUILD@" config.default_sysroot = "@DEFAULT_SYSROOT@" -config.have_openmp_rtl = ("@LLVM_TOOL_OPENMP_BUILD@" == "TRUE") or ("openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";")) -if "openmp" in "@LLVM_ENABLE_RUNTIMES@".lower().split(";"): - config.openmp_module_dir = "@CMAKE_BINARY_DIR@/runtimes/runtimes-bins/openmp/runtime/src" -else: - config.openmp_module_dir = None config.flang_runtime_f128_math_lib = "@FLANG_RUNTIME_F128_MATH_LIB@" config.have_ldbl_mant_dig_113 = "@HAVE_LDBL_MANT_DIG_113@" diff --git a/flang/tools/CMakeLists.txt b/flang/tools/CMakeLists.txt index 1d2d2c608faf..1b297af74cae 100644 --- a/flang/tools/CMakeLists.txt +++ b/flang/tools/CMakeLists.txt @@ -7,7 +7,6 @@ #===------------------------------------------------------------------------===# add_subdirectory(bbc) -add_subdirectory(f18) add_subdirectory(flang-driver) add_subdirectory(tco) add_subdirectory(f18-parse-demo) diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt deleted file mode 100644 index 900b341e85c5..000000000000 --- a/flang/tools/f18/CMakeLists.txt +++ /dev/null @@ -1,160 +0,0 @@ -set(LLVM_LINK_COMPONENTS - FrontendOpenACC - FrontendOpenMP - Support - ) - -# Define the list of Fortran module files for which it is -# sufficient to generate the module file via -fsyntax-only. -set(MODULES - "__fortran_builtins" - "__fortran_ieee_exceptions" - "__fortran_type_info" - "__ppc_types" - "__ppc_intrinsics" - "mma" - "__cuda_builtins" - "__cuda_device" - "cooperative_groups" - "cuda_runtime_api" - "cudadevice" - "ieee_arithmetic" - "ieee_exceptions" - "ieee_features" - "iso_c_binding" - "iso_fortran_env" - "iso_fortran_env_impl" - "flang_debug" -) - -# Check if 128-bit float computations can be done via long double. -check_cxx_source_compiles( - "#include - #if LDBL_MANT_DIG != 113 - #error LDBL_MANT_DIG != 113 - #endif - int main() { return 0; } - " - HAVE_LDBL_MANT_DIG_113) - -# Figure out whether we can support REAL(KIND=16) -if (FLANG_RUNTIME_F128_MATH_LIB) - set(FLANG_SUPPORT_R16 "1") -elseif (HAVE_LDBL_MANT_DIG_113) - set(FLANG_SUPPORT_R16 "1") -else() - set(FLANG_SUPPORT_R16 "0") -endif() - -# Init variable to hold extra object files coming from the Fortran modules; -# these module files will be contributed from the CMakeLists in flang/tools/f18. -set(module_objects "") - -# Create module files directly from the top-level module source directory. -# If CMAKE_CROSSCOMPILING, then the newly built flang executable was -# cross compiled, and thus can't be executed on the build system and thus -# can't be used for generating module files. -if (NOT CMAKE_CROSSCOMPILING) - foreach(filename ${MODULES}) - set(depends "") - set(opts "") - if(${filename} STREQUAL "__fortran_builtins" OR - ${filename} STREQUAL "__ppc_types") - elseif(${filename} STREQUAL "__ppc_intrinsics" OR - ${filename} STREQUAL "mma") - set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__ppc_types.mod) - elseif(${filename} STREQUAL "__cuda_device" OR - ${filename} STREQUAL "cudadevice" OR - ${filename} STREQUAL "cooperative_groups" OR - ${filename} STREQUAL "cuda_runtime_api") - set(opts -fc1 -xcuda) - if(${filename} STREQUAL "__cuda_device") - set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_builtins.mod) - elseif(${filename} STREQUAL "cudadevice") - set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__cuda_device.mod) - elseif(${filename} STREQUAL "cooperative_groups") - set(depends ${FLANG_INTRINSIC_MODULES_DIR}/cudadevice.mod) - endif() - else() - set(depends ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtins.mod) - if(${filename} STREQUAL "iso_fortran_env") - set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/iso_fortran_env_impl.mod) - endif() - if(${filename} STREQUAL "ieee_arithmetic" OR - ${filename} STREQUAL "ieee_exceptions") - set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_ieee_exceptions.mod) - endif() - endif() - if(NOT ${filename} STREQUAL "__fortran_type_info" AND NOT ${filename} STREQUAL "__fortran_builtins") - set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod) - endif() - - # The module contains PPC vector types that needs the PPC target. - if(${filename} STREQUAL "__ppc_intrinsics" OR - ${filename} STREQUAL "mma") - if (PowerPC IN_LIST LLVM_TARGETS_TO_BUILD) - set(opts "--target=ppc64le") - else() - # Do not compile PPC module if the target is not available. - continue() - endif() - endif() - - set(decls "") - if (FLANG_SUPPORT_R16) - set(decls "-DFLANG_SUPPORT_R16") - endif() - - # Some modules have an implementation part that needs to be added to the - # flang_rt.runtime library. - set(compile_with "-fsyntax-only") - set(object_output "") - set(include_in_link FALSE) - - set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename}) - # TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support - add_custom_command(OUTPUT ${base}.mod ${object_output} - COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR} - COMMAND flang ${opts} ${decls} -cpp ${compile_with} -module-dir ${FLANG_INTRINSIC_MODULES_DIR} - ${FLANG_SOURCE_DIR}/module/${filename}.f90 - DEPENDS flang ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${FLANG_SOURCE_DIR}/module/__fortran_builtins.f90 ${depends} - ) - list(APPEND MODULE_FILES ${base}.mod) - install(FILES ${base}.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang" COMPONENT flang-module-interfaces) - - # If a module has been compiled into an object file, add the file to - # the link line for the flang_rt.runtime library. - if(include_in_link) - list(APPEND module_objects ${object_output}) - endif() - endforeach() - - # Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that - # the compiled Fortran modules can be added to the link line of the flang_rt.runtime - # library. - set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "" FORCE) - - # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include. - # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod. Compile these - # files only if OpenMP support has been configured. - if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES) - message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_RUNTIMES, assuming omp_lib.mod is built there") - else() - message(WARNING "Not building omp_lib.mod, no OpenMP runtime in either LLVM_ENABLE_PROJECTS or LLVM_ENABLE_RUNTIMES") - endif() - add_custom_target(flang-module-interfaces ALL DEPENDS module_files) - add_llvm_install_targets(install-flang-module-interfaces - COMPONENT flang-module-interfaces) - add_dependencies(install-flang-module-interfaces flang-module-interfaces) -endif() - -add_custom_target(module_files ALL DEPENDS ${MODULE_FILES}) -set_target_properties(module_files PROPERTIES FOLDER "Flang/Resources") - -# TODO Move this to a more suitable location -# Copy the generated omp_lib.h header file, if OpenMP support has been configured. -if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES) - message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_RUNTIMES, assuming omp_lib.h is built there") -else() - message(STATUS "Not copying omp_lib.h, no OpenMP runtime in either LLVM_ENABLE_PROJECTS or LLVM_ENABLE_RUNTIMES") -endif() diff --git a/flang/tools/f18/dump.cpp b/flang/tools/f18/dump.cpp deleted file mode 100644 index f11b5aedf4c6..000000000000 --- a/flang/tools/f18/dump.cpp +++ /dev/null @@ -1,42 +0,0 @@ -//===-- tools/f18/dump.cpp ------------------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -// This file defines Dump routines available for calling from the debugger. -// Each is based on operator<< for that type. There are overloadings for -// reference and pointer, and for dumping to a provided raw_ostream or errs(). - -#ifdef DEBUGF18 - -#include "llvm/Support/raw_ostream.h" - -#define DEFINE_DUMP(ns, name) \ - namespace ns { \ - class name; \ - llvm::raw_ostream &operator<<(llvm::raw_ostream &, const name &); \ - } \ - void Dump(llvm::raw_ostream &os, const ns::name &x) { os << x << '\n'; } \ - void Dump(llvm::raw_ostream &os, const ns::name *x) { \ - if (x == nullptr) \ - os << "null\n"; \ - else \ - Dump(os, *x); \ - } \ - void Dump(const ns::name &x) { Dump(llvm::errs(), x); } \ - void Dump(const ns::name *x) { Dump(llvm::errs(), *x); } - -namespace Fortran { -DEFINE_DUMP(parser, Name) -DEFINE_DUMP(parser, CharBlock) -DEFINE_DUMP(semantics, Symbol) -DEFINE_DUMP(semantics, Scope) -DEFINE_DUMP(semantics, IntrinsicTypeSpec) -DEFINE_DUMP(semantics, DerivedTypeSpec) -DEFINE_DUMP(semantics, DeclTypeSpec) -} // namespace Fortran - -#endif diff --git a/llvm/runtimes/CMakeLists.txt b/llvm/runtimes/CMakeLists.txt index 0905f09c8b79..686089efa963 100644 --- a/llvm/runtimes/CMakeLists.txt +++ b/llvm/runtimes/CMakeLists.txt @@ -287,6 +287,10 @@ function(runtime_default_target) endif () endif () endif () + if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES) + # The target flang-rt-mod is a dependee of check-flang. + list(APPEND extra_targets "flang-rt-mod") + endif () if(LLVM_INCLUDE_TESTS) set_property(GLOBAL APPEND PROPERTY LLVM_ALL_LIT_TESTSUITES "@${LLVM_BINARY_DIR}/runtimes/runtimes-bins/lit.tests") @@ -581,22 +585,7 @@ if(build_runtimes) endif() endforeach() endif() - # Allow openmp to see the Fortran compiler - if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES AND "flang" IN_LIST LLVM_ENABLE_PROJECTS) - list(APPEND extra_args ENABLE_FORTRAN) - endif() if("openmp" IN_LIST LLVM_ENABLE_RUNTIMES OR "offload" IN_LIST LLVM_ENABLE_RUNTIMES) - if (${LLVM_TOOL_FLANG_BUILD}) - message(STATUS "Configuring build of omp_lib.mod and omp_lib_kinds.mod via flang") - set(LIBOMP_FORTRAN_MODULES_COMPILER "${CMAKE_BINARY_DIR}/bin/flang") - set(LIBOMP_MODULES_INSTALL_PATH "${CMAKE_INSTALL_INCLUDEDIR}/flang") - # TODO: This is a workaround until flang becomes a first-class project - # in llvm/CMakeList.txt. Until then, this line ensures that flang is - # built before "openmp" is built as a runtime project. Besides "flang" - # to build the compiler, we also need to add "module_files" to make sure - # that all .mod files are also properly build. - list(APPEND extra_deps "flang" "module_files") - endif() foreach(dep opt llvm-link llvm-extract clang llvm-offload-binary clang-nvlink-wrapper) if(TARGET ${dep}) list(APPEND extra_deps ${dep}) @@ -621,12 +610,18 @@ if(build_runtimes) if(LLVM_LIBC_FULL_BUILD) list(APPEND extra_cmake_args "-DLLVM_LIBC_FULL_BUILD=ON") endif() - if("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES) - list(APPEND extra_args ENABLE_FORTRAN) - if (${LLVM_TOOL_FLANG_BUILD}) - list(APPEND extra_deps "flang" "module_files") + if("flang" IN_LIST LLVM_ENABLE_PROJECTS) + # Allow runtimes that can use it to access the Flang compiler + if ("openmp" IN_LIST LLVM_ENABLE_RUNTIMES OR "flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES) + list(APPEND extra_args ENABLE_FORTRAN) endif() - endif () + # Ensure REAL(16) support in runtimes to be consistent with compiler + if(FLANG_RUNTIME_F128_MATH_LIB OR HAVE_LDBL_MANT_DIG_113) + list(APPEND extra_cmake_args "-DFORTRAN_SUPPORTS_REAL16=1") + else() + list(APPEND extra_cmake_args "-DFORTRAN_SUPPORTS_REAL16=0") + endif() + endif() if(NOT LLVM_RUNTIME_TARGETS) runtime_default_target( diff --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt index 512bd41f8a9e..08546dfaf249 100644 --- a/openmp/CMakeLists.txt +++ b/openmp/CMakeLists.txt @@ -106,7 +106,7 @@ math(EXPR LIBOMP_VERSION_BUILD_MONTH_DAY "${LIBOMP_VERSION_BUILD}%10000") set(LIBOMP_BUILD_DATE "No_Timestamp") -set(LIBOMP_FORTRAN_MODULES FALSE CACHE BOOL +set(LIBOMP_FORTRAN_MODULES "${RUNTIMES_FORTRAN_MODULES}" CACHE BOOL "Create Fortran module files? (requires fortran compiler)") option(LIBOMP_FORTRAN_MODULES_ONLY @@ -122,6 +122,8 @@ set(OPENMP_TEST_FLAGS "" CACHE STRING "Extra compiler flags to send to the test compiler.") set(OPENMP_TEST_OPENMP_FLAGS ${OPENMP_TEST_COMPILER_OPENMP_FLAGS} CACHE STRING "OpenMP compiler flag to use for testing OpenMP runtime libraries.") +set(OPENMP_TEST_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}" CACHE STRING + "Additional compiler flags to use for testing Fortran programs (e.g. additional module search paths via -fintrinsic-modules-path )") set(ENABLE_LIBOMPTARGET ON) # Currently libomptarget cannot be compiled on Windows or MacOS X. @@ -158,13 +160,15 @@ add_custom_target(install-openmp-stripped add_dependencies(install-openmp openmp) add_dependencies(install-openmp-stripped openmp) +if(LIBOMP_FORTRAN_MODULES) + add_subdirectory(module) +endif() + # Use the current compiler target to determine the appropriate runtime to build. if("${LLVM_DEFAULT_TARGET_TRIPLE}" MATCHES "^amdgcn|^nvptx|^spirv64" OR "${CMAKE_CXX_COMPILER_TARGET}" MATCHES "^amdgcn|^nvptx|^spirv64") add_subdirectory(device) else() - add_subdirectory(module) - # Build host runtime library, after LIBOMPTARGET variables are set since they # are needed to enable time profiling support in the OpenMP runtime. if(NOT LIBOMP_FORTRAN_MODULES_ONLY) diff --git a/openmp/cmake/modules/LibompCheckFortranFlag.cmake b/openmp/cmake/modules/LibompCheckFortranFlag.cmake deleted file mode 100644 index 344389f98938..000000000000 --- a/openmp/cmake/modules/LibompCheckFortranFlag.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# -#//===----------------------------------------------------------------------===// -#// -#// 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 -#// -#//===----------------------------------------------------------------------===// -# - -# Checking a fortran compiler flag -# There is no real trivial way to do this in CMake, so we implement it here -# this will have ${boolean} = TRUE if the flag succeeds, otherwise false. -function(libomp_check_fortran_flag flag boolean) - if(NOT DEFINED "${boolean}") - set(retval TRUE) - set(fortran_source -" program hello - print *, \"Hello World!\" - end program hello") - - # Compiling as a part of runtimes introduces ARCH-unknown-linux-gnu as a - # part of a working directory. So adding a guard for unknown. - set(failed_regexes "[Ee]rror;[Uu]nknown[^-];[Ss]kipping") - include(CheckFortranSourceCompiles) - check_fortran_source_compiles("${fortran_source}" ${boolean} FAIL_REGEX "${failed_regexes}") - set(${boolean} ${${boolean}} PARENT_SCOPE) - endif() -endfunction() diff --git a/openmp/cmake/modules/LibompHandleFlags.cmake b/openmp/cmake/modules/LibompHandleFlags.cmake index 980a62166dee..5d6558cc8ffc 100644 --- a/openmp/cmake/modules/LibompHandleFlags.cmake +++ b/openmp/cmake/modules/LibompHandleFlags.cmake @@ -161,17 +161,6 @@ function(libomp_get_libflags libflags) set(${libflags} ${libflags_local_list} PARENT_SCOPE) endfunction() -# Fortran flags -function(libomp_get_fflags fflags) - set(fflags_local) - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - libomp_append(fflags_local -m32 LIBOMP_HAVE_M32_FORTRAN_FLAG) - endif() - set(fflags_local ${fflags_local} ${LIBOMP_FFLAGS}) - libomp_setup_flags(fflags_local) - set(${fflags} ${fflags_local} PARENT_SCOPE) -endfunction() - # Python generate-defs.py flags (For Windows only) function(libomp_get_gdflags gdflags) set(gdflags_local) diff --git a/openmp/module/CMakeLists.txt b/openmp/module/CMakeLists.txt index 9265e70dd78c..c0a873f9be55 100644 --- a/openmp/module/CMakeLists.txt +++ b/openmp/module/CMakeLists.txt @@ -6,87 +6,33 @@ #// #//===----------------------------------------------------------------------===// -include(LibompCheckFortranFlag) +# Build the module files if a Fortran compiler is available. -set(LIBOMP_FFLAGS "" CACHE STRING - "Appended user specified Fortran compiler flags. These are only used if LIBOMP_FORTRAN_MODULES==TRUE.") - -# Enabling Fortran if it is needed -if (LIBOMP_FORTRAN_MODULES) - enable_language(Fortran) - - libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG) -endif () - -# Building the Fortran module files -# One compilation step creates both omp_lib.mod and omp_lib_kinds.mod -configure_file(omp_lib.F90.var omp_lib.F90 @ONLY) +configure_file(omp_lib.F90.var "${CMAKE_CURRENT_BINARY_DIR}/omp_lib.F90" @ONLY) configure_file(omp_lib.h.var "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h" @ONLY) -set(BUILD_FORTRAN_MODULES False) -if (LIBOMP_FORTRAN_MODULES_COMPILER) - # If libomp is built as an LLVM runtime and the flang compiler is available, - # compile the Fortran module files. - message(STATUS "configuring openmp to build Fortran module files using '${LIBOMP_FORTRAN_MODULES_COMPILER}'") - set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) - # omp_lib_kinds uses iso_c_binding, which depends on these intrinsic modules. - # List them so omp_lib.mod is regenerated when intrinsic modules change; otherwise - # stale omp_lib.mod can reference an incompatible iso_c_binding.mod (see flang - # tests that load omp_lib.mod with -J). - set(_libomp_flang_intrinsic_mod_deps "") - if(LLVM_BINARY_DIR) - set(_flang_intrinsic_mod_dir "${LLVM_BINARY_DIR}/include/flang") - list(APPEND _libomp_flang_intrinsic_mod_deps - "${_flang_intrinsic_mod_dir}/__fortran_builtins.mod" - "${_flang_intrinsic_mod_dir}/__fortran_type_info.mod" - "${_flang_intrinsic_mod_dir}/iso_c_binding.mod" - ) - endif() - add_custom_target(libomp-mod ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod" - COMMAND ${LIBOMP_FORTRAN_MODULES_COMPILER} -cpp -fsyntax-only ${LIBOMP_FORTRAN_SOURCE_FILE} "-J${CMAKE_CURRENT_BINARY_DIR}/../runtime/src" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}" ${_libomp_flang_intrinsic_mod_deps} - ) - set(BUILD_FORTRAN_MODULES True) -elseif (LIBOMP_FORTRAN_MODULES) - # The following requests explicit building of the Fortran module files - # Workaround for gfortran to build modules with the - # omp_sched_monotonic integer parameter - if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - set(ADDITIONAL_Fortran_FLAGS "-fno-range-check") - endif () - add_custom_target(libomp-mod ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod") - set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Misc") - libomp_get_fflags(LIBOMP_CONFIGURED_FFLAGS) - if (CMAKE_Fortran_COMPILER_SUPPORTS_F90) - set(LIBOMP_FORTRAN_SOURCE_FILE omp_lib.F90) - else () - message(FATAL_ERROR "Fortran module build requires Fortran 90 compiler") - endif () - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod" - COMMAND ${CMAKE_Fortran_COMPILER} -c ${ADDITIONAL_Fortran_FLAGS} - ${LIBOMP_CONFIGURED_FFLAGS} ${LIBOMP_FORTRAN_SOURCE_FILE} "-J${CMAKE_CURRENT_BINARY_DIR}/../runtime/src" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}" - ) - set_property(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src" PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "omp_lib${CMAKE_C_OUTPUT_EXTENSION}") - set(BUILD_FORTRAN_MODULES True) +# One compilation step creates both, omp_lib.mod and omp_lib_kinds.mod. Only +# these files are used, the object file itself can be discarded. +# TODO: Adding it to libomp ($) would allow implementing Fortran API in Fortran +add_library(libomp-mod OBJECT + "${CMAKE_CURRENT_BINARY_DIR}/omp_lib.F90" +) +set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Fortran Modules") + +# The following requests explicit building of the Fortran module files +# Workaround for gfortran to build modules with the +# omp_sched_monotonic integer parameter +if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") + target_compile_options(libomp-mod PRIVATE -fno-range-check) endif () +flang_module_target(libomp-mod PUBLIC) +add_dependencies(libomp-mod ${RUNTIMES_FORTRAN_BUILD_DEPS}) -if (BUILD_FORTRAN_MODULES) - set(destination "${LIBOMP_HEADERS_INSTALL_PATH}") - if (LIBOMP_MODULES_INSTALL_PATH) - set(destination "${LIBOMP_MODULES_INSTALL_PATH}") - endif () - install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.mod" - "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib_kinds.mod" - "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h" - DESTINATION ${destination} +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/../runtime/src/omp_lib.h" + DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH} COMPONENT openmp - ) -endif () +) openmp_register_meta_dep(libomp-mod) diff --git a/openmp/runtime/cmake/LibompExports.cmake b/openmp/runtime/cmake/LibompExports.cmake index 7a0fe51d9698..805f128ebef2 100644 --- a/openmp/runtime/cmake/LibompExports.cmake +++ b/openmp/runtime/cmake/LibompExports.cmake @@ -56,8 +56,8 @@ set(LIBOMP_EXPORTS_LIB_DIR "${LIBOMP_EXPORTS_DIR}/${libomp_platform}${libomp_suf # Put headers in exports/ directory post build add_custom_command(TARGET omp POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_CMN_DIR} - COMMAND ${CMAKE_COMMAND} -E copy omp.h ${LIBOMP_EXPORTS_CMN_DIR} - COMMAND ${CMAKE_COMMAND} -E copy ompx.h ${LIBOMP_EXPORTS_CMN_DIR} + COMMAND ${CMAKE_COMMAND} -E copy "${LIBOMP_HEADERS_INTDIR}/omp.h" ${LIBOMP_EXPORTS_CMN_DIR} + COMMAND ${CMAKE_COMMAND} -E copy "${LIBOMP_HEADERS_INTDIR}/ompx.h" ${LIBOMP_EXPORTS_CMN_DIR} ) if(LIBOMP_OMPT_SUPPORT) add_custom_command(TARGET omp POST_BUILD @@ -69,8 +69,8 @@ if(LIBOMP_FORTRAN_MODULES) # to omp and ensure that libomp-mod is built before by adding a dependency add_custom_command(TARGET omp POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${LIBOMP_EXPORTS_MOD_DIR} - COMMAND ${CMAKE_COMMAND} -E copy omp_lib.mod ${LIBOMP_EXPORTS_MOD_DIR} - COMMAND ${CMAKE_COMMAND} -E copy omp_lib_kinds.mod ${LIBOMP_EXPORTS_MOD_DIR} + COMMAND ${CMAKE_COMMAND} -E copy "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}/omp_lib.mod" ${LIBOMP_EXPORTS_MOD_DIR} + COMMAND ${CMAKE_COMMAND} -E copy "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}/omp_lib_kinds.mod" ${LIBOMP_EXPORTS_MOD_DIR} ) add_dependencies(omp libomp-mod) add_custom_command(TARGET omp POST_BUILD diff --git a/openmp/runtime/test/lit.cfg b/openmp/runtime/test/lit.cfg index 4885f4e2cfbe..6a63fce1b169 100644 --- a/openmp/runtime/test/lit.cfg +++ b/openmp/runtime/test/lit.cfg @@ -3,6 +3,7 @@ import os import re +import shlex import subprocess import lit.formats from lit.llvm.subst import ToolSubst @@ -51,6 +52,7 @@ if config.test_fortran_compiler: ToolSubst( "%flang", command=config.test_fortran_compiler, + extra_args=shlex.split(config.test_fortran_flags), unresolved="fatal", ), ], [config.llvm_tools_dir]) diff --git a/openmp/runtime/test/lit.site.cfg.in b/openmp/runtime/test/lit.site.cfg.in index a4d7c8d8b205..da8a12b23808 100644 --- a/openmp/runtime/test/lit.site.cfg.in +++ b/openmp/runtime/test/lit.site.cfg.in @@ -7,6 +7,7 @@ config.test_compiler_features = @OPENMP_TEST_COMPILER_FEATURES@ config.test_filecheck = "@OPENMP_FILECHECK_EXECUTABLE@" config.test_not = "@OPENMP_NOT_EXECUTABLE@" config.test_openmp_flags = "@OPENMP_TEST_OPENMP_FLAGS@" +config.test_fortran_flags = "@OPENMP_TEST_Fortran_FLAGS@" config.test_extra_flags = "@OPENMP_TEST_FLAGS@" config.libomp_obj_root = "@CMAKE_CURRENT_BINARY_DIR@" config.library_dir = "@LIBOMP_LIBRARY_DIR@" diff --git a/runtimes/cmake/config-Fortran.cmake b/runtimes/cmake/config-Fortran.cmake index f5cea1fc67e2..74fd15021f0a 100644 --- a/runtimes/cmake/config-Fortran.cmake +++ b/runtimes/cmake/config-Fortran.cmake @@ -11,18 +11,18 @@ # compiled. Contains the build targets for intrinsic modules, if necessary. # Otherweise, it is empty. # -# RUNTIMES_ENABLE_FLANG_MODULES - Whether to build Flang modules and emit them +# RUNTIMES_FORTRAN_MODULES - Whether to build Flang modules and emit them # into Flang's search path. This is a CMake CACHE option defined in # config-Fortran.cmake and default to ON iff the Fortran compiler is detected # for be a (compatible) version of Flang. In the OFF setting, modules are still # built, but not installed or emitted into a default path. # # RUNTIMES_OUTPUT_RESOURCE_MOD_DIR - Where to emit intrinsic module files in -# the build directory. Most relevant when RUNTIMES_ENABLE_FLANG_MODULES is ON. +# the build directory. Most relevant when RUNTIMES_FORTRAN_MODULES is ON. # # RUNTIMES_INSTALL_RESOURCE_MOD_PATH - Where to install intrinsic module files # in the install prefix. Relative to CMAKE_INSTALL_PREFIX. Only used when -# RUNTIMES_ENABLE_FLANG_MODULES is ON. +# RUNTIMES_FORTRAN_MODULES is ON. # Check whether the Fortran compiler already has access to builtin modules. Sets @@ -180,17 +180,14 @@ endif () # Check whether modules files are compatible with our version of Flang. -set(RUNTIMES_ENABLE_FLANG_MODULES_default OFF) -if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang") - set(RUNTIMES_ENABLE_FLANG_MODULES_default ON) -else () - set(RUNTIMES_ENABLE_FLANG_MODULES_default OFF) +set(RUNTIMES_FORTRAN_MODULES_default OFF) +if (RUNTIMES_ENABLE_FORTRAN AND CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang") + set(RUNTIMES_FORTRAN_MODULES_default ON) endif () -option(RUNTIMES_ENABLE_FLANG_MODULES "Make Fortran .mod files available to Flang; should only be enabled if compiling with a matching version of Flang" "${RUNTIMES_ENABLE_FLANG_MODULES_default}") - +option(RUNTIMES_FORTRAN_MODULES "Make Fortran .mod files available to Flang; should only be enabled if compiling with a matching version of Flang" "${RUNTIMES_FORTRAN_MODULES_default}") # Determine the paths for Fortran .mod files. -if (RUNTIMES_ENABLE_FLANG_MODULES) +if (RUNTIMES_FORTRAN_MODULES) # Flang expects its builtin modules in Clang's resource directory. get_toolchain_module_subdir(toolchain_mod_subdir) extend_path(RUNTIMES_OUTPUT_RESOURCE_MOD_DIR "${RUNTIMES_OUTPUT_RESOURCE_DIR}" "${toolchain_mod_subdir}") @@ -261,7 +258,15 @@ function (flang_module_target tgtname) Fortran_MODULE_DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}" ) else () - # Keep non-public modules where CMake would put them normally; - # Modules of different target must not overwrite each other. + # Modules of different targets must not overwrite each other. + # Ideally, we would use $ but + # Fortran_MODULE_DIRECTORY does not support generator expressions. + # Not defining Fortran_MODULE_DIRECTORY at all would but it into + # ${CMAKE_CURRENT_BINARY_DIR} where modules with the same name but compiled + # by different targets would clash. + set_target_properties(${tgtname} + PROPERTIES + Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${tgtname}.dir/${CMAKE_CFG_INTDIR}" + ) endif () endfunction ()