diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -2,10 +2,12 @@ # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +load("@bazel_skylib//rules:common_settings.bzl", "string_list_flag") load(":template_rule.bzl", "template_rule") load(":tblgen.bzl", "gentbl") load(":config.bzl", "llvm_config_defines") load(":targets.bzl", "llvm_targets") +load(":target_macros.bzl", "enabled_targets", "targets_with_file") load(":enum_targets_gen.bzl", "enum_targets_gen") load(":binary_alias.bzl", "binary_alias") @@ -25,74 +27,40 @@ "$(STACK_FRAME_UNLIMITED)", ] -enum_targets_gen( - name = "targets_def_gen", - src = "include/llvm/Config/Targets.def.in", - out = "include/llvm/Config/Targets.def", - macro_name = "TARGET", - targets = llvm_targets, +# A command-line flag for restricting the list of LLVM targets to build. +string_list_flag( + name = "targets", + build_setting_default = llvm_targets, ) -# Enabled targets with ASM printers. -llvm_target_asm_printers = [ - t - for t in llvm_targets - if glob(["lib/Target/{}/*AsmPrinter.cpp".format(t)]) +# For each potential LLVM target, a configuration setting for whether that +# target is enabled. +[ + config_setting( + name = "%s_enabled" % target, + flag_values = {":targets": target}, + ) + for target in llvm_targets ] -enum_targets_gen( - name = "asm_printers_def_gen", - src = "include/llvm/Config/AsmPrinters.def.in", - out = "include/llvm/Config/AsmPrinters.def", - macro_name = "ASM_PRINTER", - targets = llvm_target_asm_printers, -) - -# Enabled targets with ASM parsers. -llvm_target_asm_parsers = [ - t - for t in llvm_targets - if glob(["lib/Target/{}/AsmParser/CMakeLists.txt".format(t)]) -] - -enum_targets_gen( - name = "asm_parsers_def_gen", - src = "include/llvm/Config/AsmParsers.def.in", - out = "include/llvm/Config/AsmParsers.def", - macro_name = "ASM_PARSER", - targets = llvm_target_asm_parsers, -) - -# Enabled targets with disassemblers. -llvm_target_disassemblers = [ - t - for t in llvm_targets - if glob(["lib/Target/{}/Disassembler/CMakeLists.txt".format(t)]) -] - -enum_targets_gen( - name = "disassemblers_def_gen", - src = "include/llvm/Config/Disassemblers.def.in", - out = "include/llvm/Config/Disassemblers.def", - macro_name = "DISASSEMBLER", - targets = llvm_target_disassemblers, -) - -# Enabled targets with MCA. -llvm_target_mcas = [ - t - for t in llvm_targets - if glob(["lib/Target/{}/MCA/CMakeLists.txt".format(t)]) +# Replace macros in headers with lists of enabled targets. +[ + enum_targets_gen( + name = name, + src = "include/llvm/Config/{}.def.in".format(path), + out = "include/llvm/Config/{}.def".format(path), + macro_name = macro_name, + valid_targets = targets_with_file(pattern), + targets = ":targets", + ) for name, macro_name, path, pattern in [ + ("targets_def_gen", "TARGET", "Targets", "CMakeLists.txt"), + ("asm_printers_def_gen", "ASM_PRINTER", "AsmPrinters", "*AsmPrinter.cpp"), + ("asm_parsers_def_gen", "ASM_PARSER", "AsmParsers", "AsmParser/CMakeLists.txt"), + ("disassemblers_def_gen", "DISASSEMBLER", "Disassemblers", "Disassembler/CMakeLists.txt"), + ("target_mca_def_gen", "TARGETMCA", "TargetMCAs", "MCA/CMakeLists.txt"), + ] ] -enum_targets_gen( - name = "target_mca_def_gen", - src = "include/llvm/Config/TargetMCAs.def.in", - out = "include/llvm/Config/TargetMCAs.def", - macro_name = "TARGETMCA", - targets = llvm_target_mcas, -) - # TODO: Need to replace this with something that actually extracts the git # commit from the LLVM source (submodule or http_archive). genrule( @@ -2001,37 +1969,25 @@ cc_library( name = "AllTargetsCodeGens", copts = llvm_copts, - deps = [ - target["name"] + "CodeGen" - for target in llvm_target_lib_list - ], + deps = enabled_targets("CodeGen"), ) cc_library( name = "AllTargetsAsmParsers", copts = llvm_copts, - deps = [ - target["name"] + "AsmParser" - for target in llvm_target_lib_list - ], + deps = enabled_targets("AsmParser"), ) cc_library( name = "AllTargetsDisassemblers", copts = llvm_copts, - deps = [ - target["name"] + "Disassembler" - for target in llvm_target_lib_list - ], + deps = enabled_targets("Disassembler"), ) cc_library( name = "AllTargetsMCAs", copts = llvm_copts, - deps = [ - target["name"] + "TargetMCA" - for target in llvm_target_lib_list - ], + deps = enabled_targets("TargetMCA"), ) cc_library( diff --git a/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl b/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl --- a/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl +++ b/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl @@ -29,13 +29,15 @@ a select is not allowed to be passed to a rule within another data structure. """ -def enum_targets_gen_impl(ctx): +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") + +def _enum_targets_gen_impl(ctx): to_replace = "@LLVM_ENUM_{}S@".format(ctx.attr.macro_name) replacement = "\n".join([ - "LLVM_{}({})\n".format(ctx.attr.macro_name, t) - for t in ctx.attr.targets + "LLVM_{}({})".format(ctx.attr.macro_name, t) + for t in ctx.attr.targets[BuildSettingInfo].value + if t in ctx.attr.valid_targets ]) - ctx.actions.expand_template( template = ctx.file.src, output = ctx.outputs.out, @@ -43,13 +45,21 @@ ) enum_targets_gen = rule( + implementation = _enum_targets_gen_impl, attrs = { "src": attr.label( mandatory = True, allow_single_file = True, ), + "valid_targets": attr.string_list( + mandatory = True, + doc = "A list of LLVM targets that are valid for this enum.", + ), + "targets": attr.label( + mandatory = True, + doc = "A configuration of LLVM targets to build.", + ), "out": attr.output(mandatory = True), - "targets": attr.string_list(mandatory = True), "macro_name": attr.string( mandatory = True, doc = "The name of the enumeration. This is the suffix of the" + @@ -60,5 +70,4 @@ }, # output_to_genfiles is required for header files. output_to_genfiles = True, - implementation = enum_targets_gen_impl, ) diff --git a/utils/bazel/llvm-project-overlay/llvm/target_macros.bzl b/utils/bazel/llvm-project-overlay/llvm/target_macros.bzl new file mode 100644 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/llvm/target_macros.bzl @@ -0,0 +1,38 @@ +# This file is 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 + +"""A collection of helper macros for LLVM target selection in BUILD files.""" + +load(":targets.bzl", "llvm_targets") + +def targets_with_file(suffix): + """Find all targets with a file that matches the suffix. + + The sources for LLVM targets are in folders `lib/Target/*`. This macro + finds all targets that contain a file matching the suffix, ie., + `lib/Target//`. + """ + matches = native.glob(["lib/Target/*/{}".format(suffix)]) + return [m.split("/")[2] for m in matches] + +def enabled_targets(pattern): + """Build a list of Bazel targets matching the pattern. + + This macro builds an expression that evaluates to a list of enabled + Bazel targets of the form ``. + """ + # Build a list of selects that either choose the Bazel target or not, + # depending on the `:targets` flag. + selects = [ + select({ + ":%s_enabled" % t: ["{}{}".format(t, pattern)], + "//conditions:default": [], + }) + for t in llvm_targets + ] + # Fold over the selects with "+". + result = selects[0] + for s in selects[1:]: + result += s + return result