# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
import re
import platform
import subprocess

import lit.util
import lit.formats
from lit.llvm import llvm_config
from lit.llvm.subst import FindTool
from lit.llvm.subst import ToolSubst

# name: The name of this test suite.
config.name = "LLVM"

# testFormat: The test format to use to interpret tests.
extra_substitutions = extra_substitutions = (
    [
        (r"\| not FileCheck .*", "> /dev/null"),
        (r"\| FileCheck .*", "> /dev/null"),
    ]
    if config.enable_profcheck
    else []
)
config.test_format = lit.formats.ShTest(
    not llvm_config.use_lit_shell, extra_substitutions
)

# suffixes: A list of file extensions to treat as test files. This is overriden
# by individual lit.local.cfg files in the test subdirectories.
config.suffixes = [".ll", ".c", ".test", ".txt", ".s", ".mir", ".yaml", ".spv"]

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ["Inputs", "CMakeLists.txt", "README.txt", "LICENSE.txt"]

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root path where tests should be run.
config.test_exec_root = os.path.join(config.llvm_obj_root, "test")

# Tweak the PATH to include the tools dir.
llvm_config.with_environment("PATH", config.llvm_tools_dir, append_path=True)

# Propagate some variables from the host environment.
llvm_config.with_system_environment(["HOME", "INCLUDE", "LIB", "TMP", "TEMP"])


# Set up OCAMLPATH to include newly built OCaml libraries.
top_ocaml_lib = os.path.join(config.llvm_lib_dir, "ocaml")
llvm_ocaml_lib = os.path.join(top_ocaml_lib, "llvm")

llvm_config.with_system_environment("OCAMLPATH")
llvm_config.with_environment("OCAMLPATH", top_ocaml_lib, append_path=True)
llvm_config.with_environment("OCAMLPATH", llvm_ocaml_lib, append_path=True)

llvm_config.with_system_environment("CAML_LD_LIBRARY_PATH")
llvm_config.with_environment("CAML_LD_LIBRARY_PATH", llvm_ocaml_lib, append_path=True)

# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests.
llvm_config.with_environment("OCAMLRUNPARAM", "b")

# Provide the path to asan runtime lib 'libclang_rt.asan_osx_dynamic.dylib' if
# available. This is darwin specific since it's currently only needed on darwin.


def get_asan_rtlib():
    if (
        not "Address" in config.llvm_use_sanitizer
        or not "Darwin" in config.target_os
        or not "x86" in config.host_triple
    ):
        return ""
    try:
        import glob
    except:
        print("glob module not found, skipping get_asan_rtlib() lookup")
        return ""
    # The libclang_rt.asan_osx_dynamic.dylib path is obtained using the relative
    # path from the host cc.
    host_lib_dir = os.path.join(os.path.dirname(config.host_cc), "../lib")
    asan_dylib_dir_pattern = (
        host_lib_dir + "/clang/*/lib/darwin/libclang_rt.asan_osx_dynamic.dylib"
    )
    found_dylibs = glob.glob(asan_dylib_dir_pattern)
    if len(found_dylibs) != 1:
        return ""
    return found_dylibs[0]


llvm_config.use_default_substitutions()

# Add site-specific substitutions.
config.substitutions.append(("%llvmshlibdir", config.llvm_shlib_dir))
config.substitutions.append(("%shlibext", config.llvm_shlib_ext))
config.substitutions.append(("%pluginext", config.llvm_plugin_ext))
config.substitutions.append(("%exeext", config.llvm_exe_ext))
config.substitutions.append(("%llvm_src_root", config.llvm_src_root))

# Add IR2Vec test vocabulary path substitution
config.substitutions.append(
    (
        "%ir2vec_test_vocab_dir",
        os.path.join(config.test_source_root, "Analysis", "IR2Vec", "Inputs"),
    )
)

