Skip to content

Commit b728b89

Browse files
committed
Merge pull request #1126 from harlanhaskins/profdata-merge
[coverage] Automatic merger for LLVM profile data
2 parents a927dc8 + 2b22040 commit b728b89

File tree

22 files changed

+423
-84
lines changed

22 files changed

+423
-84
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ option(SWIFT_INCLUDE_DOCS
5858
"Create targets for building docs."
5959
TRUE)
6060

61+
set(SWIFT_ANALYZE_CODE_COVERAGE FALSE CACHE STRING
62+
"Build Swift with code coverage instrumenting enabled [FALSE, NOT-MERGED, MERGED]")
63+
set_property(CACHE SWIFT_ANALYZE_CODE_COVERAGE PROPERTY
64+
STRINGS FALSE "NOT-MERGED" "MERGED")
65+
6166
set(SWIFT_VERSION "3.0" CACHE STRING
6267
"The user-visible version of the Swift compiler")
6368
set(SWIFT_VENDOR "" CACHE STRING

cmake/modules/AddSwift.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function(_add_variant_c_compile_link_flags
6464
"-m${SWIFT_SDK_${sdk}_VERSION_MIN_NAME}-version-min=${SWIFT_SDK_${sdk}_DEPLOYMENT_VERSION}")
6565

6666
if(analyze_code_coverage)
67-
list(APPEND result "-fprofile-instr-generate=swift-%p.profraw"
67+
list(APPEND result "-fprofile-instr-generate"
6868
"-fcoverage-mapping")
6969
endif()
7070
endif()
@@ -111,7 +111,7 @@ function(_add_variant_c_compile_flags
111111
endif()
112112

113113
if(analyze_code_coverage)
114-
list(APPEND result "-fprofile-instr-generate=swift-%p.profraw"
114+
list(APPEND result "-fprofile-instr-generate"
115115
"-fcoverage-mapping")
116116
endif()
117117

test/CMakeLists.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ if(PYTHONINTERP_FOUND)
117117

118118
set(TEST_MODES optimize_none optimize optimize_unchecked)
119119

120+
120121
foreach(SDK ${SWIFT_SDKS})
121122
foreach(ARCH ${SWIFT_SDK_${SDK}_ARCHITECTURES})
122123
foreach(TEST_MODE ${TEST_MODES})
@@ -196,30 +197,52 @@ if(PYTHONINTERP_FOUND)
196197
"${CMAKE_CURRENT_SOURCE_DIR}/../validation-test/lit.site.cfg.in"
197198
"${validation_test_bin_dir}/lit.site.cfg"
198199
"validation-test${VARIANT_SUFFIX}.lit.site.cfg")
200+
set(profdata_merge_worker
201+
"${CMAKE_CURRENT_SOURCE_DIR}/../utils/profdata_merge/main.py")
202+
203+
if(SWIFT_ANALYZE_CODE_COVERAGE STREQUAL "MERGED")
204+
set(command_profdata_merge_start
205+
COMMAND "${PYTHON_EXECUTABLE}" "${profdata_merge_worker}" start
206+
-o "${swift_test_results_dir}"
207+
-l "${swift_test_results_dir}/profdata_merge.log")
208+
set(command_profdata_merge_stop
209+
COMMAND "${PYTHON_EXECUTABLE}" "${profdata_merge_worker}" stop)
210+
else()
211+
set(command_profdata_merge_start)
212+
set(command_profdata_merge_stop)
213+
endif()
199214

200215
add_custom_target("check-swift${test_mode_target_suffix}${VARIANT_SUFFIX}"
201216
${command_upload_stdlib}
202217
${command_clean_test_results_dir}
218+
${command_profdata_merge_start}
203219
COMMAND ${lit_command} "${test_bin_dir}"
220+
${command_profdata_merge_stop}
204221
DEPENDS ${test_dependencies}
205222
COMMENT "Running Swift tests for ${VARIANT_TRIPLE}"
206223
${cmake_3_2_USES_TERMINAL})
207224

208225
add_custom_target("check-swift-validation${test_mode_target_suffix}${VARIANT_SUFFIX}"
209226
${command_upload_stdlib}
210227
${command_clean_test_results_dir}
228+
${command_profdata_merge_start}
211229
COMMAND ${lit_command} "${validation_test_bin_dir}"
230+
${command_profdata_merge_stop}
212231
DEPENDS ${test_dependencies} ${validation_test_dependencies}
213232
COMMENT "Running Swift validation tests for ${VARIANT_TRIPLE}"
214233
${cmake_3_2_USES_TERMINAL})
215234

216235
add_custom_target("check-swift-all${test_mode_target_suffix}${VARIANT_SUFFIX}"
217236
${command_upload_stdlib}
218237
${command_clean_test_results_dir}
238+
${command_profdata_merge_start}
219239
COMMAND ${lit_command} "${validation_test_bin_dir}" "${test_bin_dir}"
240+
${command_profdata_merge_stop}
220241
DEPENDS ${test_dependencies} ${validation_test_dependencies}
221242
COMMENT "Running all Swift tests for ${VARIANT_TRIPLE}"
222243
${cmake_3_2_USES_TERMINAL})
244+
245+
223246
endforeach()
224247
endforeach()
225248
endforeach()
@@ -245,6 +268,7 @@ if(PYTHONINTERP_FOUND)
245268

246269
add_custom_target(check-swift-all${test_mode_target_suffix}
247270
DEPENDS "check-swift-all${test_mode_target_suffix}${SWIFT_PRIMARY_VARIANT_SUFFIX}")
271+
248272
endforeach()
249273

250274
endif()

test/Unit/lit.site.cfg.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ config.build_mode = lit_config.params.get('build_mode', "@LLVM_BUILD_MODE@")
88
config.swift_obj_root = "@SWIFT_BINARY_DIR@"
99
config.target_triple = "@TARGET_TRIPLE@"
1010

11+
config.coverage_mode = "@SWIFT_ANALYZE_CODE_COVERAGE@"
12+
1113
# Let the main config do the real work.
1214
lit_config.load_config(config, "@SWIFT_SOURCE_DIR@/test/Unit/lit.cfg")

test/lit.cfg

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ import re
2424
import subprocess
2525
import sys
2626
import tempfile
27+
import socket
28+
import glob
2729

30+
import lit
2831
import lit.formats
2932
import lit.util
3033

@@ -129,6 +132,43 @@ if config.test_exec_root is None:
129132

130133
###
131134

135+
class SwiftTest(lit.formats.ShTest, object):
136+
def __init__(self, coverage_mode=None, execute_external=True):
137+
super(SwiftTest, self).__init__(execute_external=execute_external)
138+
if coverage_mode == "FALSE":
139+
self.coverage_mode = None
140+
else:
141+
self.coverage_mode = coverage_mode
142+
143+
def profdir_for_test(self, test):
144+
_, tmp_base = lit.TestRunner.getTempPaths(test)
145+
return tmp_base + ".profdir"
146+
147+
def before_test(self, test, litConfig):
148+
if self.coverage_mode:
149+
profdir = self.profdir_for_test(test)
150+
if not os.path.exists(profdir):
151+
os.makedirs(profdir)
152+
153+
test.config.environment["LLVM_PROFILE_FILE"] = \
154+
os.path.join(profdir, "swift-%p.profraw")
155+
156+
def after_test(self, test, litConfig, result):
157+
if self.coverage_mode == "MERGED":
158+
profdir = self.profdir_for_test(test)
159+
files = glob.glob(os.path.join(profdir, "swift-*.profraw"))
160+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
161+
sock.connect(('localhost', 12400))
162+
sock.send("\n".join(files))
163+
sock.close()
164+
return result
165+
166+
167+
def execute(self, test, litConfig):
168+
self.before_test(test, litConfig)
169+
result = super(SwiftTest, self).execute(test, litConfig)
170+
return self.after_test(test, litConfig, result)
171+
132172
# name: The name of this test suite.
133173
config.name = 'Swift'
134174

@@ -138,7 +178,7 @@ if platform.system() == 'Darwin':
138178
config.environment['TOOLCHAINS'] = 'default'
139179

140180
# testFormat: The test format to use to interpret tests.
141-
config.test_format = lit.formats.ShTest(execute_external=True)
181+
config.test_format = SwiftTest(coverage_mode=config.coverage_mode)
142182

143183
# suffixes: A list of file extensions to treat as test files.
144184
config.suffixes = ['.swift', '.ll', '.sil', '.gyb', '.m']

test/lit.site.cfg.in

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ config.variant_sdk = "@VARIANT_SDK@"
1818
config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@"
1919
config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@"
2020

21+
config.coverage_mode = "@SWIFT_ANALYZE_CODE_COVERAGE@"
22+
2123
if "@SWIFT_ASAN_BUILD@" == "TRUE":
2224
config.available_features.add("asan")
2325
else:
@@ -42,11 +44,6 @@ if "@SWIFT_OPTIMIZED@" == "TRUE":
4244
if "@SWIFT_HAVE_WORKING_STD_REGEX@" == "FALSE":
4345
config.available_features.add('broken_std_regex')
4446

45-
if "@SWIFT_ANALYZE_CODE_COVERAGE@" == "TRUE":
46-
lit_config.useValgrind = True
47-
lit_config.valgrindArgs = [os.path.join(config.swift_src_root,
48-
"utils/use_profdir.py")]
49-
5047
# Let the main config do the real work.
5148
if config.test_exec_root is None:
5249
config.test_exec_root = os.path.dirname(os.path.realpath(__file__))

tools/SourceKit/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ macro(add_sourcekit_executable name)
241241

242242
if(SWIFT_ANALYZE_CODE_COVERAGE)
243243
set_property(TARGET "${name}" APPEND_STRING PROPERTY
244-
LINK_FLAGS " -fprofile-instr-generate=swift-%p.profraw -fcoverage-mapping")
244+
LINK_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
245245
endif()
246246
endif()
247247
endif()

tools/SourceKit/tools/complete-test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
1717

1818
if(SWIFT_ANALYZE_CODE_COVERAGE)
1919
set_property(TARGET complete-test APPEND_STRING PROPERTY
20-
LINK_FLAGS " -fprofile-instr-generate=swift-%p.profraw -fcoverage-mapping")
20+
LINK_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
2121
endif()
2222
endif()
2323

tools/SourceKit/tools/sourcekitd-repl/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
1111

1212
if(SWIFT_ANALYZE_CODE_COVERAGE)
1313
set_property(TARGET sourcekitd-repl APPEND_STRING PROPERTY
14-
LINK_FLAGS " -fprofile-instr-generate=swift-%p.profraw -fcoverage-mapping")
14+
LINK_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
1515
endif()
1616
endif()
1717

tools/SourceKit/tools/sourcekitd-test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
2525

2626
if(SWIFT_ANALYZE_CODE_COVERAGE)
2727
set_property(TARGET sourcekitd-test APPEND_STRING PROPERTY
28-
LINK_FLAGS " -fprofile-instr-generate=swift-%p.profraw -fcoverage-mapping")
28+
LINK_FLAGS " -fprofile-instr-generate -fcoverage-mapping")
2929
endif()
3030
endif()
3131

0 commit comments

Comments
 (0)