1"""BUILD extensions for MLIR table generation."""
2
3def gentbl(name, tblgen, td_file, tbl_outs, td_srcs = [], td_includes = [], td_relative_includes = [], strip_include_prefix = None, test = False, **kwargs):
4    """gentbl() generates tabular code from a table definition file.
5
6    Args:
7      name: The name of the build rule for use in dependencies.
8      tblgen: The binary used to produce the output.
9      td_file: The primary table definitions file.
10      tbl_outs: A list of tuples (opts, out), where each opts is a string of
11        options passed to tblgen, and the out is the corresponding output file
12        produced.
13      td_srcs: A list of table definition files included transitively.
14      td_includes: A list of include paths for relative includes, provided as build targets.
15      td_relative_includes: A list of include paths for relative includes, provided as relative path.
16      strip_include_prefix: Attribute to pass through to cc_library.
17      test: Whether to create a test to invoke the tool too.
18      **kwargs: Extra keyword arguments to pass to native rules such as cc_library below.
19    """
20    srcs = []
21    srcs += td_srcs
22    if td_file not in td_srcs:
23        srcs += [td_file]
24
25    td_includes_cmd = [
26        "-I external/llvm-project/mlir/include -I external/org_tensorflow",
27        "-I $(GENDIR)/external/llvm-project/mlir/include -I $(GENDIR)/external/org_tensorflow",
28    ]
29    for td_include in td_includes:
30        td_includes_cmd += [
31            "-I%s" % td_include,
32            "-I$(GENDIR)/%s" % td_include,
33        ]
34    for td_include in td_relative_includes:
35        td_includes_cmd += [
36            "-I%s/%s -Iexternal/org_tensorflow/%s/%s" % (native.package_name(), td_include, native.package_name(), td_include),
37            "-I$(GENDIR)/%s/%s" % (native.package_name(), td_include),
38        ]
39
40    local_inc = "-I $$(dirname $(location %s))" % td_file
41
42    if test:
43        # Rule to generate shell script to invoke tblgen. This generates a very
44        # bare shell file which the sh_test uses.
45        native.genrule(
46            name = "%s_genrule_sh" % name,
47            srcs = srcs,
48            outs = ["%s.gen.sh" % name],
49            cmd = ("echo \"\\$$1\" %s \\$${@:2} -o /dev/null > $@" % local_inc),
50            executable = 1,
51            **kwargs
52        )
53
54    for (opts, out) in tbl_outs:
55        # All arguments to generate the output except output destination.
56        base_args = [
57            "$(location %s)" % tblgen,
58            "%s" % opts,
59            "$(location %s)" % td_file,
60            "-I$(GENDIR)",
61        ] + td_includes_cmd
62        first_opt = opts.split(" ", 1)[0]
63        rule_suffix = "_{}_{}".format(first_opt.replace("-", "_").replace("=", "_"), str(hash(opts)))
64
65        # Rule to generate code using generated shell script.
66        native.genrule(
67            name = "%s_%s_genrule" % (name, rule_suffix),
68            srcs = srcs,
69            outs = [out],
70            tools = [tblgen],
71            message = "Generating code from table: %s" % td_file,
72            cmd = (" ".join(base_args) + " %s -o $@" % local_inc),
73            **kwargs
74        )
75
76        # Optionally generate rule to test tblgen invocation.
77        # Disable these on windows, because $(location ...) does not seem to
78        # work as expected on windows.
79        if test:
80            native.sh_test(
81                name = "%s_%s_genrule_test" % (name, rule_suffix),
82                srcs = ["%s.gen.sh" % name],
83                args = base_args,
84                data = srcs + [tblgen],
85                tags = ["no_windows"],
86                **kwargs
87            )
88
89    # List of opts that do not generate cc files.
90    skip_opts = ["-gen-op-doc"]
91    hdrs = [f for (opts, f) in tbl_outs if opts not in skip_opts]
92    native.cc_library(
93        name = name,
94        # include_prefix does not apply to textual_hdrs.
95        hdrs = hdrs if strip_include_prefix else [],
96        strip_include_prefix = strip_include_prefix,
97        textual_hdrs = hdrs,
98        **kwargs
99    )
100