lli_args = []
# The target triple used by default by lli is the process target triple (some
# triple appropriate for generating code for the current process) but because
# we don't support COFF in MCJIT well enough for the tests, force ELF format on
# Windows.  FIXME: the process target triple should be used here, but this is
# difficult to obtain on Windows.
# Cygwin is excluded from this workaround, even though it is COFF, because this
# breaks remote tests due to not having a __register_frame function.  The only
# test that succeeds with cygwin-elf but fails with cygwin is
# test/ExecutionEngine/MCJIT/stubs-sm-pic.ll so this test is marked as XFAIL
# for cygwin targets.
if re.search(r"windows-gnu|windows-msvc", config.host_triple):
    lli_args = ["-mtriple=" + config.host_triple + "-elf"]

llc_args = []

# Similarly, have a macro to use llc with DWARF even when the host is Windows
if re.search(r"windows-msvc", config.target_triple):
    llc_args = [" -mtriple=" + config.target_triple.replace("-msvc", "-gnu")]

# Provide the path to asan runtime lib if available. On darwin, this lib needs
# to be loaded via DYLD_INSERT_LIBRARIES before libLTO.dylib in case the files
# to be linked contain instrumented sanitizer code.
ld64_cmd = config.ld64_executable
asan_rtlib = get_asan_rtlib()
if asan_rtlib:
    ld64_cmd = "DYLD_INSERT_LIBRARIES={} {}".format(asan_rtlib, ld64_cmd)
if config.osx_sysroot:
    ld64_cmd = "{} -syslibroot {}".format(ld64_cmd, config.osx_sysroot)

ocamlc_command = "%s ocamlc -cclib -L%s %s" % (
    config.ocamlfind_executable,
    config.llvm_lib_dir,
    config.ocaml_flags,
)
ocamlopt_command = "true"
if config.have_ocamlopt:
    ocamlopt_command = "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" % (
        config.ocamlfind_executable,
        config.llvm_lib_dir,
        config.llvm_lib_dir,
        config.ocaml_flags,
    )

opt_viewer_cmd = "%s %s/tools/opt-viewer/opt-viewer.py" % (
    sys.executable,
    config.llvm_src_root,
)

llvm_original_di_preservation_cmd = os.path.join(
    config.llvm_src_root, "utils", "llvm-original-di-preservation.py"
)
config.substitutions.append(
    (
        "%llvm-original-di-preservation",
        "'%s' %s" % (config.python_executable, llvm_original_di_preservation_cmd),
    )
)

llvm_locstats_tool = os.path.join(config.llvm_tools_dir, "llvm-locstats")
config.substitutions.append(
    ("%llvm-locstats", "'%s' %s" % (config.python_executable, llvm_locstats_tool))
)
config.llvm_locstats_used = os.path.exists(llvm_locstats_tool)

tools = [
    ToolSubst("%llvm", FindTool("llvm"), unresolved="ignore"),
    ToolSubst("%lli", FindTool("lli"), post=".", extra_args=lli_args),
    ToolSubst("%llc_dwarf", FindTool("llc"), extra_args=llc_args),
    ToolSubst("%gold", config.gold_executable, unresolved="ignore"),
    ToolSubst("%ld64", ld64_cmd, unresolved="ignore"),
    ToolSubst("%ocamlc", ocamlc_command, unresolved="ignore"),
    ToolSubst("%ocamlopt", ocamlopt_command, unresolved="ignore"),
    ToolSubst("%opt-viewer", opt_viewer_cmd),
    ToolSubst("%llvm-objcopy", FindTool("llvm-objcopy")),
    ToolSubst("%llvm-strip", FindTool("llvm-strip")),
    ToolSubst("%llvm-install-name-tool", FindTool("llvm-install-name-tool")),
    ToolSubst("%llvm-bitcode-strip", FindTool("llvm-bitcode-strip")),
    ToolSubst("%split-file", FindTool("split-file")),
]

