# -*- 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.
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)

# 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"]

# 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.host_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))


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.
if re.search(r"cygwin|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-config",
        "llvm-cov",
        "llvm-cxxdump",
        "llvm-cvtres",
        "llvm-debuginfod-find",
        "llvm-debuginfo-analyzer",
        "llvm-diff",
        "llvm-dis",
        "llvm-dwarfdump",
        "llvm-dwarfutil",
        "llvm-dlltool",
        "llvm-exegesis",
        "llvm-extract",
        "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-remark-size-diff",
        "llvm-rtdyld",
        "llvm-sim",
        "llvm-size",
        "llvm-split",
        "llvm-stress",
        "llvm-strings",
        "llvm-strip",
        "llvm-tblgen",
        "llvm-tapi-diff",
        "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("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),
        ]

        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 sys.platform in ["win32"]:
    # ExecutionEngine, no weak symbols in COFF.
    config.available_features.add("uses_COFF")
else:
    # Others/can-execute.txt
    config.available_features.add("can-execute")

# 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(
        (
            "%llvmdylib",
            "{}/libLLVM-{}{}".format(
                config.llvm_shlib_dir, config.llvm_dylib_version, config.llvm_shlib_ext
            ),
        )
    )

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")

# Allow checking for specific details in the host triple
if config.host_triple:
    config.available_features.add('host=%s' % config.host_triple)

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")

# 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")

# .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-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.have_libxar:
    config.available_features.add("xar")

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")


def exclude_unsupported_files_for_aix(dirname):
    for filename in os.listdir(dirname):
        source_path = os.path.join(dirname, filename)
        if os.path.isdir(source_path):
            continue
        f = open(source_path, "r")
        try:
            data = f.read()
            # 64-bit object files are not supported on AIX, so exclude the tests.
            if (
                "-emit-obj" in data or "-filetype=obj" in data
            ) and "64" in config.target_triple:
                config.excludes += [filename]
        finally:
            f.close()


if "aix" in config.target_triple:
    for directory in (
        "/CodeGen/X86",
        "/DebugInfo",
        "/DebugInfo/X86",
        "/DebugInfo/Generic",
        "/LTO/X86",
        "/Linker",
    ):
        exclude_unsupported_files_for_aix(config.test_source_root + directory)

# 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"
