Skip to content

Commit 78faec5

Browse files
Merge branch 'main' into extend-offloading-api-llvm-objcopy
2 parents a454551 + a64e6f4 commit 78faec5

File tree

24,758 files changed

+1685477
-747445
lines changed

Some content is hidden

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

24,758 files changed

+1685477
-747445
lines changed

.ci/compute_projects.py

Lines changed: 158 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
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"},
@@ -48,16 +49,44 @@
4849
"flang",
4950
},
5051
"lld": {"bolt", "cross-project-tests"},
51-
# TODO(issues/132795): LLDB should be enabled on clang changes.
52-
"clang": {"clang-tools-extra", "compiler-rt", "cross-project-tests"},
53-
"clang-tools-extra": {"libc"},
52+
"clang": {"clang-tools-extra", "cross-project-tests", "lldb"},
5453
"mlir": {"flang"},
5554
# Test everything if ci scripts are changed.
56-
# FIXME: Figure out what is missing and add here.
57-
".ci": {"llvm", "clang", "lld", "lldb"},
55+
".ci": {
56+
"llvm",
57+
"clang",
58+
"CIR",
59+
"lld",
60+
"lldb",
61+
"bolt",
62+
"clang-tools-extra",
63+
"mlir",
64+
"polly",
65+
"flang",
66+
"libclc",
67+
"openmp",
68+
},
5869
}
5970

60-
DEPENDENT_RUNTIMES_TO_TEST = {"clang": {"libcxx", "libcxxabi", "libunwind"}}
71+
# This mapping describes runtimes that should be enabled for a specific project,
72+
# but not necessarily run for testing. The only case of this currently is lldb
73+
# which needs some runtimes enabled for tests.
74+
DEPENDENT_RUNTIMES_TO_BUILD = {"lldb": {"libcxx", "libcxxabi", "libunwind"}}
75+
76+
# This mapping describes runtimes that should be tested when the key project is
77+
# touched.
78+
DEPENDENT_RUNTIMES_TO_TEST = {
79+
"clang": {"compiler-rt"},
80+
"clang-tools-extra": {"libc"},
81+
"libc": {"libc"},
82+
"compiler-rt": {"compiler-rt"},
83+
".ci": {"compiler-rt", "libc"},
84+
}
85+
DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG = {
86+
"llvm": {"libcxx", "libcxxabi", "libunwind"},
87+
"clang": {"libcxx", "libcxxabi", "libunwind"},
88+
".ci": {"libcxx", "libcxxabi", "libunwind"},
89+
}
6190

6291
EXCLUDE_LINUX = {
6392
"cross-project-tests", # TODO(issues/132796): Tests are failing.
@@ -71,6 +100,9 @@
71100
"libc", # No Windows Support.
72101
"lldb", # TODO(issues/132800): Needs environment setup.
73102
"bolt", # No Windows Support.
103+
"libcxx",
104+
"libcxxabi",
105+
"libunwind",
74106
}
75107

76108
# These are projects that we should test if the project itself is changed but
@@ -86,12 +118,12 @@
86118
"cross-project-tests",
87119
"flang",
88120
"libc",
89-
"libcxx",
90-
"libcxxabi",
91-
"libunwind",
92121
"lldb",
93122
"openmp",
94123
"polly",
124+
"libcxx",
125+
"libcxxabi",
126+
"libunwind",
95127
}
96128

97129
PROJECT_CHECK_TARGETS = {
@@ -104,6 +136,7 @@
104136
"lldb": "check-lldb",
105137
"llvm": "check-llvm",
106138
"clang": "check-clang",
139+
"CIR": "check-clang-cir",
107140
"bolt": "check-bolt",
108141
"lld": "check-lld",
109142
"flang": "check-flang",
@@ -115,21 +148,52 @@
115148
"polly": "check-polly",
116149
}
117150

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

120170

121-
def _add_dependencies(projects: Set[str]) -> Set[str]:
171+
def _add_dependencies(projects: Set[str], runtimes: Set[str]) -> Set[str]:
122172
projects_with_dependents = set(projects)
123173
current_projects_count = 0
124174
while current_projects_count != len(projects_with_dependents):
125175
current_projects_count = len(projects_with_dependents)
126176
for project in list(projects_with_dependents):
127-
if project not in PROJECT_DEPENDENCIES:
128-
continue
129-
projects_with_dependents.update(PROJECT_DEPENDENCIES[project])
177+
if project in PROJECT_DEPENDENCIES:
178+
projects_with_dependents.update(PROJECT_DEPENDENCIES[project])
179+
for runtime in runtimes:
180+
if runtime in PROJECT_DEPENDENCIES:
181+
projects_with_dependents.update(PROJECT_DEPENDENCIES[runtime])
130182
return projects_with_dependents
131183