# FIXME: Why do we have both `lli` and `%lli` that do slightly different things?
tools.extend(
    [
        "dsymutil",
        "lli",
        "lli-child-target",
        "llvm-ar",
        "llvm-as",
        "llvm-addr2line",
        "llvm-bcanalyzer",
        "llvm-bitcode-strip",
        "llvm-cgdata",
        "llvm-config",
        "llvm-cov",
        "llvm-ctxprof-util",
        "llvm-cxxdump",
        "llvm-cvtres",
        "llvm-debuginfod-find",
        "llvm-debuginfo-analyzer",
        "llvm-diff",
        "llvm-dis",
        "llvm-dwarfdump",
        "llvm-dwarfutil",
        "llvm-dwp",
        "llvm-dlltool",
        "llvm-exegesis",
        "llvm-extract",
        "llvm-ir2vec",
        "llvm-isel-fuzzer",
        "llvm-ifs",
        "llvm-install-name-tool",
        "llvm-jitlink",
        "llvm-opt-fuzzer",
        "llvm-lib",
        "llvm-link",
        "llvm-lto",
        "llvm-lto2",
        "llvm-mc",
        "llvm-mca",
        "llvm-modextract",
        "llvm-nm",
        "llvm-objcopy",
        "llvm-objdump",
        "llvm-otool",
        "llvm-pdbutil",
        "llvm-profdata",
        "llvm-profgen",
        "llvm-ranlib",
        "llvm-rc",
        "llvm-readelf",
        "llvm-readobj",
        "llvm-rtdyld",
        "llvm-sim",
        "llvm-size",
        "llvm-split",
        "llvm-stress",
        "llvm-strings",
        "llvm-strip",
        "llvm-tblgen",
        "llvm-readtapi",
        "llvm-undname",
        "llvm-windres",
        "llvm-c-test",
        "llvm-cxxfilt",
        "llvm-xray",
        "yaml2obj",
        "obj2yaml",
        "yaml-bench",
        "verify-uselistorder",
        "bugpoint",
        "llc",
        "llvm-symbolizer",
        "opt",
        "sancov",
        "sanstats",
        "llvm-remarkutil",
    ]
)

