Skip to content

Commit d2e5fea

Browse files
authored
Merge branch 'llvm:main' into eh_llvm
2 parents c5dd642 + 613caa9 commit d2e5fea

File tree

21,398 files changed

+1716468
-588921
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

21,398 files changed

+1716468
-588921
lines changed

.ci/all_requirements.txt

Lines changed: 213 additions & 11 deletions
Large diffs are not rendered by default.

.ci/cache_lit_timing_files.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2+
# See https://llvm.org/LICENSE.txt for license information.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
"""Caches .lit_test_times.txt files between premerge invocations.
5+
6+
.lit_test_times.txt files are used by lit to order tests to best take advantage
7+
of parallelism. Having them around and up to date can result in a ~15%
8+
improvement in test times. This script downloading cached test time files and
9+
uploading new versions to the GCS buckets used for caching.
10+
"""
11+
12+
import sys
13+
import os
14+
import logging
15+
import multiprocessing.pool
16+
import pathlib
17+
import glob
18+
19+
from google.cloud import storage
20+
21+
GCS_PARALLELISM = 100
22+
23+
24+
def _maybe_upload_timing_file(bucket, timing_file_path):
25+
if os.path.exists(timing_file_path):
26+
timing_file_blob = bucket.blob("lit_timing/" + timing_file_path)
27+
timing_file_blob.upload_from_filename(timing_file_path)
28+
29+
30+
def upload_timing_files(storage_client, bucket_name: str):
31+
bucket = storage_client.bucket(bucket_name)
32+
with multiprocessing.pool.ThreadPool(GCS_PARALLELISM) as thread_pool:
33+
futures = []
34+
for timing_file_path in glob.glob("**/.lit_test_times.txt", recursive=True):
35+
futures.append(
36+
thread_pool.apply_async(
37+
_maybe_upload_timing_file, (bucket, timing_file_path)
38+
)
39+
)
40+
for future in futures:
41+
future.get()
42+
print("Done uploading")
43+
44+
45+
def _maybe_download_timing_file(blob):
46+
file_name = blob.name.removeprefix("lit_timing/")
47+
pathlib.Path(os.path.dirname(file_name)).mkdir(parents=True, exist_ok=True)
48+
blob.download_to_filename(file_name)
49+
50+
51+
def download_timing_files(storage_client, bucket_name: str):
52+
bucket = storage_client.bucket(bucket_name)
53+
blobs = bucket.list_blobs(prefix="lit_timing")
54+
with multiprocessing.pool.ThreadPool(GCS_PARALLELISM) as thread_pool:
55+
futures = []
56+
for timing_file_blob in blobs:
57+
futures.append(
58+
thread_pool.apply_async(
59+
_maybe_download_timing_file, (timing_file_blob,)
60+
)
61+
)
62+
for future in futures:
63+
future.get()
64+
print("Done downloading")
65+
66+
67+
if __name__ == "__main__":
68+
if len(sys.argv) != 2:
69+
logging.fatal("Expected usage is cache_lit_timing_files.py <upload/download>")
70+
sys.exit(1)
71+
action = sys.argv[1]
72+
storage_client = storage.Client()
73+
bucket_name = os.environ["CACHE_GCS_BUCKET"]
74+
if action == "download":
75+
download_timing_files(storage_client, bucket_name)
76+
elif action == "upload":
77+
upload_timing_files(storage_client, bucket_name)
78+
else:
79+
logging.fatal("Expected usage is cache_lit_timing_files.py <upload/download>")
80+
sys.exit(1)

