| # Copyright 2023 The IREE Authors |
| # |
| # Licensed 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 |
| |
| """Rules for compiling with clang to produce bitcode libraries.""" |
| |
| def iree_arch_to_llvm_arch( |
| iree_arch = None): |
| """Converts an IREE_ARCH value to the corresponding LLVM arch name. |
| |
| Similar to the CMake function with the same name. |
| |
| Args: |
| iree_arch: IREE_ARCH string value. |
| |
| Returns: |
| The LLVM name for that architecture (first component of target triple). |
| """ |
| |
| if not iree_arch: |
| return None |
| if iree_arch == "arm_64": |
| return "aarch64" |
| if iree_arch == "arm_32": |
| return "arm" |
| if iree_arch == "x86_64": |
| return "x86_64" |
| if iree_arch == "x86_32": |
| return "i386" |
| if iree_arch == "riscv_64": |
| return "riscv64" |
| if iree_arch == "riscv_32": |
| return "riscv32" |
| if iree_arch == "wasm_64": |
| return "wasm64" |
| if iree_arch == "wasm_32": |
| return "wasm32" |
| fail("Unhandled IREE_ARCH value %s" % iree_arch) |
| |
| def iree_bitcode_library( |
| name, |
| arch, |
| srcs, |
| internal_hdrs = [], |
| copts = [], |
| out = None, |
| **kwargs): |
| """Builds an LLVM bitcode library from an input file via clang. |
| |
| Args: |
| name: Name of the target. |
| arch: Target architecture to compile for, in IREE_ARCH format. |
| srcs: source files to pass to clang. |
| internal_hdrs: all headers transitively included by the source files. |
| Unlike typical Bazel `hdrs`, these are not exposed as |
| interface headers. This would normally be part of `srcs`, |
| but separating it was easier for `bazel_to_cmake`, as |
| CMake does not need this, and making this explicitly |
| Bazel-only allows using `filegroup` on the Bazel side. |
| copts: additional flags to pass to clang. |
| out: output file name (defaults to name.bc). |
| **kwargs: any additional attributes to pass to the underlying rules. |
| """ |
| |
| clang_tool = "@llvm-project//clang:clang" |
| link_tool = "@llvm-project//llvm:llvm-link" |
| builtin_headers_dep = "@llvm-project//clang:builtin_headers_gen" |
| builtin_headers_path = "external/llvm-project/clang/staging/include/" |
| |
| base_copts = [ |
| # Target architecture |
| "-target", |
| iree_arch_to_llvm_arch(arch), |
| |
| # C17 with no system deps. |
| "-std=c17", |
| "-nostdinc", |
| "-ffreestanding", |
| |
| # Optimized and unstamped. |
| "-O3", |
| "-DNDEBUG", |
| "-fno-ident", |
| "-fdiscard-value-names", |
| |
| # Set the size of wchar_t to 4 bytes (instead of 2 bytes). |
| # This must match what the runtime is built with. |
| "-fno-short-wchar", |
| |
| # Enable inline asm. |
| "-fasm", |
| |
| # Object file only in bitcode format: |
| "-c", |
| "-emit-llvm", |
| |
| # Force the library into standalone mode (not depending on build-directory |
| # configuration). |
| "-DIREE_DEVICE_STANDALONE=1", |
| ] |
| |
| if arch == "arm_32": |
| # Silence "warning: unknown platform, assuming -mfloat-abi=soft" |
| base_copts.append("-mfloat-abi=soft") |
| elif arch == "riscv_32": |
| # On RISC-V, linking LLVM modules requires matching target-abi. |
| # https://lists.llvm.org/pipermail/llvm-dev/2020-January/138450.html |
| # The choice of ilp32d is simply what we have in existing riscv_32 tests. |
| # Open question - how do we scale to supporting all RISC-V ABIs? |
| base_copts.append("-mabi=ilp32d") |
| elif arch == "riscv_64": |
| # Same comments as above riscv_32 case. |
| base_copts.append("-mabi=lp64d") |
| |
| bitcode_files = [] |
| for src in srcs: |
| bitcode_out = "%s_%s.bc" % (name, src) |
| bitcode_files.append(bitcode_out) |
| native.genrule( |
| name = "gen_%s" % (bitcode_out), |
| srcs = [src, builtin_headers_dep] + internal_hdrs, |
| outs = [bitcode_out], |
| cmd = " && ".join([ |
| " ".join([ |
| "$(location %s)" % (clang_tool), |
| "-isystem $(BINDIR)/%s" % builtin_headers_path, |
| " ".join(base_copts + copts), |
| " ".join(["-I $(BINDIR)/runtime/src"]), |
| " ".join(["-I runtime/src"]), |
| "-o $(location %s)" % (bitcode_out), |
| "$(location %s)" % (src), |
| ]), |
| ]), |
| tools = [ |
| clang_tool, |
| ], |
| message = "Compiling %s to %s..." % (src, bitcode_out), |
| output_to_bindir = 1, |
| **kwargs |
| ) |
| |
| if not out: |
| out = "%s.bc" % (name) |
| |
| native.genrule( |
| name = name, |
| srcs = bitcode_files, |
| outs = [out], |
| cmd = " && ".join([ |
| " ".join([ |
| "$(location %s)" % (link_tool), |
| "-o $(location %s)" % (out), |
| " ".join(["$(locations %s)" % (src) for src in bitcode_files]), |
| ]), |
| ]), |
| tools = [link_tool], |
| message = "Linking bitcode library %s to %s..." % (name, out), |
| output_to_bindir = 1, |
| **kwargs |
| ) |
| |
| def iree_cuda_bitcode_library( |
| name, |
| cuda_arch, |
| srcs, |
| internal_hdrs = [], |
| copts = [], |
| out = None, |
| **kwargs): |
| """Builds an LLVM bitcode library for CUDA from an input file via clang. |
| |
| Args: |
| name: Name of the target. |
| cuda_arch: Target sm architecture to compile for. |
| srcs: source files to pass to clang. |
| internal_hdrs: all headers transitively included by the source files. |
| Unlike typical Bazel `hdrs`, these are not exposed as |
| interface headers. This would normally be part of `srcs`, |
| but separating it was easier for `bazel_to_cmake`, as |
| CMake does not need this, and making this explicitly |
| Bazel-only allows using `filegroup` on the Bazel side. |
| copts: additional flags to pass to clang. |
| out: output file name (defaults to name.bc). |
| **kwargs: any additional attributes to pass to the underlying rules. |
| """ |
| |
| clang_tool = "@llvm-project//clang:clang" |
| link_tool = "@llvm-project//llvm:llvm-link" |
| builtin_headers_dep = "@llvm-project//clang:builtin_headers_gen" |
| builtin_headers_path = "external/llvm-project/clang/staging/include/" |
| |
| base_copts = [ |
| "-x", |
| "cuda", |
| |
| # Target architecture |
| "--cuda-gpu-arch=%s" % (cuda_arch), |
| |
| # Suppress warnings |
| "-Wno-unknown-cuda-version", |
| "-nocudalib", |
| "--cuda-device-only", |
| |
| # Optimized. |
| "-O3", |
| |
| # Object file only in bitcode format: |
| "-c", |
| "-emit-llvm", |
| ] |
| |
| bitcode_files = [] |
| for src in srcs: |
| bitcode_out = "%s_%s.bc" % (name, src) |
| bitcode_files.append(bitcode_out) |
| native.genrule( |
| name = "gen_%s" % (bitcode_out), |
| srcs = [src, builtin_headers_dep] + internal_hdrs, |
| outs = [bitcode_out], |
| cmd = " && ".join([ |
| " ".join([ |
| "$(location %s)" % (clang_tool), |
| " ".join(base_copts + copts), |
| "-o $(location %s)" % (bitcode_out), |
| "$(location %s)" % (src), |
| ]), |
| ]), |
| tools = [ |
| clang_tool, |
| ], |
| message = "Compiling %s to %s..." % (src, bitcode_out), |
| output_to_bindir = 1, |
| **kwargs |
| ) |
| |
| if not out: |
| out = "%s.bc" % (name) |
| |
| native.genrule( |
| name = name, |
| srcs = bitcode_files, |
| outs = [out], |
| cmd = " && ".join([ |
| " ".join([ |
| "$(location %s)" % (link_tool), |
| "-o $(location %s)" % (out), |
| " ".join(["$(locations %s)" % (src) for src in bitcode_files]), |
| ]), |
| ]), |
| tools = [link_tool], |
| message = "Linking bitcode library %s to %s..." % (name, out), |
| output_to_bindir = 1, |
| **kwargs |
| ) |
| |
| def iree_link_bitcode( |
| name, |
| bitcode_files, |
| out = None, |
| link_tool = "@llvm-project//llvm:llvm-link", |
| **kwargs): |
| """Builds an LLVM bitcode library from an input file via clang. |
| |
| Args: |
| name: Name of the target. |
| bitcode_files: bitcode files to link together. |
| out: output file name (defaults to name.bc). |
| link_tool: llvm-link tool used for linking bitcode files. |
| **kwargs: any additional attributes to pass to the underlying rules. |
| """ |
| |
| bitcode_files_qualified = [("//" + native.package_name() + b) if b.startswith(":") else ("//" + native.package_name() + "/" + b) if b.count(":") else b for b in bitcode_files] |
| |
| if not out: |
| out = "%s.bc" % (name) |
| native.genrule( |
| name = name, |
| srcs = bitcode_files_qualified, |
| outs = [out], |
| cmd = " && ".join([ |
| " ".join([ |
| "$(location %s)" % (link_tool), |
| "-o $(location %s)" % (out), |
| " ".join(["$(locations %s)" % (src) for src in bitcode_files_qualified]), |
| ]), |
| ]), |
| tools = [link_tool], |
| message = "Linking bitcode library %s to %s..." % (name, out), |
| output_to_bindir = 1, |
| **kwargs |
| ) |