Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion proto/swift_proto_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,18 @@ def _swift_proto_library_impl(ctx):
direct_swift_proto_cc_info = direct_providers.direct_swift_proto_cc_info
direct_swift_info = direct_providers.direct_swift_info
direct_swift_proto_info = direct_providers.direct_swift_proto_info
direct_stats_files = getattr(
direct_output_group_info,
"swift_stats",
depset(),
).to_list()
direct_files = compact(
[module.swift.swiftdoc for module in direct_swift_info.direct_modules] +
[module.swift.swiftinterface for module in direct_swift_info.direct_modules] +
[module.swift.private_swiftinterface for module in direct_swift_info.direct_modules] +
[module.swift.swiftmodule for module in direct_swift_info.direct_modules] +
[module.swift.swiftsourceinfo for module in direct_swift_info.direct_modules],
[module.swift.swiftsourceinfo for module in direct_swift_info.direct_modules] +
direct_stats_files,
)

return [
Expand Down
8 changes: 7 additions & 1 deletion proto/swift_proto_library_group.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,18 @@ def _swift_proto_library_group_impl(ctx):
direct_swift_proto_cc_info = proto_target[SwiftProtoCcInfo]
direct_swift_info = proto_target[SwiftInfo]
direct_swift_proto_info = proto_target[SwiftProtoInfo]
direct_stats_files = getattr(
direct_output_group_info,
"swift_stats",
depset(),
).to_list()
direct_files = compact(
[module.swift.swiftdoc for module in direct_swift_info.direct_modules] +
[module.swift.swiftinterface for module in direct_swift_info.direct_modules] +
[module.swift.private_swiftinterface for module in direct_swift_info.direct_modules] +
[module.swift.swiftmodule for module in direct_swift_info.direct_modules] +
[module.swift.swiftsourceinfo for module in direct_swift_info.direct_modules],
[module.swift.swiftsourceinfo for module in direct_swift_info.direct_modules] +
direct_stats_files,
)

return [
Expand Down
18 changes: 18 additions & 0 deletions swift/internal/compiling.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ load(
"SWIFT_FEATURE_EMIT_BC",
"SWIFT_FEATURE_EMIT_C_MODULE",
"SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE",
"SWIFT_FEATURE_EMIT_STATS",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
"SWIFT_FEATURE_ENABLE_EMBEDDED",
Expand Down Expand Up @@ -567,6 +568,9 @@ def compile(
represents the location where macro expansion files were written
(only in debug/fastbuild and only when the toolchain supports
macros).

* `stats_directory`: A directory-type `File` that represents the
location where Swift compilation statistics were written.
"""
toolchains = gather_toolchains(
swift_toolchain = swift_toolchain,
Expand Down Expand Up @@ -658,6 +662,7 @@ def compile(
if split_derived_file_generation:
all_compile_outputs = compact([
compile_outputs.indexstore_directory,
compile_outputs.stats_directory,
]) + compile_outputs.object_files + compile_outputs.const_values_files
all_derived_outputs = compact([
# The `.swiftmodule` file is explicitly listed as the first output
Expand Down Expand Up @@ -686,6 +691,7 @@ def compile(
compile_outputs.generated_header_file,
compile_outputs.indexstore_directory,
compile_outputs.macro_expansion_directory,
compile_outputs.stats_directory,
]) + compile_outputs.object_files + compile_outputs.const_values_files
all_derived_outputs = []

Expand Down Expand Up @@ -960,6 +966,7 @@ to use swift_common.compile(include_dev_srch_paths = ...) instead.\
const_values_files = compile_outputs.const_values_files,
indexstore_directory = compile_outputs.indexstore_directory,
macro_expansion_directory = compile_outputs.macro_expansion_directory,
stats_directory = compile_outputs.stats_directory,
),
swift_info = SwiftInfo(
modules = [module_context],
Expand Down Expand Up @@ -1523,6 +1530,16 @@ def _declare_compile_outputs(
indexstore_directory = None
include_index_unit_paths = False

if is_feature_enabled(
feature_configuration = feature_configuration,
feature_name = SWIFT_FEATURE_EMIT_STATS,
):
stats_directory = actions.declare_directory(
"{}.swift-stats".format(target_name),
)
else:
stats_directory = None

if not output_nature.emits_multiple_objects:
# If we're emitting a single object, we don't use an object map; we just
# declare the output file that the compiler will generate and there are
Expand Down Expand Up @@ -1607,6 +1624,7 @@ def _declare_compile_outputs(
object_files = object_files,
output_file_map = output_file_map,
derived_files_output_file_map = derived_files_output_file_map,
stats_directory = stats_directory,
swiftdoc_file = swiftdoc_file,
swiftinterface_file = swiftinterface_file,
swiftmodule_file = swiftmodule_file,
Expand Down
4 changes: 4 additions & 0 deletions swift/internal/feature_names.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,10 @@ SWIFT_FEATURE_SUPPRESS_WARNINGS = "swift.suppress_warnings"
# Pass -warnings-as-errors to the compiler.
SWIFT_FEATURE_TREAT_WARNINGS_AS_ERRORS = "swift.treat_warnings_as_errors"

# If enabled, Swift compilation actions emit unified compilation statistics into
# a declared output directory.
SWIFT_FEATURE_EMIT_STATS = "swift.emit_stats"

# A feature that adds target_name in output path to support building
# multiple frameworks with different target name, but same module name.
SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT = "swift.add_target_name_to_output"
Expand Down
6 changes: 6 additions & 0 deletions swift/internal/output_groups.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def supplemental_compilation_output_groups(
const_values_files = []
indexstore_files = list(additional_indexstore_files)
macro_expansions_files = []
stats_files = []

for outputs in supplemental_outputs:
if outputs.ast_files:
Expand All @@ -49,6 +50,9 @@ def supplemental_compilation_output_groups(
indexstore_files.append(outputs.indexstore_directory)
if outputs.macro_expansion_directory:
macro_expansions_files.append(outputs.macro_expansion_directory)
stats_directory = getattr(outputs, "stats_directory", None)
if stats_directory:
stats_files.append(stats_directory)

output_groups = {}
if ast_files:
Expand All @@ -59,4 +63,6 @@ def supplemental_compilation_output_groups(
output_groups["swift_index_store"] = depset(indexstore_files)
if macro_expansions_files:
output_groups["macro_expansions"] = depset(macro_expansions_files)
if stats_files:
output_groups["swift_stats"] = depset(stats_files)
return output_groups
9 changes: 8 additions & 1 deletion swift/swift_binary.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ load(
)
load(
"//swift/internal:utils.bzl",
"compact",
"expand_locations",
"get_providers",
"include_developer_search_paths",
Expand Down Expand Up @@ -88,6 +89,7 @@ def _swift_binary_impl(ctx):
output_groups = {}
module_contexts = []
additional_linking_contexts = []
default_compile_outputs = []

# If the binary has sources, compile those first and collect the outputs to
# be passed to the linker.
Expand Down Expand Up @@ -134,6 +136,9 @@ def _swift_binary_impl(ctx):
output_groups = supplemental_compilation_output_groups(
supplemental_outputs,
)
default_compile_outputs = compact([
supplemental_outputs.stats_directory,
])
else:
compile_result = None
entry_point_function_name = None
Expand Down Expand Up @@ -196,7 +201,9 @@ def _swift_binary_impl(ctx):
DefaultInfo(
executable = linking_outputs.executable,
files = depset(
[linking_outputs.executable] + additional_debug_outputs,
[linking_outputs.executable] +
additional_debug_outputs +
default_compile_outputs,
),
runfiles = ctx.runfiles(
collect_data = True,
Expand Down
8 changes: 7 additions & 1 deletion swift/swift_compiler_plugin.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ load(
)
load(
"//swift/internal:utils.bzl",
"compact",
"expand_locations",
"get_providers",
)
Expand Down Expand Up @@ -112,6 +113,9 @@ def _swift_compiler_plugin_impl(ctx):
module_contexts.append(module_context)
compilation_outputs = compile_result.compilation_outputs
supplemental_outputs = compile_result.supplemental_outputs
default_compile_outputs = compact([
supplemental_outputs.stats_directory,
])

# Apply the optional debugging outputs extension if the toolchain defines
# one.
Expand Down Expand Up @@ -189,7 +193,9 @@ def _swift_compiler_plugin_impl(ctx):
DefaultInfo(
executable = binary_linking_outputs.executable,
files = depset(
[binary_linking_outputs.executable] + additional_debug_outputs,
[binary_linking_outputs.executable] +
additional_debug_outputs +
default_compile_outputs,
),
runfiles = ctx.runfiles(
collect_data = True,
Expand Down
1 change: 1 addition & 0 deletions swift/swift_library.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ def _swift_library_impl(ctx):
module_context.swift.private_swiftinterface,
module_context.swift.swiftmodule,
module_context.swift.swiftsourceinfo,
supplemental_outputs.stats_directory,
linking_output.library_to_link.static_library,
linking_output.library_to_link.pic_static_library,
])
Expand Down
9 changes: 8 additions & 1 deletion swift/swift_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ load(
)
load(
"//swift/internal:utils.bzl",
"compact",
"expand_locations",
"get_providers",
"include_developer_search_paths",
Expand Down Expand Up @@ -496,12 +497,18 @@ def _swift_test_impl(ctx):
{"TEST_BINARIES_FOR_LLVM_COV": linking_outputs.executable.short_path},
expanded_env.get_expanded_env(ctx, {}),
)
default_compile_outputs = compact([
getattr(outputs, "stats_directory", None)
for outputs in all_supplemental_outputs
])

return [
DefaultInfo(
executable = linking_outputs.executable,
files = depset(
[linking_outputs.executable] + additional_debug_outputs,
[linking_outputs.executable] +
additional_debug_outputs +
default_compile_outputs,
),
runfiles = ctx.runfiles(
collect_data = True,
Expand Down
16 changes: 16 additions & 0 deletions swift/toolchains/config/compile_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ load(
"SWIFT_FEATURE_EMIT_BC",
"SWIFT_FEATURE_EMIT_C_MODULE",
"SWIFT_FEATURE_EMIT_PRIVATE_SWIFTINTERFACE",
"SWIFT_FEATURE_EMIT_STATS",
"SWIFT_FEATURE_EMIT_SWIFTDOC",
"SWIFT_FEATURE_EMIT_SWIFTINTERFACE",
"SWIFT_FEATURE_ENABLE_BARE_SLASH_REGEX",
Expand Down Expand Up @@ -283,6 +284,13 @@ def compile_action_configs(
configurators = [_constant_value_extraction_configurator],
),

# Configure compiler statistics output.
ActionConfigInfo(
actions = [SWIFT_ACTION_COMPILE],
configurators = [_stats_output_configurator],
features = [SWIFT_FEATURE_EMIT_STATS],
),

# Link Time Optimization (LTO).
ActionConfigInfo(
actions = all_compile_action_names(),
Expand Down Expand Up @@ -2398,6 +2406,14 @@ def _constant_value_extraction_configurator(prerequisites, args):
inputs = [prerequisites.const_gather_protocols_file],
)

def _stats_output_configurator(prerequisites, args):
"""Adds flags related to Swift compile statistics output."""
args.add(
"-Xwrapped-swift=-stats-output-dir={}".format(
prerequisites.stats_directory.path,
),
)

def _upcoming_and_experimental_features_configurator(prerequisites, args):
"""Adds upcoming and experimental features to the command line."""
args.add_all(
Expand Down
3 changes: 3 additions & 0 deletions test/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ load(":private_deps_tests.bzl", "private_deps_test_suite")
load(":private_swiftinterface_tests.bzl", "private_swiftinterface_test_suite")
load(":runtime_deps_tests.bzl", "runtime_deps_test_suite")
load(":split_derived_files_tests.bzl", "split_derived_files_test_suite")
load(":stats_output_tests.bzl", "stats_output_test_suite")
load(":swift_binary_linking_tests.bzl", "swift_binary_linking_test_suite")
load(":swift_through_non_swift_tests.bzl", "swift_through_non_swift_test_suite")
load(":swift_toolchain_tests.bzl", "swift_toolchain_test_suite")
Expand Down Expand Up @@ -75,6 +76,8 @@ private_deps_test_suite(name = "private_deps")

split_derived_files_test_suite(name = "split_derived_files")

stats_output_test_suite(name = "stats_output")

swift_binary_linking_test_suite(name = "swift_binary_rules")

swift_through_non_swift_test_suite(name = "swift_through_non_swift")
Expand Down
87 changes: 87 additions & 0 deletions test/stats_output_tests.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""Tests for `swift.emit_stats`."""

load(
"//test/rules:action_command_line_test.bzl",
"action_command_line_test",
"make_action_command_line_test_rule",
)
load(
"//test/rules:provider_test.bzl",
"make_provider_test_rule",
)

stats_output_command_line_test = make_action_command_line_test_rule(
config_settings = {
"//command_line_option:features": [
"swift.emit_stats",
],
},
)

stats_output_provider_test = make_provider_test_rule(
config_settings = {
"//command_line_option:features": [
"swift.emit_stats",
],
},
)

def stats_output_test_suite(name, tags = []):
"""Test suite for Swift stats output.

Args:
name: The base name to be used in targets created by this macro.
tags: Additional tags to apply to each test.
"""
all_tags = [name] + tags

action_command_line_test(
name = "{}_disabled_by_default".format(name),
mnemonic = "SwiftCompile",
not_expected_argv = [
"-stats-output-dir",
],
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)

stats_output_command_line_test(
name = "{}_command_line".format(name),
expected_argv = [
"-Xwrapped-swift=-stats-output-dir=$(BIN_DIR)/test/fixtures/debug_settings/simple.swift-stats",
],
mnemonic = "SwiftCompile",
not_expected_argv = [
"-trace-stats-events",
],
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)

stats_output_provider_test(
name = "{}_default_files".format(name),
expected_files = [
"test/fixtures/debug_settings/simple.swift-stats",
"*",
],
field = "files",
provider = "DefaultInfo",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)

stats_output_provider_test(
name = "{}_output_group".format(name),
expected_files = [
"test/fixtures/debug_settings/simple.swift-stats",
],
field = "swift_stats",
provider = "OutputGroupInfo",
tags = all_tags,
target_under_test = "//test/fixtures/debug_settings:simple",
)

native.test_suite(
name = name,
tags = all_tags,
)
Loading