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=...`.
235 lines
8.7 KiB
Python
235 lines
8.7 KiB
Python
# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
|
|
# Configuration file for the 'lit' test runner.
|
|
|
|
import os
|
|
import re
|
|
import shlex
|
|
import subprocess
|
|
import lit.formats
|
|
from lit.llvm.subst import ToolSubst
|
|
from lit.llvm import llvm_config
|
|
|
|
# Tell pylint that we know config and lit_config exist somewhere.
|
|
if 'PYLINT_IMPORT' in os.environ:
|
|
config = object()
|
|
lit_config = object()
|
|
|
|
def prepend_dynamic_library_path(path):
|
|
target_arch = getattr(config, 'target_arch', None)
|
|
if config.operating_system == 'Windows':
|
|
name = 'PATH'
|
|
sep = ';'
|
|
elif config.operating_system == 'Darwin':
|
|
name = 'DYLD_LIBRARY_PATH'
|
|
sep = ':'
|
|
elif config.operating_system == 'Haiku':
|
|
name = 'LIBRARY_PATH'
|
|
sep = ':'
|
|
elif target_arch == 've':
|
|
name = 'VE_LD_LIBRARY_PATH'
|
|
sep = ':'
|
|
else:
|
|
name = 'LD_LIBRARY_PATH'
|
|
sep = ':'
|
|
if name in config.environment:
|
|
config.environment[name] = path + sep + config.environment[name]
|
|
else:
|
|
config.environment[name] = path
|
|
|
|
# name: The name of this test suite.
|
|
config.name = 'libomp'
|
|
|
|
# suffixes: A list of file extensions to treat as test files.
|
|
config.suffixes = ['.c', '.cpp']
|
|
|
|
# Exclude Unit tests - they are run separately via check-libomp-unit
|
|
config.excludes = ['Unit']
|
|
|
|
if config.test_fortran_compiler:
|
|
lit_config.note("OpenMP Fortran tests enabled")
|
|
config.suffixes += ['.f90', '.F90']
|
|
llvm_config.add_tool_substitutions([
|
|
ToolSubst(
|
|
"%flang",
|
|
command=config.test_fortran_compiler,
|
|
extra_args=shlex.split(config.test_fortran_flags),
|
|
unresolved="fatal",
|
|
),
|
|
], [config.llvm_tools_dir])
|
|
else:
|
|
lit_config.note("OpenMP Fortran tests disabled")
|
|
|
|
# test_source_root: The root path where tests are located.
|
|
config.test_source_root = os.path.dirname(__file__)
|
|
|
|
# test_exec_root: The root object directory where output is placed
|
|
config.test_exec_root = config.libomp_obj_root
|
|
|
|
# test format
|
|
config.test_format = lit.formats.ShTest()
|
|
|
|
# compiler flags
|
|
flags = " -I " + config.test_source_root + \
|
|
" -L " + config.library_dir + \
|
|
" " + config.test_extra_flags
|
|
if config.has_omit_frame_pointer_flag:
|
|
flags += " -fno-omit-frame-pointer"
|
|
if config.target_arch == "s390x":
|
|
flags += " -mbackchain"
|
|
|
|
config.test_flags = " -I " + config.omp_header_directory + flags
|
|
|
|
# extra libraries
|
|
libs = ""
|
|
if config.operating_system != 'Haiku':
|
|
if config.has_libm:
|
|
libs += " -lm"
|
|
if config.has_libatomic:
|
|
libs += " -latomic"
|
|
|
|
# Allow REQUIRES / UNSUPPORTED / XFAIL to work
|
|
for feature in config.test_compiler_features:
|
|
config.available_features.add(feature)
|
|
|
|
# Setup environment to find dynamic library at runtime
|
|
if config.using_hwloc:
|
|
prepend_dynamic_library_path(config.hwloc_library_dir)
|
|
config.available_features.add('hwloc')
|
|
# Note: please keep config.library_dir *after* any potentially system
|
|
# directories, as otherwise preinstalled openmp libraries will be used
|
|
# over just-built
|
|
prepend_dynamic_library_path(config.library_dir)
|
|
|
|
# Rpath modifications for Darwin
|
|
if config.operating_system == 'Darwin':
|
|
config.test_flags += " -Wl,-rpath," + config.library_dir
|
|
if config.using_hwloc:
|
|
config.test_flags += " -Wl,-rpath," + config.hwloc_library_dir
|
|
|
|
# Find the SDK on Darwin
|
|
if config.operating_system == 'Darwin':
|
|
cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
|
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
out, err = cmd.communicate()
|
|
out = out.strip().decode()
|
|
res = cmd.wait()
|
|
if res == 0 and out:
|
|
config.test_flags += " -isysroot " + out
|
|
|
|
# Disable OMPT tests if FileCheck was not found
|
|
if config.has_ompt and config.test_filecheck == "":
|
|
lit_config.note("Not testing OMPT because FileCheck was not found")
|
|
config.has_ompt = False
|
|
|
|
if config.has_ompt:
|
|
config.available_features.add("ompt")
|
|
# for callback.h
|
|
config.test_flags += " -I " + config.test_source_root + "/ompt"
|
|
|
|
if config.has_omp_taskgraph_experimental:
|
|
config.available_features.add("omp_taskgraph_experimental")
|
|
|
|
if config.operating_system == 'AIX':
|
|
config.available_features.add("aix")
|
|
object_mode = os.environ.get('OBJECT_MODE', '32')
|
|
if object_mode == '64':
|
|
# Set OBJECT_MODE to 64 for LIT test if it is explicitly set.
|
|
config.environment['OBJECT_MODE'] = os.environ['OBJECT_MODE']
|
|
elif object_mode == '32':
|
|
# Set user data area to 2GB since the default size 256MB in 32-bit mode
|
|
# is not sufficient to run LIT tests on systems that have a lot of
|
|
# CPUs when creating one worker thread for each CPU and each worker
|
|
# thread uses 4MB stack size.
|
|
config.test_flags += " -Wl,-bmaxdata:0x80000000"
|
|
config.test_openmp_flags += " -Wl,-bmaxdata:0x80000000"
|
|
|
|
if 'Linux' in config.operating_system:
|
|
config.available_features.add("linux")
|
|
|
|
if config.operating_system == 'NetBSD':
|
|
config.available_features.add("netbsd")
|
|
|
|
if config.operating_system == 'Darwin':
|
|
config.available_features.add("darwin")
|
|
|
|
if config.operating_system in ['Windows', 'Linux', 'FreeBSD', 'NetBSD', 'DragonFly', 'AIX']:
|
|
config.available_features.add('affinity')
|
|
|
|
if config.operating_system in ['Linux']:
|
|
config.available_features.add('hidden-helper')
|
|
|
|
if config.compiler_frontend_variant == 'MSVC' or config.compiler_simulate_id == 'MSVC':
|
|
config.available_features.add("msvc")
|
|
|
|
target_arch = getattr(config, 'target_arch', None)
|
|
if target_arch:
|
|
config.available_features.add(target_arch + '-target-arch')
|
|
if target_arch in ['x86_64', 'i386']:
|
|
config.available_features.add('x86-target-arch')
|
|
|
|
import multiprocessing
|
|
try:
|
|
if multiprocessing.cpu_count() > 1:
|
|
config.available_features.add('multicpu')
|
|
except NotImplementedError:
|
|
pass
|
|
|
|
# to run with icc INTEL_LICENSE_FILE must be set
|
|
if 'INTEL_LICENSE_FILE' in os.environ:
|
|
config.environment['INTEL_LICENSE_FILE'] = os.environ['INTEL_LICENSE_FILE']
|
|
|
|
# set default environment variables for test
|
|
if 'CHECK_OPENMP_ENV' in os.environ:
|
|
test_env = os.environ['CHECK_OPENMP_ENV'].split()
|
|
for env in test_env:
|
|
name = env.split('=')[0]
|
|
value = env.split('=')[1]
|
|
config.environment[name] = value
|
|
|
|
# substitutions
|
|
config.substitutions.append(("%libomp-compile-and-run", \
|
|
"%libomp-compile && %libomp-run"))
|
|
config.substitutions.append(("%libomp-irbuilder-compile-and-run", \
|
|
"%libomp-irbuilder-compile && %libomp-run"))
|
|
config.substitutions.append(("%libomp-c99-compile-and-run", \
|
|
"%libomp-c99-compile && %libomp-run"))
|
|
config.substitutions.append(("%libomp-cxx-compile-and-run", \
|
|
"%libomp-cxx-compile && %libomp-run"))
|
|
config.substitutions.append(("%libomp-cxx20-compile-and-run", \
|
|
"%libomp-cxx20-compile && %libomp-run"))
|
|
config.substitutions.append(("%libomp-cxx-compile-c", \
|
|
"%clangXX %openmp_flags %flags -std=c++17 -x c++ %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-cxx-compile", \
|
|
"%clangXX %openmp_flags %flags -std=c++17 %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-cxx20-compile", \
|
|
"%clangXX %openmp_flags %flags -std=c++20 %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-compile", \
|
|
"%clang %openmp_flags %flags %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-irbuilder-compile", \
|
|
"%clang %openmp_flags %flags -fopenmp-enable-irbuilder %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-c99-compile", \
|
|
"%clang %openmp_flags %flags -std=c99 %s -o %t" + libs))
|
|
config.substitutions.append(("%libomp-run", "%t"))
|
|
config.substitutions.append(("%clangXX", config.test_cxx_compiler))
|
|
config.substitutions.append(("%clang", config.test_c_compiler))
|
|
config.substitutions.append(("%openmp_flags", config.test_openmp_flags))
|
|
config.substitutions.append(("%flags", config.test_flags))
|
|
config.substitutions.append(("%python", '"%s"' % (sys.executable)))
|
|
config.substitutions.append(("%not", config.test_not))
|
|
|
|
if config.has_ompt:
|
|
config.substitutions.append(("FileCheck", "tee %%t.out | %s" % config.test_filecheck))
|
|
config.substitutions.append(("%sort-threads", "sort -n -s"))
|
|
if config.operating_system == 'Windows':
|
|
# No such environment variable on Windows.
|
|
config.substitutions.append(("%preload-tool", "true ||"))
|
|
config.substitutions.append(("%no-as-needed-flag", "-Wl,--no-as-needed"))
|
|
elif config.operating_system == 'Darwin':
|
|
config.substitutions.append(("%preload-tool", "env DYLD_INSERT_LIBRARIES=%t.tool_dir/tool.so"))
|
|
# No such linker flag on Darwin.
|
|
config.substitutions.append(("%no-as-needed-flag", ""))
|
|
else:
|
|
config.substitutions.append(("%preload-tool", "env LD_PRELOAD=%t.tool_dir/tool.so"))
|
|
config.substitutions.append(("%no-as-needed-flag", "-Wl,--no-as-needed"))
|
|
else:
|
|
config.substitutions.append(("FileCheck", config.test_filecheck))
|