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 @@ -6,6 +6,7 @@ load(":tblgen.bzl", "gentbl") load(":config.bzl", "llvm_config_defines") load(":targets.bzl", "llvm_targets") +load(":enum_targets_gen.bzl", "enum_targets_gen") load(":binary_alias.bzl", "binary_alias") package( @@ -24,22 +25,20 @@ "$(STACK_FRAME_UNLIMITED)", ] -template_rule( +enum_targets_gen( name = "targets_def_gen", src = "include/llvm/Config/Targets.def.in", out = "include/llvm/Config/Targets.def", - substitutions = { - "@LLVM_ENUM_TARGETS@": "\n".join(["LLVM_TARGET({})".format(t) for t in llvm_targets]), - }, + macro_name = "TARGET", + targets = llvm_targets, ) -template_rule( +enum_targets_gen( name = "asm_printers_def_gen", src = "include/llvm/Config/AsmPrinters.def.in", out = "include/llvm/Config/AsmPrinters.def", - substitutions = { - "@LLVM_ENUM_ASM_PRINTERS@": "\n".join(["LLVM_ASM_PRINTER({})".format(t) for t in llvm_targets]), - }, + macro_name = "ASM_PRINTER", + targets = llvm_targets, ) # List of targets with ASM parsers, filtered to our list of overall targets. @@ -57,13 +56,12 @@ "X86", ] if t in llvm_targets] -template_rule( +enum_targets_gen( name = "asm_parsers_def_gen", src = "include/llvm/Config/AsmParsers.def.in", out = "include/llvm/Config/AsmParsers.def", - substitutions = { - "@LLVM_ENUM_ASM_PARSERS@": "\n".join(["LLVM_ASM_PARSER({})".format(t) for t in llvm_target_asm_parsers]), - }, + macro_name = "ASM_PARSER", + targets = llvm_target_asm_parsers, ) # List of targets with disassemblers, filtered to our list of overall targets. @@ -81,13 +79,12 @@ "X86", ] if t in llvm_targets] -template_rule( +enum_targets_gen( name = "disassemblers_def_gen", src = "include/llvm/Config/Disassemblers.def.in", out = "include/llvm/Config/Disassemblers.def", - substitutions = { - "@LLVM_ENUM_DISASSEMBLERS@": "\n".join(["LLVM_DISASSEMBLER({})".format(t) for t in llvm_target_disassemblers]), - }, + macro_name = "DISASSEMBLER", + targets = llvm_target_disassemblers, ) # TODO: Need to replace this with something that actually extracts the git diff --git a/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl b/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl new file mode 100644 --- /dev/null +++ b/utils/bazel/llvm-project-overlay/llvm/enum_targets_gen.bzl @@ -0,0 +1,64 @@ +# 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 rule to expand LLVM target enumerations. + +Replaces in a text file a single variable of the style `@LLVM_ENUM_FOOS@` with a +list of macro invocations, one for each target on its own line: + +``` +LLVM_FOO(TARGET1) +LLVM_FOO(TARGET2) +// ... +``` + +Example: +load(":enum_targets_gen.bzl", "enum_targets_gen") + +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, +) + +This rule provides a slightly more semantic API than template_rule, but the main +reason it exists is to permit a list with selects to be passed for `targets` as +a select is not allowed to be passed to a rule within another data structure. +""" + +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 + ]) + + ctx.actions.expand_template( + template = ctx.file.src, + output = ctx.outputs.out, + substitutions = {to_replace: replacement}, + ) + +enum_targets_gen = rule( + attrs = { + "src": attr.label( + mandatory = True, + allow_single_file = True, + ), + "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" + + " placeholder being replaced `@LLVM_ENUM_{}S@` and of the" + + " macro invocations generated `LLVM_{}(TARGET)`. Should be" + + " all caps and singular, e.g. 'DISASSEMBLER'", + ), + }, + # output_to_genfiles is required for header files. + output_to_genfiles = True, + implementation = enum_targets_gen_impl, +)