132184

185+
def _exclude_projects(current_projects: Set[str], platform: str) -> Set[str]:
186+
if platform == "Linux":
187+
to_exclude = EXCLUDE_LINUX
188+
elif platform == "Windows":
189+
to_exclude = EXCLUDE_WINDOWS
190+
elif platform == "Darwin":
191+
to_exclude = EXCLUDE_MAC
192+
else:
193+
raise ValueError(f"Unexpected platform: {platform}")
194+
return current_projects.difference(to_exclude)
195+
196+
133197
def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set[str]:
134198
projects_to_test = set()
135199
for modified_project in modified_projects:
@@ -147,86 +211,121 @@ def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set
147211
):
148212
continue
149213
projects_to_test.add(dependent_project)
150-
if platform == "Linux":
151-
for to_exclude in EXCLUDE_LINUX:
152-
if to_exclude in projects_to_test:
153-
projects_to_test.remove(to_exclude)
154-
elif platform == "Windows":
155-
for to_exclude in EXCLUDE_WINDOWS:
156-
if to_exclude in projects_to_test:
157-
projects_to_test.remove(to_exclude)
158-
elif platform == "Darwin":
159-
for to_exclude in EXCLUDE_MAC:
160-
if to_exclude in projects_to_test:
161-
projects_to_test.remove(to_exclude)
162-
else:
163-
raise ValueError("Unexpected platform.")
214+
projects_to_test = _exclude_projects(projects_to_test, platform)
164215
return projects_to_test
165216

166217

167-
def _compute_projects_to_build(projects_to_test: Set[str]) -> Set[str]:
168-
return _add_dependencies(projects_to_test)
218+
def _compute_projects_to_build(
219+
projects_to_test: Set[str], runtimes: Set[str]
220+
) -> Set[str]:
221+
return _add_dependencies(projects_to_test, runtimes)
169222

170223

171224
def _compute_project_check_targets(projects_to_test: Set[str]) -> Set[str]:
172225
check_targets = set()
173226
for project_to_test in projects_to_test:
174-
if project_to_test not in PROJECT_CHECK_TARGETS:
175-
continue
176-
check_targets.add(PROJECT_CHECK_TARGETS[project_to_test])
227+
if project_to_test in PROJECT_CHECK_TARGETS:
228+
check_targets.add(PROJECT_CHECK_TARGETS[project_to_test])
177229
return check_targets
178230

179231

180-
def _compute_runtimes_to_test(projects_to_test: Set[str]) -> Set[str]:
232+
def _compute_runtimes_to_test(modified_projects: Set[str], platform: str) -> Set[str]:
181233
runtimes_to_test = set()
182-
for project_to_test in projects_to_test:
183-
if project_to_test not in DEPENDENT_RUNTIMES_TO_TEST:
234+
for modified_project in modified_projects:
235+
if modified_project in DEPENDENT_RUNTIMES_TO_TEST:
236+
runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[modified_project])
237+
return _exclude_projects(runtimes_to_test, platform)
238+
239+
240+
def _compute_runtimes_to_test_needs_reconfig(
241+
modified_projects: Set[str], platform: str
242+
) -> Set[str]:
243+
runtimes_to_test = set()
244+
for modified_project in modified_projects:
245+
if modified_project in DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG:
246+
runtimes_to_test.update(
247+
DEPENDENT_RUNTIMES_TO_TEST_NEEDS_RECONFIG[modified_project]
248+
)
249+
return _exclude_projects(runtimes_to_test, platform)
250+
251+
252+
def _compute_runtimes_to_build(
253+
runtimes_to_test: Set[str], modified_projects: Set[str], platform: str
254+
) -> Set[str]:
255+
runtimes_to_build = set(runtimes_to_test)
256+
for modified_project in modified_projects:
257+
if modified_project in DEPENDENT_RUNTIMES_TO_BUILD:
258+
runtimes_to_build.update(DEPENDENT_RUNTIMES_TO_BUILD[modified_project])
259+
return _exclude_projects(runtimes_to_build, platform)
260+
261+
262+
def _path_matches(matcher: tuple[str], file_path: tuple[str]) -> bool:
263+
if len(file_path) < len(matcher):
264+
return False
265+
for match_part, file_part in zip(matcher, file_path):
266+
if match_part == "*" or file_part == "*":
184267
continue
185-
runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[project_to_test])
186-
return runtimes_to_test
268+
if match_part != file_part:
269+
return False
270+
return True
187271

