Skip to content

Commit 202e8d5

Browse files
grebecopybara-github
authored andcommitted
Shard output of cpp transpiler.
Large designs can lead to huge, slow-to-build c++ sources. This change produces one file per type. PiperOrigin-RevId: 870023245
1 parent 17525eb commit 202e8d5

35 files changed

+1816
-1108
lines changed

docs_src/bazel_rules_macros.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -825,8 +825,8 @@ xls_dslx_cpp_type_library(
825825

826826
```
827827
828-
will generate b_cpp_types_generate.cc and b_cpp_types_generate.h, and package them into a
829-
cc_library under the namespace "::xls::b".
828+
will generate (potentially many) c++ sources in _gen_b_cpp_types_generate_srcs/ as well as
829+
b_cpp_types_generate.h, and package them into a cc_library under the namespace "::xls::b".
830830
831831
If another DSLX library `a.x` depends on types in `:b_dslx`, the `xls_dslx_cpp_type_library` for
832832
`a` should explicitly depend on the C++ library above and use the same parent namespace:

xls/build_rules/xls_dslx_rules.bzl

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ def _xls_dslx_generate_cpp_type_files_impl(ctx):
724724
dslx_path = ":${PWD}:" + ctx.genfiles_dir.path + ":" + ctx.bin_dir.path + dslx_srcs_wsroot_path + wsroot_dslx_path
725725

726726
# Make arguments for the cpp_transpiler tool.
727-
cc_file = ctx.outputs.source_file
727+
cc_source_dir = ctx.actions.declare_directory(ctx.label.name + "_srcs")
728728
h_file = ctx.outputs.header_file
729729

730730
include_header_files = []
@@ -740,7 +740,7 @@ def _xls_dslx_generate_cpp_type_files_impl(ctx):
740740

741741
my_args.add(src.path)
742742

743-
my_args.add("--output_source_path={}".format(cc_file.path))
743+
my_args.add("--output_source_path_prefix={}/{}".format(cc_source_dir.path, h_file.basename.removesuffix(_H_FILE_EXTENSION)))
744744
my_args.add("--output_header_path={}".format(h_file.path))
745745
my_args.add("--dslx_path=={}".format(dslx_path))
746746
my_args.add_joined("--include_headers", include_header_files, join_with = ",")
@@ -749,7 +749,7 @@ def _xls_dslx_generate_cpp_type_files_impl(ctx):
749749
my_args.add("--namespaces={}".format(ctx.attr.namespace))
750750

751751
ctx.actions.run(
752-
outputs = [cc_file, h_file],
752+
outputs = [cc_source_dir, h_file],
753753
tools = [cpp_transpiler_tool],
754754
# The files required for converting the DSLX source file.
755755
inputs = runfiles.files,
@@ -763,7 +763,7 @@ def _xls_dslx_generate_cpp_type_files_impl(ctx):
763763
return [
764764
DefaultInfo(
765765
files = depset(
766-
direct = [cc_file, h_file],
766+
direct = [cc_source_dir, h_file],
767767
transitive = get_transitive_built_files_for_xls(ctx),
768768
),
769769
runfiles = runfiles,
@@ -775,11 +775,6 @@ xls_dslx_generate_cpp_type_files_attrs = {
775775
doc = "Direct cc_library dependencies that should be included in the generated C++ files.",
776776
),
777777
"namespace": attr.string(doc = "The C++ namespace to generate the code in (e.g., `foo::bar`)."),
778-
"source_file": attr.output(
779-
doc = "The filename of the generated source file. The filename must " +
780-
"have a '" + _CC_FILE_EXTENSION + "' extension.",
781-
mandatory = True,
782-
),
783778
"header_file": attr.output(
784779
doc = "The filename of the generated header file. The filename must " +
785780
"have a '" + _H_FILE_EXTENSION + "' extension.",
@@ -798,7 +793,6 @@ Example:
798793
name = "b_cpp_types_generate",
799794
srcs = ["b.x"],
800795
deps = [":a_dslx"],
801-
source_file = "b_cpp_types.cc",
802796
header_file = "b_cpp_types.h",
803797
namespace = "xls",
804798
)

xls/build_rules/xls_macros.bzl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,8 @@ def xls_dslx_cpp_type_library(
401401
402402
```
403403
404-
will generate b_cpp_types_generate.cc and b_cpp_types_generate.h, and package them into a
405-
cc_library under the namespace "::xls::b".
404+
will generate (potentially many) c++ sources in _gen_b_cpp_types_generate_srcs/ as well as
405+
b_cpp_types_generate.h, and package them into a cc_library under the namespace "::xls::b".
406406
407407
If another DSLX library `a.x` depends on types in `:b_dslx`, the `xls_dslx_cpp_type_library` for
408408
`a` should explicitly depend on the C++ library above and use the same parent namespace:
@@ -426,19 +426,21 @@ def xls_dslx_cpp_type_library(
426426
strongly encouraged to avoid polluting top-level namespaces per
427427
https://google.github.io/styleguide/cppguide.html#Namespace_Names.
428428
"""
429+
generated_sources_name = "_gen_" + name
429430
xls_dslx_generate_cpp_type_files(
430-
name = name + "_generate_sources",
431+
name = generated_sources_name,
431432
srcs = [src],
432-
source_file = name + ".cc",
433433
header_file = name + ".h",
434-
deps = deps,
435434
cpp_deps = cpp_deps,
435+
deps = deps,
436436
namespace = namespace,
437437
)
438438
cc_library(
439439
name = name,
440-
srcs = [":" + name + ".cc"],
440+
srcs = [":" + generated_sources_name],
441441
hdrs = [":" + name + ".h"],
442+
# TODO: bazelbuild/bazel#14843 - Remove this once no longer needed.
443+
linkstatic = True,
442444
deps = [
443445
"@com_google_absl//absl/base:core_headers",
444446
"@com_google_absl//absl/status:status",

xls/dslx/cpp_transpiler/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ cc_test(
113113
]),
114114
deps = [
115115
":cpp_transpiler",
116-
":cpp_type_generator",
117116
"//xls/common:golden_files",
118117
"//xls/common:source_location",
119118
"//xls/common:xls_gunit_main",
@@ -124,6 +123,7 @@ cc_test(
124123
"@com_google_absl//absl/status",
125124
"@com_google_absl//absl/status:status_matchers",
126125
"@com_google_absl//absl/strings:str_format",
126+
"@com_google_absl//absl/types:span",
127127
"@googletest//:gtest",
128128
],
129129
)
@@ -134,10 +134,10 @@ cc_binary(
134134
visibility = ["//xls:xls_public"],
135135
deps = [
136136
":cpp_transpiler",
137-
":cpp_type_generator",
138137
"//xls/common:exit_status",
139138
"//xls/common:init_xls",
140139
"//xls/common/file:filesystem",
140+
"//xls/common/status:ret_check",
141141
"//xls/common/status:status_macros",
142142
"//xls/dslx:create_import_data",
143143
"//xls/dslx:default_dslx_stdlib_path",

xls/dslx/cpp_transpiler/cpp_transpiler.cc

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <memory>
1919
#include <string>
2020
#include <string_view>
21+
#include <utility>
2122

2223
#include "absl/status/statusor.h"
2324
#include "absl/strings/ascii.h"
@@ -35,7 +36,7 @@
3536

3637
namespace xls::dslx {
3738

38-
absl::StatusOr<CppSource> TranspileToCpp(
39+
absl::StatusOr<CppSourceGroup> TranspileToCpp(
3940
Module* module, ImportData* import_data,
4041
absl::Span<const std::string> additional_include_headers,
4142
std::string_view output_header_path, std::string_view namespaces) {
@@ -76,7 +77,9 @@ absl::StatusOr<CppSource> TranspileToCpp(
7677
#include "xls/public/status_macros.h"
7778
#include "xls/public/value.h"
7879
79-
[[maybe_unused]] static bool FitsInNBitsSigned(int64_t value, int64_t n) {
80+
namespace {
81+
82+
[[maybe_unused]] bool FitsInNBitsSigned(int64_t value, int64_t n) {
8083
// All bits from [n - 1, 64) must be all zero or all ones.
8184
if (n >= 64) {
8285
return true;
@@ -88,17 +91,19 @@ absl::StatusOr<CppSource> TranspileToCpp(
8891
(mask & value_as_unsigned) == mask;
8992
}
9093
91-
[[maybe_unused]] static bool FitsInNBitsUnsigned(uint64_t value, int64_t n) {
94+
[[maybe_unused]] bool FitsInNBitsUnsigned(uint64_t value, int64_t n) {
9295
if (n >= 64) {
9396
return true;
9497
}
9598
return value < (uint64_t{1} << n);
9699
}
97100
98-
[[maybe_unused]] static std::string __indent(int64_t amount) {
101+
[[maybe_unused]] std::string __indent(int64_t amount) {
99102
return std::string(amount * 2, ' ');
100103
}
101104
105+
} // namespace
106+
102107
%s%s%s
103108
)";
104109
XLS_ASSIGN_OR_RETURN(TypeInfo * type_info,
@@ -139,13 +144,17 @@ absl::StatusOr<CppSource> TranspileToCpp(
139144
absl::StrAppend(&include_headers, "#include \"", header, "\"\n");
140145
}
141146

142-
return CppSource{
143-
absl::Substitute(kHeaderTemplate, header_guard,
144-
absl::StrJoin(header, "\n\n"), namespace_begin,
145-
namespace_end, include_headers),
146-
absl::StrFormat(kSourceTemplate, output_header_path, include_headers,
147-
namespace_begin, absl::StrJoin(source, "\n\n"),
148-
namespace_end)};
147+
for (std::string& src : source) {
148+
src = absl::StrFormat(kSourceTemplate, output_header_path, include_headers,
149+
namespace_begin, src, namespace_end);
150+
}
151+
std::string header_text = absl::Substitute(
152+
kHeaderTemplate, header_guard, absl::StrJoin(header, "\n\n"),
153+
namespace_begin, namespace_end, include_headers);
154+
return CppSourceGroup{
155+
.header = std::move(header_text),
156+
.source = std::move(source),
157+
};
149158
}
150159

151160
} // namespace xls::dslx

xls/dslx/cpp_transpiler/cpp_transpiler.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,21 @@
1616

1717
#include <string>
1818
#include <string_view>
19+
#include <vector>
1920

2021
#include "absl/status/statusor.h"
2122
#include "absl/types/span.h"
22-
#include "xls/dslx/cpp_transpiler/cpp_type_generator.h"
2323
#include "xls/dslx/frontend/ast.h"
2424
#include "xls/dslx/import_data.h"
2525

2626
namespace xls::dslx {
2727

28+
// A group of C++ sources which all share the same header.
29+
struct CppSourceGroup {
30+
std::string header;
31+
std::vector<std::string> source;
32+
};
33+
2834
// Converts DSLX types contained inside of "module" into their C++ equivalents.
2935
// For enums and constant declarations, this simply dumps the elements into the
3036
// returned text, using the smallest containing type for the latter, e.g., a
@@ -40,7 +46,7 @@ namespace xls::dslx {
4046
// should be infrequent, so users should feel comfortable using these
4147
// interfaces, but should also be aware of the potential for change in the
4248
// future.
43-
absl::StatusOr<CppSource> TranspileToCpp(
49+
absl::StatusOr<CppSourceGroup> TranspileToCpp(
4450
Module* module, ImportData* import_data,
4551
absl::Span<const std::string> additional_include_headers,
4652
std::string_view output_header_path, std::string_view namespaces = "");

xls/dslx/cpp_transpiler/cpp_transpiler_main.cc

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@
2222
#include "absl/log/check.h"
2323
#include "absl/log/log.h"
2424
#include "absl/status/status.h"
25+
#include "absl/strings/str_cat.h"
2526
#include "absl/strings/str_split.h"
2627
#include "absl/types/span.h"
2728
#include "xls/common/exit_status.h"
2829
#include "xls/common/file/filesystem.h"
2930
#include "xls/common/init_xls.h"
31+
#include "xls/common/status/ret_check.h"
3032
#include "xls/common/status/status_macros.h"
3133
#include "xls/dslx/cpp_transpiler/cpp_transpiler.h"
32-
#include "xls/dslx/cpp_transpiler/cpp_type_generator.h"
3334
#include "xls/dslx/create_import_data.h"
3435
#include "xls/dslx/default_dslx_stdlib_path.h"
3536
#include "xls/dslx/import_data.h"
@@ -40,8 +41,9 @@
4041
ABSL_FLAG(std::vector<std::string>, include_headers, {}, "Include headers.");
4142
ABSL_FLAG(std::string, output_header_path, "",
4243
"Path at which to write the generated header.");
43-
ABSL_FLAG(std::string, output_source_path, "",
44-
"Path at which to write the generated source.");
44+
ABSL_FLAG(std::string, output_source_path_prefix, "",
45+
"Path at which to write the generated sources (suffix of .<index>.cc "
46+
"will be added).");
4547
ABSL_FLAG(std::string, namespaces, "",
4648
"Double-colon-delimited namespaces with which to wrap the "
4749
"generated code, e.g., \"my::namespace\" (note: no leading `::`).");
@@ -69,7 +71,7 @@ absl::Status RealMain(const std::filesystem::path& module_path,
6971
absl::Span<const std::filesystem::path> dslx_paths,
7072
absl::Span<const std::string> include_headers,
7173
std::string_view output_header_path,
72-
std::string_view output_source_path,
74+
std::string_view output_source_path_prefix,
7375
std::string_view namespaces) {
7476
XLS_ASSIGN_OR_RETURN(std::string module_text, GetFileContents(module_path));
7577

@@ -81,12 +83,16 @@ absl::Status RealMain(const std::filesystem::path& module_path,
8183
ParseAndTypecheck(module_text, std::string(module_path),
8284
module_path.stem().string(), &import_data));
8385
XLS_ASSIGN_OR_RETURN(
84-
CppSource sources,
86+
CppSourceGroup sources,
8587
TranspileToCpp(module.module, &import_data, include_headers,
8688
output_header_path, std::string(namespaces)));
89+
XLS_RET_CHECK_GT(sources.source.size(), 0);
8790

8891
XLS_RETURN_IF_ERROR(SetFileContents(output_header_path, sources.header));
89-
XLS_RETURN_IF_ERROR(SetFileContents(output_source_path, sources.source));
92+
for (int i = 0; i < sources.source.size(); ++i) {
93+
XLS_RETURN_IF_ERROR(SetFileContents(
94+
absl::StrCat(output_source_path_prefix, i, ".cc"), sources.source[i]));
95+
}
9096
return absl::OkStatus();
9197
}
9298

@@ -104,9 +110,10 @@ int main(int argc, char* argv[]) {
104110
std::string output_header_path = absl::GetFlag(FLAGS_output_header_path);
105111
QCHECK(!output_header_path.empty())
106112
<< "--output_header_path must be specified.";
107-
std::string output_source_path = absl::GetFlag(FLAGS_output_source_path);
108-
QCHECK(!output_source_path.empty())
109-
<< "--output_source_path must be specified.";
113+
std::string output_source_path_prefix =
114+
absl::GetFlag(FLAGS_output_source_path_prefix);
115+
QCHECK(!output_source_path_prefix.empty())
116+
<< "--output_source_path_prefix must be specified.";
110117

111118
std::string dslx_path = absl::GetFlag(FLAGS_dslx_path);
112119
std::vector<std::string> dslx_path_strs = absl::StrSplit(dslx_path, ':');
@@ -120,7 +127,7 @@ int main(int argc, char* argv[]) {
120127
return xls::ExitStatus(xls::dslx::RealMain(
121128
args[0], absl::GetFlag(FLAGS_dslx_stdlib_path), dslx_paths,
122129
absl::GetFlag(FLAGS_include_headers), output_header_path,
123-
output_source_path, absl::GetFlag(FLAGS_namespaces)));
130+
output_source_path_prefix, absl::GetFlag(FLAGS_namespaces)));
124131

125132
return 0;
126133
}

0 commit comments

Comments
 (0)