.ci/compute_projects.py

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
PROJECT_DEPENDENCIES = {
2020
"llvm": set(),
2121
"clang": {"llvm"},
22+
"CIR": {"clang", "mlir"},
2223
"bolt": {"clang", "lld", "llvm"},
2324
"clang-tools-extra": {"clang", "llvm"},
2425
"compiler-rt": {"clang", "lld"},
2526
"libc": {"clang", "lld"},
2627
"openmp": {"clang", "lld"},
2728
"flang": {"llvm", "clang"},
29+
"flang-rt": {"flang"},
2830
"lldb": {"llvm", "clang"},
2931
"libclc": {"llvm", "clang"},
3032
"lld": {"llvm"},
@@ -48,13 +50,13 @@
4850
"flang",
4951
},
5052
"lld": {"bolt", "cross-project-tests"},
51-
# TODO(issues/132795): LLDB should be enabled on clang changes.
52-
"clang": {"clang-tools-extra", "cross-project-tests"},
53+
"clang": {"clang-tools-extra", "cross-project-tests", "lldb"},
5354
"mlir": {"flang"},
5455
# Test everything if ci scripts are changed.
5556
".ci": {
5657
"llvm",
5758
"clang",
59+
"CIR",
5860
"lld",
5961
"lldb",
6062
"bolt",
@@ -78,7 +80,10 @@
7880
"clang": {"compiler-rt"},
7981
"clang-tools-extra": {"libc"},
8082
"libc": {"libc"},
81-
".ci": {"compiler-rt", "libc"},
83+
"compiler-rt": {"compiler-rt"},
84+
"flang": {"flang-rt"},
85+
"flang-rt": {"flang-rt"},
86+
".ci": {"compiler-rt", "libc", "flang-rt"},
8287
}
8388
DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG = {
8489
"llvm": {"libcxx", "libcxxabi", "libunwind"},
@@ -93,11 +98,14 @@
9398

9499
EXCLUDE_WINDOWS = {
95100
"cross-project-tests", # TODO(issues/132797): Tests are failing.
96-
"compiler-rt", # TODO(issues/132798): Tests take excessive time.
97101
"openmp", # TODO(issues/132799): Does not detect perl installation.
98102
"libc", # No Windows Support.
99103
"lldb", # TODO(issues/132800): Needs environment setup.
100104
"bolt", # No Windows Support.
105+
"libcxx",
106+
"libcxxabi",
107+
"libunwind",
108+
"flang-rt",
101109
}
102110

103111
# These are projects that we should test if the project itself is changed but
@@ -116,6 +124,9 @@
116124
"lldb",
117125
"openmp",
118126
"polly",
127+
"libcxx",
128+
"libcxxabi",
129+
"libunwind",
119130
}
120131

121132
PROJECT_CHECK_TARGETS = {
@@ -128,9 +139,11 @@
128139
"lldb": "check-lldb",
129140
"llvm": "check-llvm",
130141
"clang": "check-clang",
142+
"CIR": "check-clang-cir",
131143
"bolt": "check-bolt",
132144
"lld": "check-lld",
133145
"flang": "check-flang",
146+
"flang-rt": "check-flang-rt",
134147
"libc": "check-libc",
135148
"lld": "check-lld",
136149
"lldb": "check-lldb",
@@ -139,7 +152,24 @@
139152
"polly": "check-polly",
140153
}
141154

142-
RUNTIMES = {"libcxx", "libcxxabi", "libunwind", "compiler-rt", "libc"}
155+
RUNTIMES = {"libcxx", "libcxxabi", "libunwind", "compiler-rt", "libc", "flang-rt"}
156+
157+
# Meta projects are projects that need explicit handling but do not reside
158+
# in their own top level folder. To add a meta project, the start of the path
159+
# for the metaproject should be mapped to the name of the project below.
160+
# Multiple paths can map to the same metaproject.
161+
META_PROJECTS = {
162+
("clang", "lib", "CIR"): "CIR",
163+
("clang", "test", "CIR"): "CIR",
164+
("clang", "include", "clang", "CIR"): "CIR",
165+
("*", "docs"): "docs",
166+
("llvm", "utils", "gn"): "gn",
167+
(".github", "workflows", "premerge.yaml"): ".ci",
168+
("third-party",): ".ci",
169+
}
170+
171+
# Projects that should not run any tests. These need to be metaprojects.
172+
SKIP_PROJECTS = ["docs", "gn"]
143173

