mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[Flang] Move builtin .mod generation into runtimes (#137828)
Move building the .mod files from openmp/flang to openmp/flang-rt using a shared mechanism. Motivations to do so are: 1. Most modules are target-dependent and need to be re-compiled for each target separately, which is something the LLVM_ENABLE_RUNTIMES system already does. Prime example is `iso_c_binding.mod` which encodes the target's ABI. Most other modules have `#ifdef`-enclosed code as well. 2. CMake has support for Fortran that we should use. Among other things, it automatically determines module dependencies so there is no need to hardcode them in the CMakeLists.txt. 3. It allows using Fortran itself to implement Flang-RT. Currently, only `iso_fortran_env_impl.f90` emits object files that are needed by Fortran applications (#89403). The workaround of #95388 could be reverted. Some new dependencies come into play: * openmp depends on flang-rt for building `lib_omp.mod` and `lib_omp_kinds.mod`. Currently, if flang-rt is not found then the modules are not built. * check-flang depends on flang-rt: If not found, the majority of tests are disabled. If not building in a bootstrpping build, the location of the module files can be pointed to using `-DFLANG_INTRINSIC_MODULES_DIR=<path>`, e.g. in a flang-standalone build. Alternatively, the test needing any of the intrinsic modules could be marked with `REQUIRES: flangrt-modules`. * check-flang depends on openmp: Not a change; tests requiring `lib_omp.mod` and `lib_omp_kinds.mod` those are already marked with `openmp_runtime`. As intrinsic are now specific to the target, their location is moved from `include/flang` to `<resource-dir>/finclude/flang/<triple>`. The mechnism to compute the location have been moved from flang-rt (previously used to compute the location of `libflang_rt.*.a`) to common locations in `cmake/GetToolchainDirs.cmake` and `runtimes/CMakeLists.txt` so they can be used by both, openmp and flang-rt. Potentially the mechnism could also be shared by other libraries such as compiler-rt. `finclude` was chosen because `gfortran` uses it as well and avoids misuse such as `#include <flang/iso_c_binding.mod>`. The search location is now determined by `ToolChain` in the driver, instead of by the frontend. Now the driver adds `-fintrinsic-module-path` for that location to the frontend call (Just like gfortran does). `-fintrinsic-module-path` had to be fixed for this because ironically it was only added to `searchDirectories`, but not `intrinsicModuleDirectories_`. Since the driver determines the location, tests invoking `flang -fc1` and `bbc` must also be passed the location by llvm-lit. This works like llvm-lit does for finding the include dirs for Clang using `-print-file-name=...`.
This commit is contained in:
@@ -538,6 +538,10 @@ public:
|
||||
// Returns Triple without the OSs version.
|
||||
llvm::Triple getTripleWithoutOSVersion() const;
|
||||
|
||||
/// Returns the target-specific path for Flang's intrinsic modules in the
|
||||
/// resource directory if it exists.
|
||||
std::optional<std::string> getDefaultIntrinsicModuleDir() const;
|
||||
|
||||
// Returns the target specific runtime path if it exists.
|
||||
std::optional<std::string> getRuntimePath() const;
|
||||
|
||||
|
||||
@@ -6082,7 +6082,7 @@ def prebind : Flag<["-"], "prebind">;
|
||||
def preload : Flag<["-"], "preload">;
|
||||
def print_file_name_EQ : Joined<["-", "--"], "print-file-name=">,
|
||||
HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">,
|
||||
Visibility<[ClangOption, CLOption]>;
|
||||
Visibility<[ClangOption, FlangOption, CLOption]>;
|
||||
def print_ivar_layout : Flag<["-"], "print-ivar-layout">,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Enable Objective-C Ivar layout bitmap print trace">,
|
||||
|
||||
@@ -6602,6 +6602,17 @@ std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const {
|
||||
if (llvm::sys::fs::exists(Twine(P)))
|
||||
return std::string(P);
|
||||
|
||||
// With Flang, also look for instrinsic modules
|
||||
if (IsFlangMode()) {
|
||||
if (std::optional<std::string> IntrPath =
|
||||
TC.getDefaultIntrinsicModuleDir()) {
|
||||
SmallString<128> P(*IntrPath);
|
||||
llvm::sys::path::append(P, Name);
|
||||
if (llvm::sys::fs::exists(Twine(P)))
|
||||
return std::string(P);
|
||||
}
|
||||
}
|
||||
|
||||
SmallString<128> D(Dir);
|
||||
llvm::sys::path::append(D, "..", Name);
|
||||
if (llvm::sys::fs::exists(Twine(D)))
|
||||
|
||||
@@ -1020,6 +1020,12 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> ToolChain::getDefaultIntrinsicModuleDir() const {
|
||||
SmallString<128> P(D.ResourceDir);
|
||||
llvm::sys::path::append(P, "finclude", "flang");
|
||||
return getTargetSubDirPath(P);
|
||||
}
|
||||
|
||||
std::optional<std::string> ToolChain::getRuntimePath() const {
|
||||
SmallString<128> P(D.ResourceDir);
|
||||
llvm::sys::path::append(P, "lib");
|
||||
|
||||
@@ -1060,6 +1060,14 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
CmdArgs.push_back("-resource-dir");
|
||||
CmdArgs.push_back(D.ResourceDir.c_str());
|
||||
|
||||
// Default intrinsic module dirs must be added after any user-provided
|
||||
// -fintrinsic-modules-path to have lower precedence
|
||||
if (std::optional<std::string> IntrModPath =
|
||||
TC.getDefaultIntrinsicModuleDir()) {
|
||||
CmdArgs.push_back("-fintrinsic-modules-path");
|
||||
CmdArgs.push_back(Args.MakeArgString(*IntrModPath));
|
||||
}
|
||||
|
||||
// Offloading related options
|
||||
addOffloadOptions(C, Inputs, JA, Args, CmdArgs);
|
||||
|
||||
|
||||
@@ -47,6 +47,17 @@ function (get_toolchain_library_subdir outvar)
|
||||
endfunction ()
|
||||
|
||||
|
||||
# Corresponds to Flang's ToolChain::getDefaultIntrinsicModuleDir().
|
||||
function (get_toolchain_module_subdir outvar)
|
||||
set(outval "finclude/flang")
|
||||
|
||||
get_toolchain_arch_dirname(arch_dirname)
|
||||
set(outval "${outval}/${arch_dirname}")
|
||||
|
||||
set(${outvar} "${outval}" PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
|
||||
# Corresponds to Clang's ToolChain::getOSLibName(). Adapted from Compiler-RT.
|
||||
function (get_toolchain_os_dirname outvar)
|
||||
if (ANDROID)
|
||||
@@ -23,40 +23,6 @@ set(FLANG_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
set(FLANG_RT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set(FLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../flang")
|
||||
|
||||
# CMake 3.24 is the first version of CMake that directly recognizes Flang.
|
||||
# LLVM's requirement is only CMake 3.20, teach CMake 3.20-3.23 how to use Flang.
|
||||
if (CMAKE_VERSION VERSION_LESS "3.24")
|
||||
cmake_path(GET CMAKE_Fortran_COMPILER STEM _Fortran_COMPILER_STEM)
|
||||
if (_Fortran_COMPILER_STEM STREQUAL "flang-new" OR _Fortran_COMPILER_STEM STREQUAL "flang")
|
||||
include(CMakeForceCompiler)
|
||||
CMAKE_FORCE_Fortran_COMPILER("${CMAKE_Fortran_COMPILER}" "LLVMFlang")
|
||||
|
||||
set(CMAKE_Fortran_COMPILER_ID "LLVMFlang")
|
||||
set(CMAKE_Fortran_COMPILER_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
|
||||
|
||||
set(CMAKE_Fortran_SUBMODULE_SEP "-")
|
||||
set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
|
||||
|
||||
set(CMAKE_Fortran_PREPROCESS_SOURCE
|
||||
"<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
|
||||
|
||||
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
|
||||
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
|
||||
|
||||
set(CMAKE_Fortran_MODDIR_FLAG "-module-dir")
|
||||
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
|
||||
set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72")
|
||||
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=")
|
||||
|
||||
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
|
||||
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
|
||||
endif ()
|
||||
endif ()
|
||||
enable_language(Fortran)
|
||||
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH
|
||||
"${FLANG_RT_SOURCE_DIR}/cmake/modules"
|
||||
@@ -65,69 +31,24 @@ list(APPEND CMAKE_MODULE_PATH
|
||||
include(AddFlangRT)
|
||||
include(GetToolchainDirs)
|
||||
include(FlangCommon)
|
||||
include(FlangRTIntrospection)
|
||||
include(HandleCompilerRT)
|
||||
include(ExtendPath)
|
||||
include(CheckFortranSourceCompiles)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
|
||||
############################
|
||||
# Build Mode Introspection #
|
||||
############################
|
||||
|
||||
# Determine whether we are in the runtimes/runtimes-bins directory of a
|
||||
# bootstrap build.
|
||||
set(LLVM_TREE_AVAILABLE OFF)
|
||||
if (LLVM_LIBRARY_OUTPUT_INTDIR AND LLVM_RUNTIME_OUTPUT_INTDIR AND PACKAGE_VERSION)
|
||||
set(LLVM_TREE_AVAILABLE ON)
|
||||
endif()
|
||||
|
||||
# Path to LLVM development tools (FileCheck, llvm-lit, not, ...)
|
||||
set(LLVM_TOOLS_DIR "${LLVM_BINARY_DIR}/bin")
|
||||
|
||||
# Determine build and install paths.
|
||||
# The build path is absolute, but the install dir is relative, CMake's install
|
||||
# command has to apply CMAKE_INSTALL_PREFIX itself.
|
||||
get_toolchain_library_subdir(toolchain_lib_subdir)
|
||||
if (LLVM_TREE_AVAILABLE)
|
||||
# In a bootstrap build emit the libraries into a default search path in the
|
||||
# build directory of the just-built compiler. This allows using the
|
||||
# just-built compiler without specifying paths to runtime libraries.
|
||||
#
|
||||
# Despite Clang in the name, get_clang_resource_dir does not depend on Clang
|
||||
# being added to the build. Flang uses the same resource dir as clang.
|
||||
include(GetClangResourceDir)
|
||||
get_clang_resource_dir(FLANG_RT_OUTPUT_RESOURCE_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")
|
||||
get_clang_resource_dir(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT)
|
||||
# Fortran compiler not optional for building Flang-RT
|
||||
enable_language(Fortran)
|
||||
|
||||
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
|
||||
else ()
|
||||
# In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be
|
||||
# read-only and/or shared by multiple runtimes with different build
|
||||
# configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
|
||||
# non-toolchain library.
|
||||
# For the install prefix, still use the resource dir assuming that Flang will
|
||||
# be installed there using the same prefix. This is to not have a difference
|
||||
# between bootstrap and standalone runtimes builds.
|
||||
set(FLANG_RT_OUTPUT_RESOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
set(FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
|
||||
|
||||
extend_path(FLANG_RT_OUTPUT_RESOURCE_LIB_DIR "${FLANG_RT_OUTPUT_RESOURCE_DIR}" "lib${LLVM_LIBDIR_SUFFIX}")
|
||||
endif ()
|
||||
set(FLANG_RT_INSTALL_RESOURCE_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH_DEFAULT}"
|
||||
CACHE PATH "Path to install runtime libraries to (default: clang resource dir)")
|
||||
extend_path(FLANG_RT_INSTALL_RESOURCE_LIB_PATH "${FLANG_RT_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")
|
||||
cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_DIR)
|
||||
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_PATH)
|
||||
# FIXME: For the libflang_rt.so, the toolchain resource lib dir is not a good
|
||||
# destination because it is not a ld.so default search path.
|
||||
# The machine where the executable is eventually executed may not be the
|
||||
# machine where the Flang compiler and its resource dir is installed, so
|
||||
# setting RPath by the driver is not an solution. It should belong into
|
||||
# /usr/lib/<triple>/libflang_rt.so, like e.g. libgcc_s.so.
|
||||
# But the linker as invoked by the Flang driver also requires
|
||||
# libflang_rt.so to be found when linking and the resource lib dir is
|
||||
# the only reliable location.
|
||||
cmake_path(NORMAL_PATH FLANG_RT_OUTPUT_RESOURCE_LIB_DIR)
|
||||
cmake_path(NORMAL_PATH FLANG_RT_INSTALL_RESOURCE_LIB_PATH)
|
||||
flang_module_fortran_enable()
|
||||
|
||||
|
||||
#################
|
||||
@@ -234,6 +155,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)
|
||||
|
||||
@@ -190,6 +190,12 @@ function (add_flangrt_library name)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (build_object)
|
||||
add_library(${name}.compile ALIAS "${name_object}")
|
||||
else ()
|
||||
add_library(${name}.compile ALIAS "${default_target}")
|
||||
endif ()
|
||||
|
||||
foreach (tgtname IN LISTS libtargets)
|
||||
if (NOT WIN32)
|
||||
# Use same stem name for .a and .so. Common in UNIX environments.
|
||||
@@ -219,6 +225,17 @@ 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)
|
||||
|
||||
target_compile_options(${tgtname} PRIVATE
|
||||
# Always enable preprocessor regardless of file extention
|
||||
"$<$<COMPILE_LANGUAGE:Fortran>:-cpp>"
|
||||
|
||||
# Missing type descriptors are expected for intrinsic modules
|
||||
"$<$<COMPILE_LANGUAGE:Fortran>:SHELL:-mmlir;SHELL:-ignore-missing-type-desc>"
|
||||
|
||||
# Flang bug workaround: Reformating of cooked token buffer causes identifier to be split between lines
|
||||
"$<$<COMPILE_LANGUAGE:Fortran>:SHELL:-Xflang;SHELL:-fno-reformat>"
|
||||
)
|
||||
|
||||
# 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.
|
||||
@@ -226,6 +243,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
|
||||
@@ -344,13 +365,13 @@ function (add_flangrt_library name)
|
||||
if (ARG_INSTALL_WITH_TOOLCHAIN)
|
||||
set_target_properties(${tgtname}
|
||||
PROPERTIES
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${FLANG_RT_OUTPUT_RESOURCE_LIB_DIR}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_LIB_DIR}"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_LIB_DIR}"
|
||||
)
|
||||
|
||||
install(TARGETS ${tgtname}
|
||||
ARCHIVE DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
|
||||
LIBRARY DESTINATION "${FLANG_RT_INSTALL_RESOURCE_LIB_PATH}"
|
||||
ARCHIVE DESTINATION "${RUNTIMES_INSTALL_RESOURCE_LIB_PATH}"
|
||||
LIBRARY DESTINATION "${RUNTIMES_INSTALL_RESOURCE_LIB_PATH}"
|
||||
)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -88,16 +88,16 @@ macro(enable_omp_offload_compilation name files)
|
||||
"${FLANG_RT_DEVICE_ARCHITECTURES}"
|
||||
)
|
||||
|
||||
set(OMP_COMPILE_OPTIONS
|
||||
set(OMP_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:C,CXX>:
|
||||
-fopenmp
|
||||
-fvisibility=hidden
|
||||
-fopenmp-cuda-mode
|
||||
--offload-arch=${compile_for_architectures}
|
||||
# Force LTO for the device part.
|
||||
-foffload-lto
|
||||
)
|
||||
set_source_files_properties(${files} PROPERTIES COMPILE_OPTIONS
|
||||
"${OMP_COMPILE_OPTIONS}"
|
||||
>)
|
||||
set_property(SOURCE ${files} APPEND
|
||||
PROPERTY COMPILE_DEFINITIONS ${OMP_COMPILE_OPTIONS}
|
||||
)
|
||||
target_link_options(${name}.static PUBLIC ${OMP_COMPILE_OPTIONS})
|
||||
|
||||
@@ -105,6 +105,12 @@ macro(enable_omp_offload_compilation name files)
|
||||
set_source_files_properties(${files}
|
||||
PROPERTIES COMPILE_DEFINITIONS OMP_OFFLOAD_BUILD
|
||||
)
|
||||
|
||||
# If building flang-rt together with libomp, ensure that libomp is built first and found because -fopenmp will try to link it.
|
||||
if (TARGET omp)
|
||||
add_dependencies(${name} omp)
|
||||
target_link_options(${name}.static PUBLIC "-L$<TARGET_FILE_DIR:omp>")
|
||||
endif ()
|
||||
else()
|
||||
message(FATAL_ERROR
|
||||
"Flang-rt build with OpenMP offload is not supported for these compilers:\n"
|
||||
|
||||
37
flang-rt/cmake/modules/FlangRTIntrospection.cmake
Normal file
37
flang-rt/cmake/modules/FlangRTIntrospection.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
#===-- cmake/modules/FlangRTIntrospection.cmake ----------------------------===#
|
||||
#
|
||||
# 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
|
||||
#
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
|
||||
# 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.
|
||||
#
|
||||
# * Does not work with Flang and CMake < 3.24
|
||||
#
|
||||
# * This is intentionally wrapped in a function to get its own namespace for
|
||||
# CMAKE_REQUIRED_FLAGS and CMAKE_TRY_COMPILE_TARGET_TYPE. In particular,
|
||||
# cmake_pop_check_state() does not reset CMAKE_TRY_COMPILE_TARGET_TYPE,
|
||||
# causing later try_compile invocations to fail. If you see
|
||||
# enable_language(CUDA) failing because CMAKE_RANLIB is empty, this is the
|
||||
# reason.
|
||||
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 ()
|
||||
@@ -12,6 +12,13 @@ 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
|
||||
)
|
||||
|
||||
|
||||
# List of files that are buildable for all devices.
|
||||
set(supported_sources
|
||||
${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp
|
||||
@@ -73,7 +80,16 @@ set(supported_sources
|
||||
|
||||
# List of source not used for GPU offloading.
|
||||
set(host_sources
|
||||
${FLANG_SOURCE_DIR}/module/iso_fortran_env_impl.f90
|
||||
__fortran_ieee_exceptions.f90
|
||||
__fortran_type_info.f90
|
||||
iso_fortran_env.f90
|
||||
ieee_arithmetic.f90
|
||||
ieee_exceptions.f90
|
||||
ieee_features.f90
|
||||
iso_c_binding.f90
|
||||
iso_fortran_env_impl.f90
|
||||
iso_fortran_env.f90
|
||||
|
||||
command.cpp
|
||||
complex-powi.cpp
|
||||
complex-reduction.c
|
||||
@@ -88,8 +104,32 @@ set(host_sources
|
||||
temporary-stack.cpp
|
||||
time-intrinsic.cpp
|
||||
unit-map.cpp
|
||||
|
||||
__cuda_device.f90
|
||||
cooperative_groups.f90
|
||||
cudadevice.f90
|
||||
)
|
||||
|
||||
if (LLVM_TARGET_TRIPLE MATCHES "^ppc|^powerpc")
|
||||
list(APPEND intrinsics_sources
|
||||
__ppc_types.f90
|
||||
)
|
||||
list(APPEND host_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
|
||||
cudadevice.f90
|
||||
APPEND PROPERTY
|
||||
COMPILE_OPTIONS --offload-host-only -xcuda
|
||||
)
|
||||
|
||||
|
||||
# Sources that can be compiled directly for the GPU.
|
||||
set(gpu_sources
|
||||
${FLANG_SOURCE_DIR}/lib/Decimal/binary-to-decimal.cpp
|
||||
@@ -175,19 +215,42 @@ else ()
|
||||
set(f128_sources "")
|
||||
endif ()
|
||||
|
||||
if ("${LLVM_RUNTIMES_TARGET}" MATCHES "^amdgcn|^nvptx")
|
||||
if (LLVM_RUNTIMES_TARGET MATCHES "^amdgcn|^nvptx")
|
||||
set(sources ${gpu_sources})
|
||||
elseif(FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "CUDA")
|
||||
set(sources ${supported_sources})
|
||||
else ()
|
||||
set(sources ${supported_sources} ${host_sources} ${f128_sources})
|
||||
endif ()
|
||||
|
||||
|
||||
# check-flang depends on this to build intrinsic modules
|
||||
if (NOT TARGET flang-rt-mod)
|
||||
add_custom_target(flang-rt-mod)
|
||||
endif ()
|
||||
|
||||
if (NOT WIN32)
|
||||
# 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.intrinsics.obj OBJECT
|
||||
${intrinsics_sources}
|
||||
)
|
||||
|
||||
# This barrier exists to force all of the intrinsic modules of
|
||||
# flang_rt.intrinsics.obj to be built before anything that depends on it.
|
||||
# Without it, CMake/Ninja seem to think that the modules of
|
||||
# flang_rt.intrinsics.obj can be built concurrently to those in
|
||||
# flang_rt.runtime.
|
||||
add_custom_target(flang_rt.intrinsics
|
||||
COMMENT "Intrinsic module dependency barrier"
|
||||
)
|
||||
add_dependencies(flang_rt.intrinsics flang_rt.intrinsics.obj)
|
||||
|
||||
add_flangrt_library(flang_rt.runtime STATIC SHARED
|
||||
${sources}
|
||||
LINK_LIBRARIES ${Backtrace_LIBRARY}
|
||||
${sources} $<TARGET_OBJECTS:flang_rt.intrinsics.obj>
|
||||
LINK_LIBRARIES flang_rt.intrinsics.obj ${Backtrace_LIBRARY}
|
||||
INSTALL_WITH_TOOLCHAIN
|
||||
ADDITIONAL_HEADERS ${public_headers} ${private_headers}
|
||||
)
|
||||
@@ -198,6 +261,13 @@ if (NOT WIN32)
|
||||
# Select a default runtime, which is used for unit and regression tests.
|
||||
get_target_property(default_target flang_rt.runtime.default ALIASED_TARGET)
|
||||
add_library(flang_rt.runtime.unittest ALIAS "${default_target}")
|
||||
|
||||
# Select a target that compiles the sources to build the public module files.
|
||||
get_target_property(compile_target flang_rt.runtime.compile ALIASED_TARGET)
|
||||
flang_module_target(flang_rt.intrinsics.obj PUBLIC)
|
||||
flang_module_target(${compile_target} PUBLIC)
|
||||
add_dependencies(${compile_target} flang_rt.intrinsics)
|
||||
add_dependencies(flang-rt-mod flang_rt.intrinsics ${compile_target})
|
||||
else()
|
||||
# Target for building all versions of the runtime
|
||||
add_custom_target(flang_rt.runtime)
|
||||
@@ -205,12 +275,23 @@ else()
|
||||
|
||||
function (add_win_flangrt_runtime libtype suffix msvc_lib)
|
||||
set(name "flang_rt.runtime.${suffix}")
|
||||
|
||||
add_flangrt_library(${name}.intrinsics.obj OBJECT
|
||||
${intrinsics_sources}
|
||||
)
|
||||
add_custom_target(${name}.intrinsics
|
||||
COMMAND echo "${name} Dependency barrier"
|
||||
COMMENT "Intrinsic module dependency barrier"
|
||||
)
|
||||
add_dependencies(${name}.intrinsics ${name}.intrinsics.obj)
|
||||
|
||||
add_flangrt_library(${name} ${libtype}
|
||||
${sources}
|
||||
${sources} $<TARGET_OBJECTS:${name}.intrinsics.obj>
|
||||
${ARGN}
|
||||
LINK_LIBRARIES ${Backtrace_LIBRARY}
|
||||
LINK_LIBRARIES ${name}.intrinsics.obj ${Backtrace_LIBRARY}
|
||||
ADDITIONAL_HEADERS ${public_headers} ${private_headers}
|
||||
)
|
||||
get_target_property(compile_target ${name}.compile ALIASED_TARGET)
|
||||
|
||||
if (msvc_lib)
|
||||
set_target_properties(${name}
|
||||
@@ -220,11 +301,19 @@ else()
|
||||
endif ()
|
||||
|
||||
# Setting an unique Fortran_MODULE_DIRECTORY is required for each variant to
|
||||
# write a different .mod file.
|
||||
set_target_properties(${name}
|
||||
PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY "module.${suffix}"
|
||||
)
|
||||
# write a different .mod file. One of them has to be selected to be the
|
||||
# public module that is to be installed. We select the first.
|
||||
if (_has_public_intrinsics)
|
||||
set(is_public "")
|
||||
else ()
|
||||
set(is_public PUBLIC)
|
||||
add_dependencies(flang-rt-mod ${name}.intrinsics ${compile_target})
|
||||
set(_has_public_intrinsics "YES" PARENT_SCOPE)
|
||||
endif ()
|
||||
|
||||
flang_module_target(${name}.intrinsics.obj ${is_public})
|
||||
flang_module_target(${compile_target} ${is_public})
|
||||
add_dependencies(${compile_target} ${name}.intrinsics)
|
||||
|
||||
enable_cuda_compilation(${name} "${supported_sources}")
|
||||
enable_omp_offload_compilation(${name} "${supported_sources}")
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
@@ -6,7 +6,7 @@ config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
|
||||
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 = "@FLANG_RT_OUTPUT_RESOURCE_LIB_DIR@"
|
||||
config.flang_rt_output_resource_lib_dir = "@RUNTIMES_OUTPUT_RESOURCE_LIB_DIR@"
|
||||
config.flang_rt_experimental_offload_support = "@FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT@"
|
||||
config.cc = "@CMAKE_C_COMPILER@"
|
||||
config.flang = "@CMAKE_Fortran_COMPILER@"
|
||||
|
||||
@@ -49,9 +49,8 @@ function(add_flangrt_unittest_offload_properties target)
|
||||
# FIXME: replace 'native' in --offload-arch option with the list
|
||||
# of targets that Fortran Runtime was built for.
|
||||
if (FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT STREQUAL "OpenMP")
|
||||
set_target_properties(${target}
|
||||
PROPERTIES LINK_OPTIONS
|
||||
"-fopenmp;--offload-arch=native"
|
||||
set_property(TARGET ${target} APPEND
|
||||
PROPERTY LINK_OPTIONS -fopenmp --offload-arch=native
|
||||
)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -92,6 +92,10 @@ class CompilerInvocation : public CompilerInvocationBase {
|
||||
// intrinsic of iso_fortran_env.
|
||||
std::string allCompilerInvocOpts;
|
||||
|
||||
/// Location of the resource directory containing files specific to this
|
||||
/// instance/version of Flang.
|
||||
std::string resourceDir;
|
||||
|
||||
/// Semantic options
|
||||
// TODO: Merge with or translate to frontendOpts. We shouldn't need two sets
|
||||
// of options.
|
||||
@@ -177,6 +181,9 @@ public:
|
||||
getSemanticsCtx(Fortran::parser::AllCookedSources &allCookedSources,
|
||||
const llvm::TargetMachine &);
|
||||
|
||||
std::string &getResourceDir() { return resourceDir; }
|
||||
const std::string &getResourceDir() const { return resourceDir; }
|
||||
|
||||
std::string &getModuleDir() { return moduleDir; }
|
||||
const std::string &getModuleDir() const { return moduleDir; }
|
||||
|
||||
|
||||
@@ -885,16 +885,6 @@ static bool parseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
|
||||
return diags.getNumErrors() == numErrorsBefore;
|
||||
}
|
||||
|
||||
// Generate the path to look for intrinsic modules
|
||||
static std::string getIntrinsicDir(const char *argv) {
|
||||
// TODO: Find a system independent API
|
||||
llvm::SmallString<128> driverPath;
|
||||
driverPath.assign(llvm::sys::fs::getMainExecutable(argv, nullptr));
|
||||
llvm::sys::path::remove_filename(driverPath);
|
||||
driverPath.append("/../include/flang/");
|
||||
return std::string(driverPath);
|
||||
}
|
||||
|
||||
// Generate the path to look for OpenMP headers
|
||||
static std::string getOpenMPHeadersDir(const char *argv) {
|
||||
llvm::SmallString<128> includePath;
|
||||
@@ -1568,6 +1558,14 @@ bool CompilerInvocation::createFromArgs(
|
||||
success = false;
|
||||
}
|
||||
|
||||
// User-specified or default resource dir
|
||||
if (const llvm::opt::Arg *a =
|
||||
args.getLastArg(clang::options::OPT_resource_dir))
|
||||
invoc.resourceDir = a->getValue();
|
||||
else
|
||||
invoc.resourceDir = clang::driver::Driver::GetResourcesPath(
|
||||
llvm::sys::fs::getMainExecutable(argv0, nullptr));
|
||||
|
||||
// -flang-experimental-hlfir
|
||||
if (args.hasArg(clang::options::OPT_flang_experimental_hlfir) ||
|
||||
args.hasArg(clang::options::OPT_emit_hlfir)) {
|
||||
@@ -1834,9 +1832,11 @@ void CompilerInvocation::setFortranOpts() {
|
||||
preprocessorOptions.searchDirectoriesFromIntrModPath.begin(),
|
||||
preprocessorOptions.searchDirectoriesFromIntrModPath.end());
|
||||
|
||||
// Add the default intrinsic module directory
|
||||
fortranOptions.intrinsicModuleDirectories.emplace_back(
|
||||
getIntrinsicDir(getArgv0()));
|
||||
// Add the ordered list of -fintrinsic-modules-path
|
||||
fortranOptions.intrinsicModuleDirectories.insert(
|
||||
fortranOptions.intrinsicModuleDirectories.end(),
|
||||
preprocessorOptions.searchDirectoriesFromIntrModPath.begin(),
|
||||
preprocessorOptions.searchDirectoriesFromIntrModPath.end());
|
||||
|
||||
// Add the directory supplied through -J/-module-dir to the list of search
|
||||
// directories
|
||||
|
||||
@@ -621,12 +621,15 @@ bool Semantics::Perform() {
|
||||
const auto *frontModule{std::get_if<common::Indirection<parser::Module>>(
|
||||
&program_.v.front().u)};
|
||||
if (frontModule &&
|
||||
(std::get<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
|
||||
.statement.v.source == "__fortran_builtins" ||
|
||||
std::get<parser::Statement<parser::ModuleStmt>>(
|
||||
frontModule->value().t)
|
||||
.statement.v.source == "__ppc_types")) {
|
||||
std::get<parser::Statement<parser::ModuleStmt>>(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<parser::Statement<parser::ModuleStmt>>(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<parser::Statement<parser::ModuleStmt>>(frontModule->value().t)
|
||||
.statement.v.source == "__ppc_intrinsics" ||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
DisableFormat: true
|
||||
@@ -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=<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_BUILD_EXAMPLES
|
||||
LLVM_BYE_LINK_INTO_TOOLS
|
||||
LLVM_ENABLE_PLUGINS
|
||||
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_BUILD_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})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
! DUMMY module
|
||||
! Added for testing purposes. The contents of this file are currently not relevant.
|
||||
! Using this file will cause an error because of missing checksum
|
||||
module ieee_arithmetic
|
||||
type::ieee_round_type
|
||||
integer(1),private::mode=0_1
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
! DUMMY module
|
||||
! Added for testing purposes. The contents of this file are currently not relevant.
|
||||
! Using this file will cause an error because of missing checksum
|
||||
module iso_fortran_env
|
||||
use __fortran_builtins,only:event_type=>__builtin_event_type
|
||||
use __fortran_builtins,only:lock_type=>__builtin_lock_type
|
||||
|
||||
55
flang/test/Driver/intrinsic-module-path.F90
Normal file
55
flang/test/Driver/intrinsic-module-path.F90
Normal file
@@ -0,0 +1,55 @@
|
||||
! Ensure argument -fintrinsic-modules-path works as expected.
|
||||
|
||||
!-----------------------------------------
|
||||
! FLANG DRIVER
|
||||
!-----------------------------------------
|
||||
! NOTE: Depending on how Flang is built, the default intrinsics may have higher
|
||||
! or lower priority than -fintrinsic-modules-path added here. Using
|
||||
! basictestmoduleone.mod from Inputs/module-dir/ will trigger an error.
|
||||
|
||||
! RUN: %flang -fsyntax-only -### %s 2>&1 | FileCheck %s --check-prefix=DEFAULTPATH
|
||||
|
||||
! RUN: %flang -fsyntax-only -DINTRINSICS_DEFAULT %s
|
||||
! RUN: not %flang -fsyntax-only -DINTRINSICS_INPUTONE %s 2>&1 | FileCheck %s --check-prefix=NOINPUTONE
|
||||
! RUN: not %flang -fsyntax-only -DINTRINSICS_INPUTTWO %s 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO
|
||||
! RUN: %flang -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ %s
|
||||
! RUN: %flang -fsyntax-only -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/ %s
|
||||
! RUN: %flang -fsyntax-only -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/ -fintrinsic-modules-path=%S/Inputs/module-dir/ %s
|
||||
! RUN: not %flang -fsyntax-only -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir/ -fintrinsic-modules-path=%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE
|
||||
|
||||
|
||||
!-----------------------------------------
|
||||
! FLANG FRONTEND (flang -fc1)
|
||||
!-----------------------------------------
|
||||
! NOTE: %flang_cc1 the default intrinsics path always has higher priority than
|
||||
! -fintrinsic-modules-path added here. Accidentally using
|
||||
! ieee_arithmetic/iso_fortran_env from the Inputs/ directory will trigger
|
||||
! an error (e.g. when the default intrinsics dir is empty).
|
||||
|
||||
! RUN: %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT %s
|
||||
! RUN: not %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTONE %s 2>&1 | FileCheck %s --check-prefix=NOINPUTONE
|
||||
! RUN: not %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO %s 2>&1 | FileCheck %s --check-prefix=NOINPUTTWO
|
||||
! RUN: %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir %s
|
||||
! RUN: %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTONE -fintrinsic-modules-path=%S/Inputs/ %s
|
||||
! RUN: %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/ -fintrinsic-modules-path=%S/Inputs/module-dir/ %s
|
||||
! RUN: not %flang_fc1 -fsyntax-only -DINTRINSICS_DEFAULT -DINTRINSICS_INPUTONE -DINTRINSICS_INPUTTWO -fintrinsic-modules-path=%S/Inputs/module-dir -fintrinsic-modules-path=%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=WRONGINPUTONE
|
||||
|
||||
|
||||
! DEFAULTPATH: flang{{.*}}-fc1{{.*}}-fintrinsic-modules-path
|
||||
|
||||
! NOINPUTONE: Source file 'basictestmoduleone.mod' was not found
|
||||
! NOINPUTTWO: Source file 'basictestmoduletwo.mod' was not found
|
||||
! WRONGINPUTONE: 't1' not found in module 'basictestmoduleone'
|
||||
|
||||
program test_intrinsic_module_path
|
||||
#ifdef INTRINSICS_DEFAULT
|
||||
use ieee_arithmetic, only: ieee_round_type
|
||||
use iso_fortran_env, only: team_type, event_type, lock_type
|
||||
#endif
|
||||
#ifdef INTRINSICS_INPUTONE
|
||||
use basictestmoduleone, only: t1
|
||||
#endif
|
||||
#ifdef INTRINSICS_INPUTTWO
|
||||
use basictestmoduletwo, only: t2
|
||||
#endif
|
||||
end program
|
||||
@@ -1,23 +0,0 @@
|
||||
! Ensure argument -fintrinsic-modules-path works as expected.
|
||||
! WITHOUT the option, the default location for the module is checked and no error generated.
|
||||
! With the option GIVEN, the module with the same name is PREPENDED, and considered over the
|
||||
! default one, causing a CHECKSUM error.
|
||||
|
||||
!-----------------------------------------
|
||||
! FRONTEND FLANG DRIVER (flang -fc1)
|
||||
!-----------------------------------------
|
||||
! RUN: %flang_fc1 -fsyntax-only %s 2>&1 | FileCheck %s --allow-empty --check-prefix=WITHOUT
|
||||
! RUN: not %flang_fc1 -fsyntax-only -fintrinsic-modules-path %S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=GIVEN
|
||||
! RUN: not %flang_fc1 -fsyntax-only -fintrinsic-modules-path=%S/Inputs/ %s 2>&1 | FileCheck %s --check-prefix=GIVEN
|
||||
|
||||
! WITHOUT-NOT: 'ieee_arithmetic.mod' was not found
|
||||
! WITHOUT-NOT: 'iso_fortran_env.mod' was not found
|
||||
|
||||
! GIVEN: error: Cannot use module file for module 'ieee_arithmetic': File has invalid checksum
|
||||
! GIVEN: error: Cannot use module file for module 'iso_fortran_env': File has invalid checksum
|
||||
|
||||
|
||||
program test_intrinsic_module_path
|
||||
use ieee_arithmetic, only: ieee_round_type
|
||||
use iso_fortran_env, only: team_type, event_type, lock_type
|
||||
end program
|
||||
@@ -1,7 +1,7 @@
|
||||
! REQUIRES: x86-registered-target
|
||||
! checks fatlto objects: that valid bitcode is included in the object file generated.
|
||||
|
||||
! RUN: %flang -fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -emit-obj %s -o %t.o
|
||||
! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -emit-obj %s -o %t.o
|
||||
! RUN: llvm-readelf -S %t.o | FileCheck %s --check-prefixes=ELF
|
||||
! RUN: llvm-objcopy --dump-section=.llvm.lto=%t.bc %t.o
|
||||
! RUN: llvm-dis %t.bc -o - | FileCheck %s --check-prefixes=DIS
|
||||
@@ -11,7 +11,7 @@
|
||||
! DIS-NEXT: ret void
|
||||
! DIS-NEXT: }
|
||||
|
||||
! RUN: %flang -fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -S %s -o - | FileCheck %s --check-prefixes=ASM
|
||||
! RUN: %flang_fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -S %s -o - | FileCheck %s --check-prefixes=ASM
|
||||
|
||||
! ASM: .section .llvm.lto,"e",@llvm_lto
|
||||
! ASM-NEXT: .Lllvm.embedded.object:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
! Test interface that lowering handles small interface mismatch with
|
||||
! type bound procedures.
|
||||
! RUN: bbc -emit-hlfir %s -o - -I nw | FileCheck %s
|
||||
! RUN: %bbc_bare -emit-hlfir %s -o - -I nw | FileCheck %s
|
||||
|
||||
module dispatch_mismatch
|
||||
type t
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
! 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
|
||||
! FIXME: Make flang a cross-compiler
|
||||
! UNSUPPORTED: true
|
||||
|
||||
! RUN: %flang_fc1 -triple aarch64-unknown-linux-gnu -emit-hlfir -fopenmp %s -o - | FileCheck %s
|
||||
subroutine simdloop_aligned_cptr(A)
|
||||
use iso_c_binding
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -139,18 +139,95 @@ config.substitutions.append(("%isysroot", " ".join(isysroot_flag)))
|
||||
if config.default_sysroot:
|
||||
config.available_features.add("default_sysroot")
|
||||
|
||||
|
||||
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: openmp should write this file into the resource 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",
|
||||
),
|
||||
# Variant that does not implicitly add intrinsic search paths
|
||||
ToolSubst(
|
||||
"%bbc_bare",
|
||||
command=FindTool("bbc"),
|
||||
unresolved="fatal",
|
||||
),
|
||||
]
|
||||
@@ -193,16 +270,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
|
||||
|
||||
@@ -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_BUILD_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@"
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#===------------------------------------------------------------------------===#
|
||||
|
||||
add_subdirectory(bbc)
|
||||
add_subdirectory(f18)
|
||||
add_subdirectory(flang-driver)
|
||||
add_subdirectory(tco)
|
||||
add_subdirectory(f18-parse-demo)
|
||||
|
||||
@@ -98,6 +98,11 @@ static llvm::cl::alias
|
||||
llvm::cl::desc("intrinsic module directory"),
|
||||
llvm::cl::aliasopt(intrinsicIncludeDirs));
|
||||
|
||||
static llvm::cl::alias
|
||||
intrinsicModulePath("fintrinsic-modules-path",
|
||||
llvm::cl::desc("intrinsic module search paths"),
|
||||
llvm::cl::aliasopt(intrinsicIncludeDirs));
|
||||
|
||||
static llvm::cl::opt<std::string>
|
||||
moduleDir("module", llvm::cl::desc("module output directory (default .)"),
|
||||
llvm::cl::init("."));
|
||||
@@ -574,14 +579,6 @@ int main(int argc, char **argv) {
|
||||
|
||||
if (includeDirs.size() == 0) {
|
||||
includeDirs.push_back(".");
|
||||
// Default Fortran modules should be installed in include/flang (a sibling
|
||||
// to the bin) directory.
|
||||
intrinsicIncludeDirs.push_back(
|
||||
llvm::sys::path::parent_path(
|
||||
llvm::sys::path::parent_path(
|
||||
llvm::sys::fs::getMainExecutable(argv[0], nullptr)))
|
||||
.str() +
|
||||
"/include/flang");
|
||||
}
|
||||
|
||||
Fortran::parser::Options options;
|
||||
|
||||
@@ -1,170 +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"
|
||||
"cudadevice"
|
||||
"ieee_arithmetic"
|
||||
"ieee_exceptions"
|
||||
"ieee_features"
|
||||
"iso_c_binding"
|
||||
"iso_fortran_env"
|
||||
"iso_fortran_env_impl"
|
||||
)
|
||||
|
||||
# Check if 128-bit float computations can be done via long double.
|
||||
check_cxx_source_compiles(
|
||||
"#include <cfloat>
|
||||
#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")
|
||||
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 (LLVM_TOOL_OPENMP_BUILD)
|
||||
message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_PROJECTS, building omp_lib.mod")
|
||||
set(base ${FLANG_INTRINSIC_MODULES_DIR}/omp_lib)
|
||||
add_custom_command(OUTPUT ${base}.mod ${base}_kinds.mod
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
|
||||
COMMAND flang -cpp -fsyntax-only ${opts} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
|
||||
${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90
|
||||
DEPENDS flang ${FLANG_INTRINSIC_MODULES_DIR}/iso_c_binding.mod ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.F90 ${depends}
|
||||
)
|
||||
list(APPEND MODULE_FILES ${base}.mod ${base}_kinds.mod)
|
||||
install(FILES ${base}.mod ${base}_kinds.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang" COMPONENT flang-module-interfaces)
|
||||
elseif ("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_llvm_install_targets(install-flang-module-interfaces
|
||||
COMPONENT 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 (LLVM_TOOL_OPENMP_BUILD)
|
||||
message(STATUS "OpenMP runtime support enabled via LLVM_ENABLE_PROJECTS, building omp_lib.h")
|
||||
file(COPY ${CMAKE_BINARY_DIR}/projects/openmp/runtime/src/omp_lib.h DESTINATION "${CMAKE_BINARY_DIR}/include/flang/OpenMP/" FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/include/flang/OpenMP/omp_lib.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang/OpenMP")
|
||||
elseif ("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()
|
||||
@@ -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
|
||||
@@ -252,6 +252,11 @@ function(runtime_default_target)
|
||||
# OpenMP tests
|
||||
list(APPEND extra_targets "libomp-mod")
|
||||
endif ()
|
||||
if ("flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
|
||||
# The target flang-rt-mod is a dependee of check-flang needed to run its
|
||||
# tests.
|
||||
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")
|
||||
@@ -536,18 +541,15 @@ if(build_runtimes)
|
||||
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")
|
||||
if("flang" IN_LIST LLVM_ENABLE_PROJECTS)
|
||||
# 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=TRUE")
|
||||
else()
|
||||
list(APPEND extra_cmake_args "-DFORTRAN_SUPPORTS_REAL16=FALSE")
|
||||
endif()
|
||||
endif()
|
||||
if("openmp" IN_LIST LLVM_ENABLE_RUNTIMES OR "offload" IN_LIST LLVM_ENABLE_RUNTIMES)
|
||||
foreach(dep opt llvm-link llvm-extract clang llvm-offload-binary clang-nvlink-wrapper)
|
||||
if(TARGET ${dep})
|
||||
list(APPEND extra_deps ${dep})
|
||||
|
||||
@@ -111,6 +111,12 @@ 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.")
|
||||
|
||||
if (LLVM_RUNTIMES_BUILD)
|
||||
flang_module_fortran_enable()
|
||||
endif ()
|
||||
|
||||
set(ENABLE_LIBOMPTARGET ON)
|
||||
# Currently libomptarget cannot be compiled on Windows or MacOS X.
|
||||
|
||||
@@ -109,7 +109,7 @@ set(LIBOMP_MIC_ARCH knc CACHE STRING
|
||||
if("${LIBOMP_ARCH}" STREQUAL "mic")
|
||||
libomp_check_variable(LIBOMP_MIC_ARCH knf knc)
|
||||
endif()
|
||||
set(LIBOMP_FORTRAN_MODULES FALSE CACHE BOOL
|
||||
set(LIBOMP_FORTRAN_MODULES "${RUNTIMES_FLANG_MODULES_ENABLED}" CACHE BOOL
|
||||
"Create Fortran module files? (requires fortran compiler)")
|
||||
|
||||
# - Support for universal fat binary builds on Mac
|
||||
@@ -147,8 +147,6 @@ else()
|
||||
set(LIBOMP_LIBFLAGS "" CACHE STRING
|
||||
"Appended user specified linked libs flags. (e.g., -lm)")
|
||||
endif()
|
||||
set(LIBOMP_FFLAGS "" CACHE STRING
|
||||
"Appended user specified Fortran compiler flags. These are only used if LIBOMP_FORTRAN_MODULES==TRUE.")
|
||||
|
||||
# Should the libomp library and generated headers be copied into the original source exports/ directory
|
||||
# Turning this to FALSE aids parallel builds to not interfere with each other.
|
||||
@@ -272,10 +270,6 @@ set(LIBOMP_TOOLS_DIR ${LIBOMP_BASE_DIR}/tools)
|
||||
set(LIBOMP_INC_DIR ${LIBOMP_SRC_DIR}/include)
|
||||
set(LIBOMP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Enabling Fortran if it is needed
|
||||
if(${LIBOMP_FORTRAN_MODULES})
|
||||
enable_language(Fortran)
|
||||
endif()
|
||||
# Enable MASM Compiler if it is needed (Windows only)
|
||||
if(WIN32)
|
||||
enable_language(ASM_MASM)
|
||||
|
||||
@@ -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()
|
||||
@@ -156,17 +156,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)
|
||||
|
||||
@@ -16,7 +16,6 @@ include(CheckIncludeFile)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckSymbolExists)
|
||||
include(LibompCheckFortranFlag)
|
||||
include(LLVMCheckCompilerLinkerFlag)
|
||||
|
||||
# Check for versioned symbols
|
||||
@@ -97,9 +96,6 @@ if(WIN32)
|
||||
endforeach()
|
||||
endforeach()
|
||||
endif()
|
||||
if(${LIBOMP_FORTRAN_MODULES})
|
||||
libomp_check_fortran_flag(-m32 LIBOMP_HAVE_M32_FORTRAN_FLAG)
|
||||
endif()
|
||||
|
||||
# Check non-posix pthread API here before CMAKE_REQUIRED_DEFINITIONS gets messed up
|
||||
check_symbol_exists(pthread_setname_np "pthread.h" LIBOMP_HAVE_PTHREAD_SETNAME_NP)
|
||||
|
||||
@@ -382,46 +382,6 @@ endif()
|
||||
configure_file(${LIBOMP_INC_DIR}/omp_lib.h.var omp_lib.h @ONLY)
|
||||
configure_file(${LIBOMP_INC_DIR}/omp_lib.F90.var omp_lib.F90 @ONLY)
|
||||
|
||||
set(BUILD_FORTRAN_MODULES False)
|
||||
if (NOT ${LIBOMP_FORTRAN_MODULES_COMPILER} STREQUAL "")
|
||||
# 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)
|
||||
add_custom_target(libomp-mod ALL DEPENDS omp_lib.mod omp_lib_kinds.mod)
|
||||
add_custom_command(
|
||||
OUTPUT omp_lib.mod omp_lib_kinds.mod
|
||||
COMMAND ${LIBOMP_FORTRAN_MODULES_COMPILER} -cpp -fsyntax-only ${LIBOMP_FORTRAN_SOURCE_FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
|
||||
)
|
||||
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 omp_lib.mod 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 omp_lib.mod omp_lib_kinds.mod
|
||||
COMMAND ${CMAKE_Fortran_COMPILER} -c ${ADDITIONAL_Fortran_FLAGS}
|
||||
${LIBOMP_CONFIGURED_FFLAGS} ${LIBOMP_FORTRAN_SOURCE_FILE}
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${LIBOMP_FORTRAN_SOURCE_FILE}
|
||||
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
|
||||
)
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${CMAKE_C_OUTPUT_EXTENSION})
|
||||
set(BUILD_FORTRAN_MODULES True)
|
||||
endif()
|
||||
|
||||
# Move files to exports/ directory if requested
|
||||
if(${LIBOMP_COPY_EXPORTS})
|
||||
include(LibompExports)
|
||||
@@ -502,15 +462,32 @@ if(${LIBOMP_OMPT_SUPPORT})
|
||||
install(FILES ${LIBOMP_HEADERS_INTDIR}/omp-tools.h DESTINATION ${LIBOMP_HEADERS_INSTALL_PATH} RENAME ompt.h)
|
||||
set(LIBOMP_OMP_TOOLS_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
|
||||
endif()
|
||||
if(${BUILD_FORTRAN_MODULES})
|
||||
|
||||
|
||||
# Build the modules files if a Fortran compiler is available.
|
||||
# Only LLVM_ENABLE_RUNTIMES=openmp is supported, LLVM_ENABLE_PROJECTS=openmp
|
||||
# has been deprecated.
|
||||
if(LIBOMP_FORTRAN_MODULES)
|
||||
add_library(libomp-mod OBJECT
|
||||
omp_lib.F90
|
||||
)
|
||||
set_target_properties(libomp-mod PROPERTIES FOLDER "OpenMP/Fortran Modules")
|
||||
|
||||
if (CMAKE_Fortran_COMPILER_ID STREQUAL "GNU")
|
||||
target_compile_options(libomp-mod PRIVATE -fno-range-check)
|
||||
endif()
|
||||
|
||||
flang_module_target(libomp-mod PUBLIC)
|
||||
if (FORTRAN_MODULE_DEPS)
|
||||
add_dependencies(libomp-mod ${FORTRAN_MODULE_DEPS})
|
||||
endif ()
|
||||
|
||||
set (destination ${LIBOMP_HEADERS_INSTALL_PATH})
|
||||
if (NOT ${LIBOMP_MODULES_INSTALL_PATH} STREQUAL "")
|
||||
set (destination ${LIBOMP_MODULES_INSTALL_PATH})
|
||||
endif()
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/omp_lib.mod
|
||||
${CMAKE_CURRENT_BINARY_DIR}/omp_lib_kinds.mod
|
||||
DESTINATION ${destination}
|
||||
)
|
||||
endif()
|
||||
|
||||
@@ -48,6 +48,7 @@ if config.test_fortran_compiler:
|
||||
ToolSubst(
|
||||
"%flang",
|
||||
command=config.test_fortran_compiler,
|
||||
extra_args=config.test_fortran_flags.split(),
|
||||
unresolved="fatal",
|
||||
),
|
||||
], [config.llvm_tools_dir])
|
||||
|
||||
@@ -8,6 +8,7 @@ config.test_compiler_has_omp_h = @OPENMP_TEST_COMPILER_HAS_OMP_H@
|
||||
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@"
|
||||
|
||||
@@ -85,6 +85,42 @@ include(CheckLibraryExists)
|
||||
include(LLVMCheckCompilerLinkerFlag)
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
include(ExtendPath)
|
||||
|
||||
|
||||
# CMake 3.24 is the first version of CMake that directly recognizes Flang.
|
||||
# LLVM's requirement is only CMake 3.20, teach CMake 3.20-3.23 how to use Flang, if used.
|
||||
if (CMAKE_VERSION VERSION_LESS "3.24" AND CMAKE_Fortran_COMPILER)
|
||||
cmake_path(GET CMAKE_Fortran_COMPILER STEM _Fortran_COMPILER_STEM)
|
||||
if (_Fortran_COMPILER_STEM STREQUAL "flang-new" OR
|
||||
_Fortran_COMPILER_STEM STREQUAL "flang")
|
||||
include(CMakeForceCompiler)
|
||||
CMAKE_FORCE_Fortran_COMPILER("${CMAKE_Fortran_COMPILER}" "LLVMFlang")
|
||||
|
||||
set(CMAKE_Fortran_COMPILER_ID "LLVMFlang")
|
||||
set(CMAKE_Fortran_COMPILER_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}")
|
||||
|
||||
set(CMAKE_Fortran_SUBMODULE_SEP "-")
|
||||
set(CMAKE_Fortran_SUBMODULE_EXT ".mod")
|
||||
|
||||
set(CMAKE_Fortran_PREPROCESS_SOURCE
|
||||
"<CMAKE_Fortran_COMPILER> -cpp <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
|
||||
|
||||
set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-ffixed-form")
|
||||
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-ffree-form")
|
||||
|
||||
set(CMAKE_Fortran_MODDIR_FLAG "-module-dir")
|
||||
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_ON "-cpp")
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_PREPROCESS_OFF "-nocpp")
|
||||
set(CMAKE_Fortran_POSTPROCESS_FLAG "-ffixed-line-length-72")
|
||||
|
||||
set(CMAKE_Fortran_COMPILE_OPTIONS_TARGET "--target=")
|
||||
|
||||
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG "-Wl,")
|
||||
set(CMAKE_Fortran_LINKER_WRAPPER_FLAG_SEP ",")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
# Determine whether we are in the runtimes/runtimes-bins directory of a
|
||||
@@ -94,17 +130,6 @@ if (LLVM_LIBRARY_DIR AND LLVM_TOOLS_BINARY_DIR AND PACKAGE_VERSION)
|
||||
set(LLVM_TREE_AVAILABLE ON)
|
||||
endif()
|
||||
|
||||
if(LLVM_TREE_AVAILABLE)
|
||||
# Setting these variables will allow the sub-build to put their outputs into
|
||||
# the library and bin directories of the top-level build.
|
||||
set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR})
|
||||
set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_TOOLS_BINARY_DIR})
|
||||
else()
|
||||
# Use own build directory for artifact output.
|
||||
set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}")
|
||||
set(LLVM_RUNTIME_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
|
||||
endif()
|
||||
|
||||
# CMake omits default compiler include paths, but in runtimes build, we use
|
||||
# -nostdinc and -nostdinc++ and control include paths manually so this behavior
|
||||
# is undesirable. Filtering CMAKE_{LANG}_IMPLICIT_INCLUDE_DIRECTORIES to remove
|
||||
@@ -217,6 +242,61 @@ message(STATUS "LLVM default target triple: ${LLVM_DEFAULT_TARGET_TRIPLE}")
|
||||
|
||||
set(LLVM_TARGET_TRIPLE "${LLVM_DEFAULT_TARGET_TRIPLE}")
|
||||
|
||||
|
||||
if(LLVM_TREE_AVAILABLE)
|
||||
# In a bootstrap build emit the libraries into a default search path in the
|
||||
# build directory of the just-built compiler. This allows using the
|
||||
# just-built compiler without specifying paths to runtime libraries.
|
||||
# LLVM_LIBRARY_OUTPUT_INTDIR/LLVM_RUNTIME_OUTPUT_INTDIR is used by
|
||||
# AddLLVM.cmake as artifact output locations.
|
||||
set(LLVM_LIBRARY_OUTPUT_INTDIR ${LLVM_LIBRARY_DIR})
|
||||
set(LLVM_RUNTIME_OUTPUT_INTDIR ${LLVM_TOOLS_BINARY_DIR})
|
||||
|
||||
# Despite Clang in the name, get_clang_resource_dir does not depend on Clang
|
||||
# being added to the build. Flang uses the same resource dir as Clang.
|
||||
include(GetClangResourceDir)
|
||||
get_clang_resource_dir(RUNTIMES_OUTPUT_RESOURCE_DIR PREFIX "${LLVM_LIBRARY_OUTPUT_INTDIR}/..")
|
||||
get_clang_resource_dir(RUNTIMES_INSTALL_RESOURCE_PATH_DEFAULT)
|
||||
else()
|
||||
# In a standalone runtimes build, do not write into LLVM_BINARY_DIR. It may be
|
||||
# read-only and/or shared by multiple runtimes with different build
|
||||
# configurations (e.g. Debug/Release). Use the runtime's own lib dir like any
|
||||
# non-toolchain library. Use own build directory for artifact output.
|
||||
set(LLVM_LIBRARY_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}")
|
||||
set(LLVM_RUNTIME_OUTPUT_INTDIR "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin")
|
||||
|
||||
# For the install prefix, still use the resource dir assuming that Flang will
|
||||
# be installed there using the same prefix. This is to not have a difference
|
||||
# between bootstrap and standalone runtimes builds.
|
||||
set(RUNTIMES_OUTPUT_RESOURCE_DIR "${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
|
||||
set(RUNTIMES_INSTALL_RESOURCE_PATH_DEFAULT "lib${LLVM_LIBDIR_SUFFIX}/clang/${LLVM_VERSION_MAJOR}")
|
||||
endif()
|
||||
|
||||
# Determine build and install paths.
|
||||
# The build path is absolute, but the install dir is relative, CMake's install
|
||||
# command has to apply CMAKE_INSTALL_PREFIX itself.
|
||||
# FIXME: For shared libraries, the toolchain resource lib dir is not a good
|
||||
# destination because it is not a ld.so default search path.
|
||||
# The machine where the executable is eventually executed may not be the
|
||||
# machine where the Flang compiler and its resource dir is installed, so
|
||||
# setting RPath by the driver is not an solution. It should belong into
|
||||
# /usr/lib/<triple>/lib<name>.so, like e.g. libgcc_s.so.
|
||||
# But the linker as invoked by the Flang driver also requires
|
||||
# libflang_rt.so to be found when linking and the resource lib dir is
|
||||
# the only reliable location.
|
||||
include(GetToolchainDirs)
|
||||
get_toolchain_library_subdir(toolchain_lib_subdir)
|
||||
extend_path(RUNTIMES_OUTPUT_RESOURCE_LIB_DIR "${RUNTIMES_OUTPUT_RESOURCE_DIR}" "${toolchain_lib_subdir}")
|
||||
|
||||
set(RUNTIMES_INSTALL_RESOURCE_PATH "${RUNTIMES_INSTALL_RESOURCE_PATH_DEFAULT}" CACHE PATH "Path to install headers, runtime libraries, and Fortran modules to (default: Clang resource dir)")
|
||||
extend_path(RUNTIMES_INSTALL_RESOURCE_LIB_PATH "${RUNTIMES_INSTALL_RESOURCE_PATH}" "${toolchain_lib_subdir}")
|
||||
|
||||
cmake_path(NORMAL_PATH RUNTIMES_OUTPUT_RESOURCE_DIR)
|
||||
cmake_path(NORMAL_PATH RUNTIMES_INSTALL_RESOURCE_PATH)
|
||||
cmake_path(NORMAL_PATH RUNTIMES_OUTPUT_RESOURCE_LIB_DIR)
|
||||
cmake_path(NORMAL_PATH RUNTIMES_INSTALL_RESOURCE_LIB_PATH)
|
||||
|
||||
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(option_prefix "")
|
||||
if (CMAKE_C_SIMULATE_ID MATCHES "MSVC")
|
||||
@@ -328,6 +408,127 @@ if(LLVM_INCLUDE_TESTS)
|
||||
umbrella_lit_testsuite_begin(check-runtimes)
|
||||
endif()
|
||||
|
||||
|
||||
include(CheckFortranSourceCompiles)
|
||||
|
||||
# Enable building Fortran modules
|
||||
# * Set up the Fortran compiler
|
||||
# * Determine files location in the Clang/Flang resource dir
|
||||
# * Install module files
|
||||
macro (flang_module_fortran_enable)
|
||||
# Assume flang modules are enabled until all tests pass
|
||||
set(FORTRAN_MODULE_DEPS "")
|
||||
set(RUNTIMES_FLANG_MODULES_ENABLED_default OFF)
|
||||
|
||||
include(CheckLanguage)
|
||||
check_language(Fortran)
|
||||
|
||||
if (CMAKE_Fortran_COMPILER)
|
||||
enable_language(Fortran)
|
||||
|
||||
if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang" AND "flang-rt" IN_LIST LLVM_ENABLE_RUNTIMES)
|
||||
# In a bootstrapping build, the intrinsic modules are not built yet.
|
||||
# Targets can depend on flang-rt-mod to ensure they are built before.
|
||||
set(FORTRAN_MODULE_DEPS flang-rt-mod)
|
||||
set(RUNTIMES_FLANG_MODULES_ENABLED_default ON)
|
||||
message(STATUS "${LLVM_SUBPROJECT_TITLE}: Building Fortran modules for Flang bootstrapping itself")
|
||||
else ()
|
||||
# Check whether building modules works, avoid causing the entire build to fail because of Fortran.
|
||||
# The primary situation we want to support here is Flang or its intrinsic modules were built separately in a non-bootstrapping build.
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
check_fortran_source_compiles("
|
||||
subroutine testroutine
|
||||
use iso_c_binding
|
||||
end subroutine
|
||||
" HAVE_FORTRAN_INTRINSIC_MODS SRC_EXT F90)
|
||||
cmake_pop_check_state()
|
||||
if (HAVE_FORTRAN_INTRINSIC_MODS)
|
||||
set(RUNTIMES_FLANG_MODULES_ENABLED_default ON)
|
||||
message(STATUS "${LLVM_SUBPROJECT_TITLE}: Non-bootstrapping Fortran modules build (${CMAKE_Fortran_COMPILER_ID} located at ${CMAKE_Fortran_COMPILER})")
|
||||
else ()
|
||||
message(STATUS "Not compiling Flang modules: Not passing smoke check")
|
||||
endif ()
|
||||
endif ()
|
||||
else ()
|
||||
message(STATUS "Not compiling Flang modules: Fortran not enabled")
|
||||
endif ()
|
||||
|
||||
option(RUNTIMES_FLANG_MODULES_ENABLED "Build Fortran modules" "${RUNTIMES_FLANG_MODULES_ENABLED_default}")
|
||||
|
||||
if (RUNTIMES_FLANG_MODULES_ENABLED)
|
||||
if (CMAKE_Fortran_COMPILER_ID STREQUAL "LLVMFlang")
|
||||
get_toolchain_module_subdir(toolchain_mod_subdir)
|
||||
extend_path(RUNTIMES_OUTPUT_RESOURCE_MOD_DIR "${RUNTIMES_OUTPUT_RESOURCE_DIR}" "${toolchain_mod_subdir}")
|
||||
extend_path(RUNTIMES_INSTALL_RESOURCE_MOD_PATH "${RUNTIMES_INSTALL_RESOURCE_PATH}" "${toolchain_mod_subdir}")
|
||||
else ()
|
||||
# For non-Flang compilers, avoid the risk of Flang accidentally picking them up.
|
||||
extend_path(RUNTIMES_OUTPUT_RESOURCE_MOD_DIR "${RUNTIMES_OUTPUT_RESOURCE_DIR}" "finclude-${CMAKE_Fortran_COMPILER_ID}")
|
||||
extend_path(RUNTIMES_INSTALL_RESOURCE_MOD_PATH "${RUNTIMES_INSTALL_RESOURCE_PATH}" "finclude-${CMAKE_Fortran_COMPILER_ID}")
|
||||
endif ()
|
||||
cmake_path(NORMAL_PATH RUNTIMES_OUTPUT_RESOURCE_MOD_DIR)
|
||||
cmake_path(NORMAL_PATH RUNTIMES_INSTALL_RESOURCE_MOD_PATH)
|
||||
|
||||
# Avoid module files to be installed multiple times if this macro is called multiple times
|
||||
get_property(is_installed GLOBAL PROPERTY RUNTIMES_MODS_INSTALLED)
|
||||
if (NOT is_installed)
|
||||
# No way to find out which mod files built by target individually, so install the entire output directory
|
||||
# https://stackoverflow.com/questions/52712416/cmake-fortran-module-directory-to-be-used-with-add-library
|
||||
set(destination "${RUNTIMES_INSTALL_RESOURCE_MOD_PATH}/..")
|
||||
cmake_path(NORMAL_PATH destination)
|
||||
install(DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}"
|
||||
DESTINATION "${destination}"
|
||||
)
|
||||
set_property(GLOBAL PROPERTY RUNTIMES_MODS_INSTALLED TRUE)
|
||||
endif ()
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
|
||||
# Set options to compile Fortran module files.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# flang_module_target(name
|
||||
# PUBLIC
|
||||
# Modules files are to be used by other Fortran sources. If a library is
|
||||
# compiled multiple times (e.g. static/shared, or msvcrt variants), only
|
||||
# one of those can be public module files; non-public modules are still
|
||||
# generated but to be forgotten deep inside the build directory to not
|
||||
# conflict with each other.
|
||||
# Also, installs the module with the toolchain.
|
||||
# )
|
||||
function (flang_module_target tgtname)
|
||||
set(options PUBLIC)
|
||||
cmake_parse_arguments(ARG
|
||||
"${options}"
|
||||
""
|
||||
""
|
||||
${ARGN})
|
||||
|
||||
if (NOT RUNTIMES_FLANG_MODULES_ENABLED)
|
||||
return ()
|
||||
endif ()
|
||||
|
||||
# Let it find the other public module files
|
||||
target_compile_options(${tgtname} PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:Fortran>:-fintrinsic-modules-path=${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}>"
|
||||
)
|
||||
|
||||
if (ARG_PUBLIC)
|
||||
set_target_properties(${tgtname}
|
||||
PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY "${RUNTIMES_OUTPUT_RESOURCE_MOD_DIR}"
|
||||
)
|
||||
else ()
|
||||
set_target_properties(${tgtname}
|
||||
PROPERTIES
|
||||
Fortran_MODULE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${tgtname}.mod"
|
||||
)
|
||||
endif ()
|
||||
endfunction ()
|
||||
|
||||
|
||||
# We do this in two loops so that HAVE_* is set for each runtime before the
|
||||
# other runtimes are added.
|
||||
foreach(entry ${runtimes})
|
||||
|
||||
Reference in New Issue
Block a user