# The following tools are optional
tools.extend(
    [
        ToolSubst("llvm-mt", unresolved="ignore"),
        ToolSubst("llvm-debuginfod", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch3", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch4", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch5", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch6", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch7", unresolved="ignore"),
        ToolSubst("Kaleidoscope-Ch8", unresolved="ignore"),
        ToolSubst("LLJITWithThinLTOSummaries", unresolved="ignore"),
        ToolSubst("LLJITWithRemoteDebugging", unresolved="ignore"),
        ToolSubst("OrcV2CBindingsBasicUsage", unresolved="ignore"),
        ToolSubst("OrcV2CBindingsAddObjectFile", unresolved="ignore"),
        ToolSubst("OrcV2CBindingsRemovableCode", unresolved="ignore"),
        ToolSubst("OrcV2CBindingsLazy", unresolved="ignore"),
        ToolSubst("OrcV2CBindingsVeryLazy", unresolved="ignore"),
        ToolSubst("dxil-dis", unresolved="ignore"),
    ]
)


# Find (major, minor) version of ptxas
def ptxas_version(ptxas):
    ptxas_cmd = subprocess.Popen([ptxas, "--version"], stdout=subprocess.PIPE)
    ptxas_out = ptxas_cmd.stdout.read().decode("ascii")
    ptxas_cmd.wait()
    match = re.search(r"release (\d+)\.(\d+)", ptxas_out)
    if match:
        return (int(match.group(1)), int(match.group(2)))
    print("couldn't determine ptxas version")
    return None


# Enable %ptxas and %ptxas-verify tools.
# %ptxas-verify defaults to sm_60 architecture. It can be overriden
# by specifying required one, for instance: %ptxas-verify -arch=sm_80.
def enable_ptxas(ptxas_executable):
    version = ptxas_version(ptxas_executable)
    if version:
        # ptxas is supposed to be backward compatible with previous
        # versions, so add a feature for every known version prior to
        # the current one.
        ptxas_known_versions = [
            (9, 0),
            (9, 1),
            (9, 2),
            (10, 0),
            (10, 1),
            (10, 2),
            (11, 0),
            (11, 1),
            (11, 2),
            (11, 3),
            (11, 4),
            (11, 5),
            (11, 6),
            (11, 7),
            (11, 8),
            (12, 0),
            (12, 1),
            (12, 2),
            (12, 3),
            (12, 4),
            (12, 5),
            (12, 6),
            (12, 8),
        ]

        def version_int(ver):
            return ver[0] * 100 + ver[1]

        # ignore ptxas if its version is below the minimum supported
        # version
        min_version = ptxas_known_versions[0]
        if version_int(version) < version_int(min_version):
            print(
                "Warning: ptxas version {}.{} is not supported".format(
                    version[0], version[1]
                )
            )
            return

        for known_version in ptxas_known_versions:
            if version_int(known_version) <= version_int(version):
                major, minor = known_version
                config.available_features.add("ptxas-{}.{}".format(major, minor))

    config.available_features.add("ptxas")
    tools.extend(
        [
            ToolSubst("%ptxas", ptxas_executable),
            ToolSubst("%ptxas-verify", "{} -arch=sm_60 -c -".format(ptxas_executable)),
        ]
    )


ptxas_executable = (
    os.environ.get("LLVM_PTXAS_EXECUTABLE", None) or config.ptxas_executable
)
if ptxas_executable:
    enable_ptxas(ptxas_executable)

llvm_config.add_tool_substitutions(tools, config.llvm_tools_dir)

# Targets

config.targets = frozenset(config.targets_to_build.split())

for arch in config.targets_to_build.split():
    config.available_features.add(arch.lower() + "-registered-target")

# Features
known_arches = ["x86_64", "mips64", "ppc64", "aarch64"]
if config.host_ldflags.find("-m32") < 0 and any(
    config.llvm_host_triple.startswith(x) for x in known_arches
):
    config.available_features.add("llvm-64-bits")

config.available_features.add("host-byteorder-" + sys.byteorder + "-endian")
if config.target_triple:
    if re.match(
        r"(aarch64_be|arc|armeb|bpfeb|lanai|m68k|mips|mips64|powerpc|powerpc64|sparc|sparcv9|s390x|s390|tce|thumbeb)-.*",
        config.target_triple,
    ):
        config.available_features.add("target-byteorder-big-endian")
    else:
        config.available_features.add("target-byteorder-little-endian")

if sys.platform in ["win32", "cygwin"]:
    # ExecutionEngine, no weak symbols in COFF.
    config.available_features.add("uses_COFF")

if sys.platform not in ["win32"]:
    # Others/can-execute.txt
    config.available_features.add("can-execute")

# Detect Windows Subsystem for Linux (WSL)
uname_r = platform.uname().release
if uname_r.endswith("-Microsoft"):
    config.available_features.add("wsl1")
elif uname_r.endswith("microsoft-standard-WSL2"):
    config.available_features.add("wsl2")

# Loadable module
if config.has_plugins:
    config.available_features.add("plugins")

if config.build_examples:
    config.available_features.add("examples")

if config.linked_bye_extension:
    config.substitutions.append(("%llvmcheckext", "CHECK-EXT"))
    config.substitutions.append(("%loadbye", ""))
    config.substitutions.append(("%loadnewpmbye", ""))
else:
    config.substitutions.append(("%llvmcheckext", "CHECK-NOEXT"))
    config.substitutions.append(
        (
            "%loadbye",
            "-load={}/Bye{}".format(config.llvm_shlib_dir, config.llvm_shlib_ext),
        )
    )
    config.substitutions.append(
        (
            "%loadnewpmbye",
            "-load-pass-plugin={}/Bye{}".format(
                config.llvm_shlib_dir, config.llvm_shlib_ext
            ),
        )
    )

if config.linked_exampleirtransforms_extension:
    config.substitutions.append(("%loadexampleirtransforms", ""))
else:
    config.substitutions.append(
        (
            "%loadexampleirtransforms",
            "-load-pass-plugin={}/ExampleIRTransforms{}".format(
                config.llvm_shlib_dir, config.llvm_shlib_ext
            ),
        )
    )

# Static libraries are not built if BUILD_SHARED_LIBS is ON.
if not config.build_shared_libs and not config.link_llvm_dylib:
    config.available_features.add("static-libs")

if config.link_llvm_dylib:
    config.available_features.add("llvm-dylib")
    config.substitutions.append(
        (
            # libLLVM.so.19.0git
            "%llvmdylib",
            "{}/libLLVM{}.{}".format(
                config.llvm_shlib_dir, config.llvm_shlib_ext, config.llvm_dylib_version
            ),
        )
    )

if config.have_tf_aot:
    config.available_features.add("have_tf_aot")

if config.have_tflite:
    config.available_features.add("have_tflite")

if config.llvm_inliner_model_autogenerated:
    config.available_features.add("llvm_inliner_model_autogenerated")

if config.llvm_raevict_model_autogenerated:
    config.available_features.add("llvm_raevict_model_autogenerated")


def have_cxx_shared_library():
    readobj_exe = lit.util.which("llvm-readobj", config.llvm_tools_dir)
    if not readobj_exe:
        print("llvm-readobj not found")
        return False

    try:
        readobj_cmd = subprocess.Popen(
            [readobj_exe, "--needed-libs", readobj_exe], stdout=subprocess.PIPE
        )
    except OSError:
        print("could not exec llvm-readobj")
        return False

    readobj_out = readobj_cmd.stdout.read().decode("ascii")
    readobj_cmd.wait()

    regex = re.compile(r"(libc\+\+|libstdc\+\+|msvcp).*\.(so|dylib|dll)")
    needed_libs = False
    for line in readobj_out.splitlines():
        if "NeededLibraries [" in line:
            needed_libs = True
        if "]" in line:
            needed_libs = False
        if needed_libs and regex.search(line.lower()):
            return True
    return False


if have_cxx_shared_library():
    config.available_features.add("cxx-shared-library")

if config.libcxx_used:
    config.available_features.add("libcxx-used")

# LLVM can be configured with an empty default triple
# Some tests are "generic" and require a valid default triple
if config.target_triple:
    config.available_features.add("default_triple")
    # Direct object generation
    if not config.target_triple.startswith(("nvptx", "xcore")):
        config.available_features.add("object-emission")

if config.have_llvm_driver:
    config.available_features.add("llvm-driver")

import subprocess


def have_ld_plugin_support():
    if not os.path.exists(
        os.path.join(config.llvm_shlib_dir, "LLVMgold" + config.llvm_shlib_ext)
    ):
        return False

    ld_cmd = subprocess.Popen(
        [config.gold_executable, "--help"], stdout=subprocess.PIPE, env={"LANG": "C"}
    )
    ld_out = ld_cmd.stdout.read().decode()
    ld_cmd.wait()

    if not "-plugin" in ld_out:
        return False

    # check that the used emulations are supported.
    emu_line = [l for l in ld_out.split("\n") if "supported emulations" in l]
    if len(emu_line) != 1:
        return False
    emu_line = emu_line[0]
    fields = emu_line.split(":")
    if len(fields) != 3:
        return False
    emulations = fields[2].split()
    if "elf_x86_64" not in emulations:
        return False
    if "elf32ppc" in emulations:
        config.available_features.add("ld_emu_elf32ppc")

    ld_version = subprocess.Popen(
        [config.gold_executable, "--version"], stdout=subprocess.PIPE, env={"LANG": "C"}
    )
    if not "GNU gold" in ld_version.stdout.read().decode():
        return False
    ld_version.wait()

    return True


if have_ld_plugin_support():
    config.available_features.add("ld_plugin")


def have_ld64_plugin_support():
    if not os.path.exists(
        os.path.join(config.llvm_shlib_dir, "libLTO" + config.llvm_shlib_ext)
    ):
        return False

    if config.ld64_executable == "":
        return False

    ld_cmd = subprocess.Popen([config.ld64_executable, "-v"], stderr=subprocess.PIPE)
    ld_out = ld_cmd.stderr.read().decode()
    ld_cmd.wait()

    if "ld64" not in ld_out or "LTO" not in ld_out:
        return False

    return True


if have_ld64_plugin_support():
    config.available_features.add("ld64_plugin")


def host_unwind_supports_jit():
    # Do we expect the host machine to support JIT registration of clang's
    # default unwind info format for the host (e.g. eh-frames, compact-unwind,
    # etc.).

    # Linux and the BSDs use DWARF eh-frames and all known unwinders support
    # register_frame at minimum.
    if platform.system() in ["Linux", "FreeBSD", "NetBSD"]:
        return True

    # Windows does not support frame info without the ORC runtime.
    if platform.system() == "Windows":
        return False

    # On Darwin/x86-64 clang produces both eh-frames and compact-unwind, and
    # libunwind supports register_frame. On Darwin/arm64 clang produces
    # compact-unwind only, and JIT'd registration is not available before
    # macOS 14.0.
    if platform.system() == "Darwin":
        assert "arm64" in config.host_triple or "x86_64" in config.host_triple

        if "x86_64" in config.host_triple:
            return True

        # Must be arm64. Check the macOS version.
        try:
            osx_version = subprocess.check_output(
                ["sw_vers", "-productVersion"], universal_newlines=True
            )
            osx_version = tuple(int(x) for x in osx_version.split("."))
            if len(osx_version) == 2:
                osx_version = (osx_version[0], osx_version[1], 0)
            if osx_version >= (14, 0):
                return True
        except:
            pass

        return False

    return False


if host_unwind_supports_jit():
    config.available_features.add("host-unwind-supports-jit")

# Ask llvm-config about asserts
llvm_config.feature_config(
    [
        ("--assertion-mode", {"ON": "asserts"}),
        ("--build-mode", {"[Dd][Ee][Bb][Uu][Gg]": "debug"}),
    ]
)

if "darwin" == sys.platform:
    cmd = ["sysctl", "hw.optional.fma"]
    sysctl_cmd = subprocess.Popen(cmd, stdout=subprocess.PIPE)

    # Non zero return, probably a permission issue
    if sysctl_cmd.wait():
        print(
            'Warning: sysctl exists but calling "{}" failed, defaulting to no fma3.'.format(
                " ".join(cmd)
            )
        )
    else:
        result = sysctl_cmd.stdout.read().decode("ascii")
        if "hw.optional.fma: 1" in result:
            config.available_features.add("fma3")

if not hasattr(sys, "getwindowsversion") or sys.getwindowsversion().build >= 17063:
    config.available_features.add("unix-sockets")

# .debug_frame is not emitted for targeting Windows x64, aarch64/arm64, AIX, or Apple Silicon Mac.
if not re.match(
    r"^(x86_64|aarch64|arm64|powerpc|powerpc64).*-(windows-cygnus|windows-gnu|windows-msvc|aix)",
    config.target_triple,
) and not re.match(r"^arm64(e)?-apple-(macos|darwin)", config.target_triple):
    config.available_features.add("debug_frame")

if config.enable_backtrace:
    config.available_features.add("backtrace")

if config.enable_threads:
    config.available_features.add("thread_support")

if config.have_libxml2:
    config.available_features.add("libxml2")

if config.have_curl:
    config.available_features.add("curl")

if config.have_httplib:
    config.available_features.add("httplib")

if config.have_opt_viewer_modules:
    config.available_features.add("have_opt_viewer_modules")

if config.expensive_checks:
    config.available_features.add("expensive_checks")

if "MemoryWithOrigins" in config.llvm_use_sanitizer:
    config.available_features.add("use_msan_with_origins")


# Some tools support an environment variable "OBJECT_MODE" on AIX OS, which
# controls the kind of objects they will support. If there is no "OBJECT_MODE"
# environment variable specified, the default behaviour is to support 32-bit
# objects only. In order to not affect most test cases, which expect to support
# 32-bit and 64-bit objects by default, set the environment variable
# "OBJECT_MODE" to 'any' by default on AIX OS.
if "system-aix" in config.available_features:
    config.environment["OBJECT_MODE"] = "any"

if config.has_logf128:
    config.available_features.add("has_logf128")
