From 86589ee7e88748d9406d2bfc88b24b332086123c Mon Sep 17 00:00:00 2001 From: Manuel Burghard Date: Wed, 22 May 2024 20:43:55 +0200 Subject: [PATCH] Add features to enable LTO --- swift/internal/compiling.bzl | 40 ++++++++++++++++++++++++-- swift/internal/feature_names.bzl | 6 ++++ test/compiler_arguments_tests.bzl | 33 +++++++++++++++++++++ test/fixtures/compiler_arguments/BUILD | 6 ++++ test/output_file_map_tests.bzl | 38 ++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 2 deletions(-) diff --git a/swift/internal/compiling.bzl b/swift/internal/compiling.bzl index a9e2fb121..66beb5f09 100644 --- a/swift/internal/compiling.bzl +++ b/swift/internal/compiling.bzl @@ -60,6 +60,7 @@ load( "SWIFT_FEATURE_FASTBUILD", "SWIFT_FEATURE_FILE_PREFIX_MAP", "SWIFT_FEATURE_FULL_DEBUG_INFO", + "SWIFT_FEATURE_FULL_LTO", "SWIFT_FEATURE_GLOBAL_MODULE_CACHE_USES_TMPDIR", "SWIFT_FEATURE_INDEX_WHILE_BUILDING", "SWIFT_FEATURE_LAYERING_CHECK", @@ -75,6 +76,7 @@ load( "SWIFT_FEATURE_SUPPORTS_LIBRARY_EVOLUTION", "SWIFT_FEATURE_SUPPORTS_SYSTEM_MODULE_FLAG", "SWIFT_FEATURE_SYSTEM_MODULE", + "SWIFT_FEATURE_THIN_LTO", "SWIFT_FEATURE_TREAT_WARNINGS_AS_ERRORS", "SWIFT_FEATURE_USE_C_MODULES", "SWIFT_FEATURE_USE_EXPLICIT_SWIFT_MODULE_MAP", @@ -259,7 +261,11 @@ def compile_action_configs( configurators = [ swift_toolchain_config.add_arg("-emit-bc"), ], - features = [SWIFT_FEATURE_EMIT_BC], + features = [ + [SWIFT_FEATURE_EMIT_BC], + [SWIFT_FEATURE_FULL_LTO], + [SWIFT_FEATURE_THIN_LTO], + ], ), # Add the single object file or object file map, whichever is needed. @@ -399,6 +405,24 @@ def compile_action_configs( configurators = [_constant_value_extraction_configurator], features = [SWIFT_FEATURE__SUPPORTS_CONST_VALUE_EXTRACTION], ), + + # Link Time Optimization (LTO) + swift_toolchain_config.action_config( + actions = [swift_action_names.COMPILE], + configurators = [ + swift_toolchain_config.add_arg("-lto=llvm-thin"), + ], + features = [SWIFT_FEATURE_THIN_LTO], + not_features = [SWIFT_FEATURE_FULL_LTO], + ), + swift_toolchain_config.action_config( + actions = [swift_action_names.COMPILE], + configurators = [ + swift_toolchain_config.add_arg("-lto=llvm-full"), + ], + features = [SWIFT_FEATURE_FULL_LTO], + not_features = [SWIFT_FEATURE_THIN_LTO], + ), ] if generated_header_rewriter: @@ -3142,10 +3166,22 @@ def _declare_compile_outputs( # If enabled the compiler will emit LLVM BC files instead of Mach-O object # files. + # LTO implies emitting LLVM BC files, too + + full_lto_enabled = is_feature_enabled( + feature_configuration = feature_configuration, + feature_name = SWIFT_FEATURE_FULL_LTO, + ) + + thin_lto_enabled = is_feature_enabled( + feature_configuration = feature_configuration, + feature_name = SWIFT_FEATURE_THIN_LTO, + ) + emits_bc = is_feature_enabled( feature_configuration = feature_configuration, feature_name = SWIFT_FEATURE_EMIT_BC, - ) + ) or full_lto_enabled or thin_lto_enabled if not output_nature.emits_multiple_objects: # If we're emitting a single object, we don't use an object map; we just diff --git a/swift/internal/feature_names.bzl b/swift/internal/feature_names.bzl index 642353440..c7f89cad8 100644 --- a/swift/internal/feature_names.bzl +++ b/swift/internal/feature_names.bzl @@ -362,3 +362,9 @@ SWIFT_FEATURE_ADD_TARGET_NAME_TO_OUTPUT = "swift.add_target_name_to_output" # extraction (Swift 5.8 and above). Users should never manually enable, disable, or query this # feature. SWIFT_FEATURE__SUPPORTS_CONST_VALUE_EXTRACTION = "swift._supports_const_value_extraction" + +# Enable thin LTO and update output-file-map correctly +SWIFT_FEATURE_THIN_LTO = "swift.thin_lto" + +# Enable full LTO and update output-file-map correctly +SWIFT_FEATURE_FULL_LTO = "swift.full_lto" diff --git a/test/compiler_arguments_tests.bzl b/test/compiler_arguments_tests.bzl index ae4de94a5..d861b9b4e 100644 --- a/test/compiler_arguments_tests.bzl +++ b/test/compiler_arguments_tests.bzl @@ -14,6 +14,23 @@ split_test = make_action_command_line_test_rule( }, ) +thin_lto_test = make_action_command_line_test_rule( + config_settings = { + "//command_line_option:features": [ + "swift.thin_lto", + ], + }, +) + +full_lto_test = make_action_command_line_test_rule( + config_settings = { + "//command_line_option:features": [ + "swift.full_lto", + ], + }, +) + + def compiler_arguments_test_suite(name): """Test suite for various command line flags passed to Swift compiles. @@ -69,6 +86,22 @@ def compiler_arguments_test_suite(name): target_under_test = "@build_bazel_rules_swift//test/fixtures/compiler_arguments:lib_package_name", ) + thin_lto_test( + name = "{}_thin_lto".format(name), + expected_argv = ["-lto=llvm-thin"], + mnemonic = "SwiftCompile", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/compiler_arguments:bin", + ) + + full_lto_test( + name = "{}_full_lto".format(name), + expected_argv = ["-lto=llvm-full"], + mnemonic = "SwiftCompile", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/compiler_arguments:bin", + ) + native.test_suite( name = name, tags = [name], diff --git a/test/fixtures/compiler_arguments/BUILD b/test/fixtures/compiler_arguments/BUILD index abc979e58..349b57074 100644 --- a/test/fixtures/compiler_arguments/BUILD +++ b/test/fixtures/compiler_arguments/BUILD @@ -34,3 +34,9 @@ swift_test( srcs = ["empty.swift"], tags = FIXTURE_TAGS, ) + +swift_binary( + name = "bin", + srcs = ["empty.swift"], + tags = FIXTURE_TAGS, +) diff --git a/test/output_file_map_tests.bzl b/test/output_file_map_tests.bzl index f920f9cc0..344c6eb53 100644 --- a/test/output_file_map_tests.bzl +++ b/test/output_file_map_tests.bzl @@ -71,6 +71,22 @@ output_file_map_embed_target_name_bitcode_wmo_test = make_output_file_map_test_r }, ) +output_file_map_thin_lto_test = make_output_file_map_test_rule( + config_settings = { + "//command_line_option:features": [ + "swift.thin_lto", + ], + }, +) + +output_file_map_full_lto_test = make_output_file_map_test_rule( + config_settings = { + "//command_line_option:features": [ + "swift.full_lto", + ], + }, +) + def output_file_map_test_suite(name): """Test suite for `swift_library` generating output file maps. @@ -147,6 +163,28 @@ def output_file_map_test_suite(name): target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", ) + output_file_map_thin_lto_test( + name = "{}_thin_lto".format(name), + expected_mapping = { + "llvm-bc": "test/fixtures/debug_settings/simple_objs/Empty.swift.bc", + }, + file_entry = "test/fixtures/debug_settings/Empty.swift", + output_file_map = "test/fixtures/debug_settings/simple.output_file_map.json", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + + output_file_map_full_lto_test( + name = "{}_full_lto".format(name), + expected_mapping = { + "llvm-bc": "test/fixtures/debug_settings/simple_objs/Empty.swift.bc", + }, + file_entry = "test/fixtures/debug_settings/Empty.swift", + output_file_map = "test/fixtures/debug_settings/simple.output_file_map.json", + tags = [name], + target_under_test = "@build_bazel_rules_swift//test/fixtures/debug_settings:simple", + ) + native.test_suite( name = name, tags = [name],