Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 1 | # Copyright 2023 The IREE Authors |
| 2 | # |
| 3 | # Licensed under the Apache License v2.0 with LLVM Exceptions. |
| 4 | # See https://llvm.org/LICENSE.txt for license information. |
| 5 | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | |
| 7 | """Rules for compiling with clang to produce bitcode libraries.""" |
| 8 | |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 9 | def iree_arch_to_llvm_arch( |
| 10 | iree_arch = None): |
| 11 | """Converts an IREE_ARCH value to the corresponding LLVM arch name. |
| 12 | |
| 13 | Similar to the CMake function with the same name. |
| 14 | |
| 15 | Args: |
| 16 | iree_arch: IREE_ARCH string value. |
| 17 | |
| 18 | Returns: |
| 19 | The LLVM name for that architecture (first component of target triple). |
| 20 | """ |
| 21 | |
| 22 | if not iree_arch: |
| 23 | return None |
| 24 | if iree_arch == "arm_64": |
| 25 | return "aarch64" |
| 26 | if iree_arch == "arm_32": |
| 27 | return "arm" |
| 28 | if iree_arch == "x86_64": |
| 29 | return "x86_64" |
| 30 | if iree_arch == "x86_32": |
| 31 | return "i386" |
| 32 | if iree_arch == "riscv_64": |
| 33 | return "riscv64" |
| 34 | if iree_arch == "riscv_32": |
| 35 | return "riscv32" |
| 36 | if iree_arch == "wasm_64": |
| 37 | return "wasm64" |
| 38 | if iree_arch == "wasm_32": |
| 39 | return "wasm32" |
| 40 | fail("Unhandled IREE_ARCH value %s" % iree_arch) |
| 41 | |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 42 | def iree_bitcode_library( |
| 43 | name, |
| 44 | srcs, |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 45 | internal_hdrs = [], |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 46 | copts = [], |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 47 | out = None, |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 48 | arch = None, |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 49 | **kwargs): |
| 50 | """Builds an LLVM bitcode library from an input file via clang. |
| 51 | |
| 52 | Args: |
| 53 | name: Name of the target. |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 54 | arch: Target architecture to compile for, in IREE_ARCH format. If left |
| 55 | empty, will produce architecture-independent bitcode by stripping |
| 56 | target triple and target attributes; that only makes sense if the |
| 57 | sources being compiled are truly architecture-independent. |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 58 | srcs: source files to pass to clang. |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 59 | internal_hdrs: all headers transitively included by the source files. |
| 60 | Unlike typical Bazel `hdrs`, these are not exposed as |
| 61 | interface headers. This would normally be part of `srcs`, |
| 62 | but separating it was easier for `bazel_to_cmake`, as |
| 63 | CMake does not need this, and making this explicitly |
| 64 | Bazel-only allows using `filegroup` on the Bazel side. |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 65 | copts: additional flags to pass to clang. |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 66 | out: output file name (defaults to name.bc). |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 67 | **kwargs: any additional attributes to pass to the underlying rules. |
| 68 | """ |
| 69 | |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 70 | clang_tool = "@llvm-project//clang:clang" |
| 71 | link_tool = "@llvm-project//llvm:llvm-link" |
| 72 | builtin_headers_dep = "@llvm-project//clang:builtin_headers_gen" |
| 73 | builtin_headers_path = "external/llvm-project/clang/staging/include/" |
| 74 | |
| 75 | base_copts = [ |
| 76 | # C17 with no system deps. |
| 77 | "-std=c17", |
| 78 | "-nostdinc", |
| 79 | "-ffreestanding", |
| 80 | |
| 81 | # Optimized and unstamped. |
| 82 | "-O3", |
| 83 | "-DNDEBUG", |
| 84 | "-fno-ident", |
| 85 | "-fdiscard-value-names", |
| 86 | |
| 87 | # Set the size of wchar_t to 4 bytes (instead of 2 bytes). |
| 88 | # This must match what the runtime is built with. |
| 89 | "-fno-short-wchar", |
| 90 | |
| 91 | # Object file only in bitcode format: |
| 92 | "-c", |
| 93 | "-emit-llvm", |
| 94 | |
| 95 | # Force the library into standalone mode (not depending on build-directory |
| 96 | # configuration). |
| 97 | "-DIREE_DEVICE_STANDALONE=1", |
| 98 | ] |
| 99 | |
| 100 | llvmir_processing_tool = None |
| 101 | if arch: |
| 102 | # Compile to the specified target architecture. |
| 103 | base_copts.extend(["-target", iree_arch_to_llvm_arch(arch)]) |
| 104 | else: |
| 105 | # Output text rather than binary serialization of LLVM IR for processing |
| 106 | base_copts.append("-S") |
| 107 | |
| 108 | # Strip target information from generated LLVM IR. |
| 109 | llvmir_processing_tool = "//build_tools/scripts:strip_target_info" |
| 110 | |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 111 | bitcode_files = [] |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 112 | for src in srcs: |
| 113 | bitcode_out = "%s_%s.bc" % (name, src) |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 114 | native.genrule( |
| 115 | name = "gen_%s" % (bitcode_out), |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 116 | srcs = [src, builtin_headers_dep] + internal_hdrs, |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 117 | outs = [bitcode_out], |
| 118 | cmd = " && ".join([ |
| 119 | " ".join([ |
| 120 | "$(location %s)" % (clang_tool), |
MaheshRavishankar | 29647b3 | 2023-05-19 10:54:42 -0700 | [diff] [blame] | 121 | "-isystem $(BINDIR)/%s" % builtin_headers_path, |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 122 | " ".join(base_copts + copts), |
MaheshRavishankar | 29647b3 | 2023-05-19 10:54:42 -0700 | [diff] [blame] | 123 | " ".join(["-I $(BINDIR)/runtime/src"]), |
| 124 | " ".join(["-I runtime/src"]), |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 125 | "-o $(location %s)" % (bitcode_out), |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 126 | "$(location %s)" % (src), |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 127 | ]), |
| 128 | ]), |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 129 | tools = [ |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 130 | clang_tool, |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 131 | ], |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 132 | message = "Compiling %s to %s..." % (src, bitcode_out), |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 133 | output_to_bindir = 1, |
| 134 | **kwargs |
| 135 | ) |
| 136 | |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 137 | if llvmir_processing_tool: |
| 138 | processed_bitcode_out = "%s_%s.processed.bc" % (name, src) |
| 139 | native.genrule( |
| 140 | name = "gen_%s" % (processed_bitcode_out), |
| 141 | srcs = [bitcode_out], |
| 142 | outs = [processed_bitcode_out], |
| 143 | cmd = " ".join([ |
| 144 | "$(location %s)" % (llvmir_processing_tool), |
| 145 | "< $(location %s)" % bitcode_out, |
| 146 | "> $(location %s)" % processed_bitcode_out, |
| 147 | ]), |
| 148 | tools = [ |
| 149 | llvmir_processing_tool, |
| 150 | ], |
| 151 | message = "Processing %s into %s using %s..." % (bitcode_out, processed_bitcode_out, llvmir_processing_tool), |
| 152 | output_to_bindir = 1, |
| 153 | **kwargs |
| 154 | ) |
| 155 | bitcode_files.append(processed_bitcode_out) |
| 156 | else: |
| 157 | bitcode_files.append(bitcode_out) |
| 158 | |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 159 | if not out: |
| 160 | out = "%s.bc" % (name) |
| 161 | native.genrule( |
| 162 | name = name, |
| 163 | srcs = bitcode_files, |
| 164 | outs = [out], |
| 165 | cmd = " && ".join([ |
| 166 | " ".join([ |
| 167 | "$(location %s)" % (link_tool), |
| 168 | "-o $(location %s)" % (out), |
| 169 | " ".join(["$(locations %s)" % (src) for src in bitcode_files]), |
| 170 | ]), |
| 171 | ]), |
bjacob | 041b4e8 | 2023-05-30 19:59:26 -0400 | [diff] [blame] | 172 | tools = [link_tool], |
Ben Vanik | 7f6c57c | 2023-02-07 18:04:32 -0800 | [diff] [blame] | 173 | message = "Linking bitcode library %s to %s..." % (name, out), |
| 174 | output_to_bindir = 1, |
| 175 | **kwargs |
| 176 | ) |
MaheshRavishankar | 29647b3 | 2023-05-19 10:54:42 -0700 | [diff] [blame] | 177 | |
| 178 | def iree_link_bitcode( |
| 179 | name, |
| 180 | bitcode_files, |
| 181 | out = None, |
| 182 | link_tool = "@llvm-project//llvm:llvm-link", |
| 183 | **kwargs): |
| 184 | """Builds an LLVM bitcode library from an input file via clang. |
| 185 | |
| 186 | Args: |
| 187 | name: Name of the target. |
| 188 | bitcode_files: bitcode files to link together. |
| 189 | out: output file name (defaults to name.bc). |
| 190 | link_tool: llvm-link tool used for linking bitcode files. |
| 191 | **kwargs: any additional attributes to pass to the underlying rules. |
| 192 | """ |
| 193 | |
| 194 | bitcode_files_qualified = [(("//" + native.package_name() + "/" + b) if b.count(":") else b) for b in bitcode_files] |
| 195 | |
| 196 | if not out: |
| 197 | out = "%s.bc" % (name) |
| 198 | native.genrule( |
| 199 | name = name, |
| 200 | srcs = bitcode_files_qualified, |
| 201 | outs = [out], |
| 202 | cmd = " && ".join([ |
| 203 | " ".join([ |
| 204 | "$(location %s)" % (link_tool), |
| 205 | "-o $(location %s)" % (out), |
| 206 | " ".join(["$(locations %s)" % (src) for src in bitcode_files_qualified]), |
| 207 | ]), |
| 208 | ]), |
| 209 | tools = [link_tool], |
| 210 | message = "Linking bitcode library %s to %s..." % (name, out), |
| 211 | output_to_bindir = 1, |
| 212 | **kwargs |
| 213 | ) |