144174

145175
def _add_dependencies(projects: Set[str], runtimes: Set[str]) -> Set[str]:
@@ -233,21 +263,34 @@ def _compute_runtimes_to_build(
233263
return _exclude_projects(runtimes_to_build, platform)
234264

235265

266+
def _path_matches(matcher: tuple[str], file_path: tuple[str]) -> bool:
267+
if len(file_path) < len(matcher):
268+
return False
269+
for match_part, file_part in zip(matcher, file_path):
270+
if match_part == "*" or file_part == "*":
271+
continue
272+
if match_part != file_part:
273+
return False
274+
return True
275+
276+
277+
def _get_modified_projects_for_file(modified_file: str) -> Set[str]:
278+
modified_projects = set()
279+
path_parts = pathlib.Path(modified_file).parts
280+
for meta_project_files in META_PROJECTS.keys():
281+
if _path_matches(meta_project_files, path_parts):
282+
meta_project = META_PROJECTS[meta_project_files]
283+
if meta_project in SKIP_PROJECTS:
284+
return set()
285+
modified_projects.add(meta_project)
286+
modified_projects.add(pathlib.Path(modified_file).parts[0])
287+
return modified_projects
288+
289+
236290
def _get_modified_projects(modified_files: list[str]) -> Set[str]:
237291
modified_projects = set()
238292
for modified_file in modified_files:
239-
path_parts = pathlib.Path(modified_file).parts
240-
# Exclude files in the docs directory. They do not impact an test
241-
# targets and there is a separate workflow used for ensuring the
242-
# documentation builds.
243-
if len(path_parts) > 2 and path_parts[1] == "docs":
244-
continue
245-
# Exclude files for the gn build. We do not test it within premerge
246-
# and changes occur often enough that they otherwise take up
247-
# capacity.
248-
if len(path_parts) > 3 and path_parts[:3] == ("llvm", "utils", "gn"):
249-
continue
250-
modified_projects.add(pathlib.Path(modified_file).parts[0])
293+
modified_projects.update(_get_modified_projects_for_file(modified_file))
251294
return modified_projects
252295

253296

@@ -267,6 +310,13 @@ def get_env_variables(modified_files: list[str], platform: str) -> Set[str]:
267310
runtimes_check_targets_needs_reconfig = _compute_project_check_targets(
268311
runtimes_to_test_needs_reconfig
269312
)
313+
314+
# CIR is used as a pseudo-project in this script. It is built as part of the
315+
# clang build, but it requires an explicit option to enable. We set that
316+
# option here, and remove it from the projects_to_build list.
317+
enable_cir = "ON" if "CIR" in projects_to_build else "OFF"
318+
projects_to_build.discard("CIR")
319+
270320
# We use a semicolon to separate the projects/runtimes as they get passed
271321
# to the CMake invocation and thus we need to use the CMake list separator
272322
# (;). We use spaces to separate the check targets as they end up getting
@@ -279,13 +329,15 @@ def get_env_variables(modified_files: list[str], platform: str) -> Set[str]:
279329
"runtimes_check_targets_needs_reconfig": " ".join(
280330
sorted(runtimes_check_targets_needs_reconfig)
281331
),
332+
"enable_cir": enable_cir,
282333
}
283334

284335

285336
if __name__ == "__main__":
286337
current_platform = platform.system()
287338
if len(sys.argv) == 2:
288339
current_platform = sys.argv[1]
289-
env_variables = get_env_variables(sys.stdin.readlines(), current_platform)
340+
changed_files = [line.strip() for line in sys.stdin.readlines()]
341+
env_variables = get_env_variables(changed_files, current_platform)
290342
for env_variable in env_variables:
291343
print(f"{env_variable}='{env_variables[env_variable]}'")

0 commit comments

Comments
 (0)