188272

189-
def _compute_runtime_check_targets(runtimes_to_test: Set[str]) -> Set[str]:
190-
check_targets = set()
191-
for runtime_to_test in runtimes_to_test:
192-
check_targets.add(PROJECT_CHECK_TARGETS[runtime_to_test])
193-
return check_targets
273+
def _get_modified_projects_for_file(modified_file: str) -> Set[str]:
274+
modified_projects = set()
275+
path_parts = pathlib.Path(modified_file).parts
276+
for meta_project_files in META_PROJECTS.keys():
277+
if _path_matches(meta_project_files, path_parts):
278+
meta_project = META_PROJECTS[meta_project_files]
279+
if meta_project in SKIP_PROJECTS:
280+
return set()
281+
modified_projects.add(meta_project)
282+
modified_projects.add(pathlib.Path(modified_file).parts[0])
283+
return modified_projects
194284

195285

196286
def _get_modified_projects(modified_files: list[str]) -> Set[str]:
197287
modified_projects = set()
198288
for modified_file in modified_files:
199-
path_parts = pathlib.Path(modified_file).parts
200-
# Exclude files in the docs directory. They do not impact an test
201-
# targets and there is a separate workflow used for ensuring the
202-
# documentation builds.
203-
if len(path_parts) > 2 and path_parts[1] == "docs":
204-
continue
205-
# Exclude files for the gn build. We do not test it within premerge
206-
# and changes occur often enough that they otherwise take up
207-
# capacity.
208-
if len(path_parts) > 3 and path_parts[:3] == ("llvm", "utils", "gn"):
209-
continue
210-
modified_projects.add(pathlib.Path(modified_file).parts[0])
289+
modified_projects.update(_get_modified_projects_for_file(modified_file))
211290
return modified_projects
212291

213292

214293
def get_env_variables(modified_files: list[str], platform: str) -> Set[str]:
215294
modified_projects = _get_modified_projects(modified_files)
216295
projects_to_test = _compute_projects_to_test(modified_projects, platform)
217-
projects_to_build = _compute_projects_to_build(projects_to_test)
296+
runtimes_to_test = _compute_runtimes_to_test(modified_projects, platform)
297+
runtimes_to_test_needs_reconfig = _compute_runtimes_to_test_needs_reconfig(
298+
modified_projects, platform
299+
)
300+
runtimes_to_build = _compute_runtimes_to_build(
301+
runtimes_to_test | runtimes_to_test_needs_reconfig, modified_projects, platform
302+
)
303+
projects_to_build = _compute_projects_to_build(projects_to_test, runtimes_to_build)
218304
projects_check_targets = _compute_project_check_targets(projects_to_test)
219-
runtimes_to_test = _compute_runtimes_to_test(projects_to_test)
220-
runtimes_check_targets = _compute_runtime_check_targets(runtimes_to_test)
305+
runtimes_check_targets = _compute_project_check_targets(runtimes_to_test)
306+
runtimes_check_targets_needs_reconfig = _compute_project_check_targets(
307+
runtimes_to_test_needs_reconfig
308+
)
309+
310+
# CIR is used as a pseudo-project in this script. It is built as part of the
311+
# clang build, but it requires an explicit option to enable. We set that
312+
# option here, and remove it from the projects_to_build list.
313+
enable_cir = "ON" if "CIR" in projects_to_build else "OFF"
314+
projects_to_build.discard("CIR")
315+
221316
# We use a semicolon to separate the projects/runtimes as they get passed
222317
# to the CMake invocation and thus we need to use the CMake list separator
223318
# (;). We use spaces to separate the check targets as they end up getting
224319
# passed to ninja.
225320
return {
226321
"projects_to_build": ";".join(sorted(projects_to_build)),
227322
"project_check_targets": " ".join(sorted(projects_check_targets)),
228-
"runtimes_to_build": ";".join(sorted(runtimes_to_test)),
323+
"runtimes_to_build": ";".join(sorted(runtimes_to_build)),
229324
"runtimes_check_targets": " ".join(sorted(runtimes_check_targets)),
325+
"runtimes_check_targets_needs_reconfig": " ".join(
326+
sorted(runtimes_check_targets_needs_reconfig)
327+
),
328+
"enable_cir": enable_cir,
230329
}
231330

232331

0 commit comments

Comments
 (0)