Reapplication of #137828 and #169638 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. Constants such as `c_long_double` also have different values). Most other modules have `#ifdef`-enclosed code as well. For instance this caused offload targets nvptx64-nvidia-cuda/amdgpu-amd-amdhsa to use the modules files compiled for the host which may contrain uses of the types REAL(10) or REAL(16) not available for nvptx/amdgpu. 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. Currently the dependencies between builtin modules and `omp_lib.mod` seem to be incorrect: https://github.com/llvm/llvm-project/pull/174474#issuecomment-3880189581 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 (PR #169525). If using Flang for cross-compilation or target-offloading, flang-rt must now be compiled for each target not only for the library, but also to get the target-specific module files. For instance in a bootstrapping runtime build, this can be done by adding: `-DLLVM_RUNTIME_TARGETS=default;nvptx64-nvidia-cuda;amdgpu-amd-amdhsa`. 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. Another subdirectory `flang` avoids accidental inclusion of gfortran-modules which due to compression would result in user-unfriendly errors. Now the driver adds `-fintrinsic-module-path` for that location to the frontend call (Just like gfortran does). 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=...`. |
||
|---|---|---|
| .. | ||
| cmake | ||
| examples | ||
| include/flang-rt/runtime | ||
| lib | ||
| test | ||
| unittests | ||
| .clang-format | ||
| .clang-tidy | ||
| CMakeLists.txt | ||
| CODE_OWNERS.TXT | ||
| LICENSE.TXT | ||
| README.md | ||
Fortran Runtime (Flang-RT)
Flang-RT is the runtime library for code emitted by the Flang compiler (https://flang.llvm.org).
Getting Started
There are two build modes for the Flang-RT. The bootstrap build, also called the in-tree build, and the runtime-only build, also called the out-of-tree build. Not to be confused with the terms in-source and out-of-source builds as defined by CMake. In an in-source build, the source directory and the build directory are identical, whereas with an out-of-source build the build artifacts are stored somewhere else, possibly in a subdirectory of the source directory. LLVM does not support in-source builds.
Requirements
Requirements:
Bootstrapping Runtimes Build
The bootstrapping build will first build Clang and Flang, then use these
compilers to compile Flang-RT. CMake will create a secondary build tree
configured to use these just-built compilers. The secondary build will reuse
the same build options (Flags, Debug/Release, ...) as the primary build.
It will also ensure that once built, Flang-RT is found by Flang from either
the build- or install-prefix. To enable, add flang-rt to
LLVM_ENABLE_RUNTIMES:
cmake -S <path-to-llvm-project-source>/llvm \
-GNinja \
-DLLVM_ENABLE_PROJECTS="clang;flang" \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
...
It is recommended to enable building OpenMP alongside Flang and Flang-RT
as well. This will build omp_lib.mod required to use OpenMP from Fortran.
Building Compiler-RT may also be required, particularly on platforms that do
not provide all C-ABI functionality (such as Windows).
cmake -S <path-to-llvm-project-source>/llvm \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_ENABLE_PROJECTS="clang;flang" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt;flang-rt;openmp" \
...
By default, the enabled runtimes will only be built for the host platform
(-DLLVM_RUNTIME_TARGETS=default). To add additional targets to support
cross-compilation via flang --target=<target-triple>, add more triples to
LLVM_RUNTIME_TARGETS, such as
-DLLVM_RUNTIME_TARGETS="default;aarch64-linux-gnu".
After configuration, build, test, and install the runtime(s) via
$ ninja flang-rt
$ ninja check-flang-rt
$ ninja install
Standalone Runtimes Build
Instead of building Clang and Flang from scratch, the standalone Runtime build
uses CMake's environment introspection to find a C, C++, and Fortran compiler.
The compiler to be used can be controlled using CMake's standard mechanisms such
as CMAKE_CXX_COMPILER, CMAKE_CXX_COMPILER, and CMAKE_Fortran_COMPILER.
CMAKE_Fortran_COMPILER must be flang built from the same Git commit as
Flang-RT to ensure they are using the same ABI. The C and C++ compiler
can be any compiler supporting the same ABI.
In addition to the compiler, the build must be able to find LLVM development
tools such as lit and FileCheck that are not found in an LLVM's install
directory. Use CMAKE_BINARY_DIR to point to directory where LLVM has
been built. When building Flang as part of a bootstrapping build
(LLVM_ENABLE_PROJECTS=flang), Flang-RT is automatically added
unless configured with -DFLANG_ENABLE_FLANG_RT=OFF. Add that option to avoid
having two conflicting versions of the same library.
A simple build configuration might look like the following:
cmake -S <path-to-llvm-project-source>/runtimes \
-GNinja \
-DLLVM_BINARY_DIR=<path-to-llvm-builddir> \
-DCMAKE_Fortran_COMPILER=<path-to-llvm-builddir>/bin/flang \
-DCMAKE_Fortran_COMPILER_WORKS=yes \
-DLLVM_ENABLE_RUNTIMES=flang-rt \
...
The CMAKE_Fortran_COMPILER_WORKS parameter must be set because otherwise CMake
will test whether the Fortran compiler can compile and link programs which will
obviously fail without a runtime library available yet.
Building Flang-RT for cross-compilation triple, the target triple can be
selected using LLVM_DEFAULT_TARGET_TRIPLE. Of course, Flang-RT can be built
multiple times with different build configurations, but have to be located
manually when using with the Flang driver using the -L option.
After configuration, build, test, and install the runtime via
$ ninja
$ ninja check-flang-rt
$ ninja install
Configuration Option Reference
Flang-RT has the followign configuration options. This is in addition to the build options the LLVM_ENABLE_RUNTIMES mechanism and CMake itself provide.
-
FLANG_RT_INCLUDE_TESTS(boolean; default:ON)When
OFF, does not add any tests and unittests. Thecheck-flang-rtbuild target will do nothing. -
FLANG_RUNTIME_F128_MATH_LIB(default:"")Determines the implementation of
REAL(16)math functions. If set tolibquadmath, usesquadmath.hand-lquadmathtypically distributed with gcc. If empty, disablesREAL(16)support. For any other value, introspects the compiler for__float128or 128-bitlong doublesupport. More details. -
FLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT(values:"CUDA",""default:"")When set to
CUDA, builds Flang-RT with experimental support for GPU accelerators using CUDA.CMAKE_CUDA_COMPILERmust be set if not automatically detected by CMake.nvccas well asclangare supported. -
FLANG_RT_INCLUDE_CUF(bool, default:OFF)Compiles the
libflang_rt.cuda_<CUDA-version>.a/.solibrary. This is independent ofFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDAand only requires a CUDA Toolkit installation (noCMAKE_CUDA_COMPILER).
Experimental CUDA Support
With -DFLANG_RT_EXPERIMENTAL_OFFLOAD_SUPPORT=CUDA, the following
additional configuration options become available.
-
FLANG_RT_LIBCUDACXX_PATH(path, default:"")Path to libcu++ package installation.
-
FLANG_RT_CUDA_RUNTIME_PTX_WITHOUT_GLOBAL_VARS(boolean, default:OFF)Do not compile global variables' definitions when producing PTX library. Default is
OFF, meaning global variable definitions are compiled by default.
GPU Offloading Support
Flang-RT can be built for GPU targets (AMDGPU, NVPTX) using the LLVM
runtimes build infrastructure. The easiest way to configure a build for
GPU offloading is via the CMake cache file at
offload/cmake/caches/FlangOffload.cmake.