blob: 27b1ed64ca06f2881391e02ccc892cdc8a98c8a6 [file] [log] [blame]
Ben Vanik7f6c57c2023-02-07 18:04:32 -08001# 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
bjacob041b4e82023-05-30 19:59:26 -04009def 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 Vanik7f6c57c2023-02-07 18:04:32 -080042def iree_bitcode_library(
43 name,
bjacob446a5422023-06-01 06:10:27 -040044 arch,
Ben Vanik7f6c57c2023-02-07 18:04:32 -080045 srcs,
bjacob041b4e82023-05-30 19:59:26 -040046 internal_hdrs = [],
Ben Vanik7f6c57c2023-02-07 18:04:32 -080047 copts = [],
Ben Vanik7f6c57c2023-02-07 18:04:32 -080048 out = None,
Ben Vanik7f6c57c2023-02-07 18:04:32 -080049 **kwargs):
50 """Builds an LLVM bitcode library from an input file via clang.
51
52 Args:
53 name: Name of the target.
bjacob446a5422023-06-01 06:10:27 -040054 arch: Target architecture to compile for, in IREE_ARCH format.
Ben Vanik7f6c57c2023-02-07 18:04:32 -080055 srcs: source files to pass to clang.
bjacob041b4e82023-05-30 19:59:26 -040056 internal_hdrs: all headers transitively included by the source files.
57 Unlike typical Bazel `hdrs`, these are not exposed as
58 interface headers. This would normally be part of `srcs`,
59 but separating it was easier for `bazel_to_cmake`, as
60 CMake does not need this, and making this explicitly
61 Bazel-only allows using `filegroup` on the Bazel side.
Ben Vanik7f6c57c2023-02-07 18:04:32 -080062 copts: additional flags to pass to clang.
Ben Vanik7f6c57c2023-02-07 18:04:32 -080063 out: output file name (defaults to name.bc).
Ben Vanik7f6c57c2023-02-07 18:04:32 -080064 **kwargs: any additional attributes to pass to the underlying rules.
65 """
66
bjacob041b4e82023-05-30 19:59:26 -040067 clang_tool = "@llvm-project//clang:clang"
68 link_tool = "@llvm-project//llvm:llvm-link"
69 builtin_headers_dep = "@llvm-project//clang:builtin_headers_gen"
70 builtin_headers_path = "external/llvm-project/clang/staging/include/"
71
72 base_copts = [
bjacob446a5422023-06-01 06:10:27 -040073 # Target architecture
74 "-target",
75 iree_arch_to_llvm_arch(arch),
76
bjacob041b4e82023-05-30 19:59:26 -040077 # C17 with no system deps.
78 "-std=c17",
79 "-nostdinc",
80 "-ffreestanding",
81
82 # Optimized and unstamped.
83 "-O3",
84 "-DNDEBUG",
85 "-fno-ident",
86 "-fdiscard-value-names",
87
88 # Set the size of wchar_t to 4 bytes (instead of 2 bytes).
89 # This must match what the runtime is built with.
90 "-fno-short-wchar",
91
bjacobbf8588e2023-06-01 06:37:13 -040092 # Enable inline asm.
93 "-fasm",
94
bjacob041b4e82023-05-30 19:59:26 -040095 # Object file only in bitcode format:
96 "-c",
97 "-emit-llvm",
98
99 # Force the library into standalone mode (not depending on build-directory
100 # configuration).
101 "-DIREE_DEVICE_STANDALONE=1",
102 ]
103
Benoit Jacob7d736b52024-01-18 11:54:39 -0500104 if arch == "arm_32":
105 # Silence "warning: unknown platform, assuming -mfloat-abi=soft"
106 base_copts.append("-mfloat-abi=soft")
107 elif arch == "riscv_32":
108 # On RISC-V, linking LLVM modules requires matching target-abi.
109 # https://lists.llvm.org/pipermail/llvm-dev/2020-January/138450.html
110 # The choice of ilp32d is simply what we have in existing riscv_32 tests.
111 # Open question - how do we scale to supporting all RISC-V ABIs?
112 base_copts.append("-mabi=ilp32d")
113 elif arch == "riscv_64":
114 # Same comments as above riscv_32 case.
115 base_copts.append("-mabi=lp64d")
116
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800117 bitcode_files = []
bjacob041b4e82023-05-30 19:59:26 -0400118 for src in srcs:
119 bitcode_out = "%s_%s.bc" % (name, src)
bjacob446a5422023-06-01 06:10:27 -0400120 bitcode_files.append(bitcode_out)
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800121 native.genrule(
122 name = "gen_%s" % (bitcode_out),
bjacob041b4e82023-05-30 19:59:26 -0400123 srcs = [src, builtin_headers_dep] + internal_hdrs,
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800124 outs = [bitcode_out],
125 cmd = " && ".join([
126 " ".join([
127 "$(location %s)" % (clang_tool),
MaheshRavishankar29647b32023-05-19 10:54:42 -0700128 "-isystem $(BINDIR)/%s" % builtin_headers_path,
bjacob041b4e82023-05-30 19:59:26 -0400129 " ".join(base_copts + copts),
MaheshRavishankar29647b32023-05-19 10:54:42 -0700130 " ".join(["-I $(BINDIR)/runtime/src"]),
131 " ".join(["-I runtime/src"]),
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800132 "-o $(location %s)" % (bitcode_out),
bjacob041b4e82023-05-30 19:59:26 -0400133 "$(location %s)" % (src),
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800134 ]),
135 ]),
bjacob041b4e82023-05-30 19:59:26 -0400136 tools = [
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800137 clang_tool,
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800138 ],
bjacob041b4e82023-05-30 19:59:26 -0400139 message = "Compiling %s to %s..." % (src, bitcode_out),
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800140 output_to_bindir = 1,
141 **kwargs
142 )
143
144 if not out:
145 out = "%s.bc" % (name)
MaheshRavishankar37c79f02023-06-27 11:31:33 -0700146
147 native.genrule(
148 name = name,
149 srcs = bitcode_files,
150 outs = [out],
151 cmd = " && ".join([
152 " ".join([
153 "$(location %s)" % (link_tool),
154 "-o $(location %s)" % (out),
155 " ".join(["$(locations %s)" % (src) for src in bitcode_files]),
156 ]),
157 ]),
158 tools = [link_tool],
159 message = "Linking bitcode library %s to %s..." % (name, out),
160 output_to_bindir = 1,
161 **kwargs
162 )
163
164def iree_cuda_bitcode_library(
165 name,
166 cuda_arch,
167 srcs,
168 internal_hdrs = [],
169 copts = [],
170 out = None,
171 **kwargs):
172 """Builds an LLVM bitcode library for CUDA from an input file via clang.
173
174 Args:
175 name: Name of the target.
176 cuda_arch: Target sm architecture to compile for.
177 srcs: source files to pass to clang.
178 internal_hdrs: all headers transitively included by the source files.
179 Unlike typical Bazel `hdrs`, these are not exposed as
180 interface headers. This would normally be part of `srcs`,
181 but separating it was easier for `bazel_to_cmake`, as
182 CMake does not need this, and making this explicitly
183 Bazel-only allows using `filegroup` on the Bazel side.
184 copts: additional flags to pass to clang.
185 out: output file name (defaults to name.bc).
186 **kwargs: any additional attributes to pass to the underlying rules.
187 """
188
189 clang_tool = "@llvm-project//clang:clang"
190 link_tool = "@llvm-project//llvm:llvm-link"
191 builtin_headers_dep = "@llvm-project//clang:builtin_headers_gen"
192 builtin_headers_path = "external/llvm-project/clang/staging/include/"
193
194 base_copts = [
195 "-x",
196 "cuda",
197
198 # Target architecture
199 "--cuda-gpu-arch=%s" % (cuda_arch),
200
201 # Suppress warnings
202 "-Wno-unknown-cuda-version",
203 "-nocudalib",
204 "--cuda-device-only",
205
206 # Optimized.
207 "-O3",
208
209 # Object file only in bitcode format:
210 "-c",
211 "-emit-llvm",
212 ]
213
214 bitcode_files = []
215 for src in srcs:
216 bitcode_out = "%s_%s.bc" % (name, src)
217 bitcode_files.append(bitcode_out)
218 native.genrule(
219 name = "gen_%s" % (bitcode_out),
220 srcs = [src, builtin_headers_dep] + internal_hdrs,
221 outs = [bitcode_out],
222 cmd = " && ".join([
223 " ".join([
224 "$(location %s)" % (clang_tool),
225 " ".join(base_copts + copts),
226 "-o $(location %s)" % (bitcode_out),
227 "$(location %s)" % (src),
228 ]),
229 ]),
230 tools = [
231 clang_tool,
232 ],
233 message = "Compiling %s to %s..." % (src, bitcode_out),
234 output_to_bindir = 1,
235 **kwargs
236 )
237
238 if not out:
239 out = "%s.bc" % (name)
240
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800241 native.genrule(
242 name = name,
243 srcs = bitcode_files,
244 outs = [out],
245 cmd = " && ".join([
246 " ".join([
247 "$(location %s)" % (link_tool),
248 "-o $(location %s)" % (out),
249 " ".join(["$(locations %s)" % (src) for src in bitcode_files]),
250 ]),
251 ]),
bjacob041b4e82023-05-30 19:59:26 -0400252 tools = [link_tool],
Ben Vanik7f6c57c2023-02-07 18:04:32 -0800253 message = "Linking bitcode library %s to %s..." % (name, out),
254 output_to_bindir = 1,
255 **kwargs
256 )
MaheshRavishankar29647b32023-05-19 10:54:42 -0700257
258def iree_link_bitcode(
259 name,
260 bitcode_files,
261 out = None,
262 link_tool = "@llvm-project//llvm:llvm-link",
263 **kwargs):
264 """Builds an LLVM bitcode library from an input file via clang.
265
266 Args:
267 name: Name of the target.
268 bitcode_files: bitcode files to link together.
269 out: output file name (defaults to name.bc).
270 link_tool: llvm-link tool used for linking bitcode files.
271 **kwargs: any additional attributes to pass to the underlying rules.
272 """
273
Benoit Jacob7d736b52024-01-18 11:54:39 -0500274 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]
MaheshRavishankar29647b32023-05-19 10:54:42 -0700275
276 if not out:
277 out = "%s.bc" % (name)
278 native.genrule(
279 name = name,
280 srcs = bitcode_files_qualified,
281 outs = [out],
282 cmd = " && ".join([
283 " ".join([
284 "$(location %s)" % (link_tool),
285 "-o $(location %s)" % (out),
286 " ".join(["$(locations %s)" % (src) for src in bitcode_files_qualified]),
287 ]),
288 ]),
289 tools = [link_tool],
290 message = "Linking bitcode library %s to %s..." % (name, out),
291 output_to_bindir = 1,
292 **kwargs
293 )