Skip to content

Commit 5c3197e

Browse files
authored
merge main into amd-staging (llvm#1353)
2 parents 56d502c + 6d07a8b commit 5c3197e

File tree

365 files changed

+8150
-4200
lines changed

Some content is hidden

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

365 files changed

+8150
-4200
lines changed

.ci/compute_projects.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
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+
"""Computes the list of projects that need to be tested from a diff.
5+
6+
Does some things, spits out a list of projects.
7+
"""
8+
9+
from collections.abc import Set
10+
import pathlib
11+
import platform
12+
import sys
13+
14+
# This mapping lists out the dependencies for each project. These should be
15+
# direct dependencies. The code will handle transitive dependencies. Some
16+
# projects might have optional dependencies depending upon how they are built.
17+
# The dependencies listed here should be the dependencies required for the
18+
# configuration built/tested in the premerge CI.
19+
PROJECT_DEPENDENCIES = {
20+
"llvm": set(),
21+
"clang": {"llvm"},
22+
"bolt": {"clang", "lld", "llvm"},
23+
"clang-tools-extra": {"clang", "llvm"},
24+
"compiler-rt": {"clang", "lld"},
25+
"libc": {"clang", "lld"},
26+
"openmp": {"clang", "lld"},
27+
"flang": {"llvm", "clang"},
28+
"lldb": {"llvm", "clang"},
29+
"libclc": {"llvm", "clang"},
30+
"lld": {"llvm"},
31+
"mlir": {"llvm"},
32+
"polly": {"llvm"},
33+
}
34+
35+
# This mapping describes the additional projects that should be tested when a
36+
# specific project is touched. We enumerate them specifically rather than
37+
# just invert the dependencies list to give more control over what exactly is
38+
# tested.
39+
DEPENDENTS_TO_TEST = {
40+
"llvm": {
41+
"bolt",
42+
"clang",
43+
"clang-tools-extra",
44+
"lld",
45+
"lldb",
46+
"mlir",
47+
"polly",
48+
"flang",
49+
},
50+
"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"},
54+
"mlir": {"flang"},
55+
}
56+
57+
DEPENDENT_RUNTIMES_TO_TEST = {"clang": {"libcxx", "libcxxabi", "libunwind"}}
58+
59+
EXCLUDE_LINUX = {
60+
"cross-project-tests", # TODO(issues/132796): Tests are failing.
61+
"openmp", # https://github.com/google/llvm-premerge-checks/issues/410
62+
}
63+
64+
EXCLUDE_WINDOWS = {
65+
"cross-project-tests", # TODO(issues/132797): Tests are failing.
66+
"compiler-rt", # TODO(issues/132798): Tests take excessive time.
67+
"openmp", # TODO(issues/132799): Does not detect perl installation.
68+
"libc", # No Windows Support.
69+
"lldb", # TODO(issues/132800): Needs environment setup.
70+
"bolt", # No Windows Support.
71+
}
72+
73+
# These are projects that we should test if the project itself is changed but
74+
# where testing is not yet stable enough for it to be enabled on changes to
75+
# dependencies.
76+
EXCLUDE_DEPENDENTS_WINDOWS = {
77+
"flang", # TODO(issues/132803): Flang is not stable.
78+
}
79+
80+
EXCLUDE_MAC = {
81+
"bolt",
82+
"compiler-rt",
83+
"cross-project-tests",
84+
"flang",
85+
"libc",
86+
"libcxx",
87+
"libcxxabi",
88+
"libunwind",
89+
"lldb",
90+
"openmp",
91+
"polly",
92+
}
93+
94+
PROJECT_CHECK_TARGETS = {
95+
"clang-tools-extra": "check-clang-tools",
96+
"compiler-rt": "check-compiler-rt",
97+
"cross-project-tests": "check-cross-project",
98+
"libcxx": "check-cxx",
99+
"libcxxabi": "check-cxxabi",
100+
"libunwind": "check-unwind",
101+
"lldb": "check-lldb",
102+
"llvm": "check-llvm",
103+
"clang": "check-clang",
104+
"bolt": "check-bolt",
105+
"lld": "check-lld",
106+
"flang": "check-flang",
107+
"libc": "check-libc",
108+
"lld": "check-lld",
109+
"lldb": "check-lldb",
110+
"mlir": "check-mlir",
111+
"openmp": "check-openmp",
112+
"polly": "check-polly",
113+
}
114+
115+
116+
def _add_dependencies(projects: Set[str]) -> Set[str]:
117+
projects_with_dependents = set(projects)
118+
current_projects_count = 0
119+
while current_projects_count != len(projects_with_dependents):
120+
current_projects_count = len(projects_with_dependents)
121+
for project in list(projects_with_dependents):
122+
if project not in PROJECT_DEPENDENCIES:
123+
continue
124+
projects_with_dependents.update(PROJECT_DEPENDENCIES[project])
125+
return projects_with_dependents
126+
127+
128+
def _compute_projects_to_test(modified_projects: Set[str], platform: str) -> Set[str]:
129+
projects_to_test = set()
130+
for modified_project in modified_projects:
131+
# Skip all projects where we cannot run tests.
132+
if modified_project not in PROJECT_CHECK_TARGETS:
133+
continue
134+
projects_to_test.add(modified_project)
135+
if modified_project not in DEPENDENTS_TO_TEST:
136+
continue
137+
for dependent_project in DEPENDENTS_TO_TEST[modified_project]:
138+
if (
139+
platform == "Windows"
140+
and dependent_project in EXCLUDE_DEPENDENTS_WINDOWS
141+
):
142+
continue
143+
projects_to_test.add(dependent_project)
144+
if platform == "Linux":
145+
for to_exclude in EXCLUDE_LINUX:
146+
if to_exclude in projects_to_test:
147+
projects_to_test.remove(to_exclude)
148+
elif platform == "Windows":
149+
for to_exclude in EXCLUDE_WINDOWS:
150+
if to_exclude in projects_to_test:
151+
projects_to_test.remove(to_exclude)
152+
elif platform == "Darwin":
153+
for to_exclude in EXCLUDE_MAC:
154+
if to_exclude in projects_to_test:
155+
projects_to_test.remove(to_exclude)
156+
else:
157+
raise ValueError("Unexpected platform.")
158+
return projects_to_test
159+
160+
161+
def _compute_projects_to_build(projects_to_test: Set[str]) -> Set[str]:
162+
return _add_dependencies(projects_to_test)
163+
164+
165+
def _compute_project_check_targets(projects_to_test: Set[str]) -> Set[str]:
166+
check_targets = set()
167+
for project_to_test in projects_to_test:
168+
if project_to_test not in PROJECT_CHECK_TARGETS:
169+
continue
170+
check_targets.add(PROJECT_CHECK_TARGETS[project_to_test])
171+
return check_targets
172+
173+
174+
def _compute_runtimes_to_test(projects_to_test: Set[str]) -> Set[str]:
175+
runtimes_to_test = set()
176+
for project_to_test in projects_to_test:
177+
if project_to_test not in DEPENDENT_RUNTIMES_TO_TEST:
178+
continue
179+
runtimes_to_test.update(DEPENDENT_RUNTIMES_TO_TEST[project_to_test])
180+
return runtimes_to_test
181+
182+
183+
def _compute_runtime_check_targets(runtimes_to_test: Set[str]) -> Set[str]:
184+
check_targets = set()
185+
for runtime_to_test in runtimes_to_test:
186+
check_targets.add(PROJECT_CHECK_TARGETS[runtime_to_test])
187+
return check_targets
188+
189+
190+
def _get_modified_projects(modified_files: list[str]) -> Set[str]:
191+
modified_projects = set()
192+
for modified_file in modified_files:
193+
modified_projects.add(pathlib.Path(modified_file).parts[0])
194+
return modified_projects
195+
196+
197+
def get_env_variables(modified_files: list[str], platform: str) -> Set[str]:
198+
modified_projects = _get_modified_projects(modified_files)
199+
projects_to_test = _compute_projects_to_test(modified_projects, platform)
200+
projects_to_build = _compute_projects_to_build(projects_to_test)
201+
projects_check_targets = _compute_project_check_targets(projects_to_test)
202+
runtimes_to_test = _compute_runtimes_to_test(projects_to_test)
203+
runtimes_check_targets = _compute_runtime_check_targets(runtimes_to_test)
204+
# We use a semicolon to separate the projects/runtimes as they get passed
205+
# to the CMake invocation and thus we need to use the CMake list separator
206+
# (;). We use spaces to separate the check targets as they end up getting
207+
# passed to ninja.
208+
return {
209+
"projects_to_build": ";".join(sorted(projects_to_build)),
210+
"project_check_targets": " ".join(sorted(projects_check_targets)),
211+
"runtimes_to_build": ";".join(sorted(runtimes_to_test)),
212+
"runtimes_check_targets": " ".join(sorted(runtimes_check_targets)),
213+
}
214+
215+
216+
if __name__ == "__main__":
217+
current_platform = platform.system()
218+
if len(sys.argv) == 2:
219+
current_platform = sys.argv[1]
220+
env_variables = get_env_variables(sys.stdin.readlines(), current_platform)
221+
for env_variable in env_variables:
222+
print(f"{env_variable}='{env_variables[env_variable]}'")

.ci/compute_projects_test.py

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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+
"""Does some stuff."""
5+
6+
import unittest
7+
8+
import compute_projects
9+
10+
11+
class TestComputeProjects(unittest.TestCase):
12+
def test_llvm(self):
13+
env_variables = compute_projects.get_env_variables(
14+
["llvm/CMakeLists.txt"], "Linux"
15+
)
16+
self.assertEqual(
17+
env_variables["projects_to_build"],
18+
"bolt;clang;clang-tools-extra;flang;lld;lldb;llvm;mlir;polly",
19+
)
20+
self.assertEqual(
21+
env_variables["project_check_targets"],
22+
"check-bolt check-clang check-clang-tools check-flang check-lld check-lldb check-llvm check-mlir check-polly",
23+
)
24+
self.assertEqual(
25+
env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind"
26+
)
27+
self.assertEqual(
28+
env_variables["runtimes_check_targets"],
29+
"check-cxx check-cxxabi check-unwind",
30+
)
31+
32+
def test_llvm_windows(self):
33+
env_variables = compute_projects.get_env_variables(
34+
["llvm/CMakeLists.txt"], "Windows"
35+
)
36+
self.assertEqual(
37+
env_variables["projects_to_build"],
38+
"clang;clang-tools-extra;lld;llvm;mlir;polly",
39+
)
40+
self.assertEqual(
41+
env_variables["project_check_targets"],
42+
"check-clang check-clang-tools check-lld check-llvm check-mlir check-polly",
43+
)
44+
self.assertEqual(
45+
env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind"
46+
)
47+
self.assertEqual(
48+
env_variables["runtimes_check_targets"],
49+
"check-cxx check-cxxabi check-unwind",
50+
)
51+
52+
def test_llvm_mac(self):
53+
env_variables = compute_projects.get_env_variables(
54+
["llvm/CMakeLists.txt"], "Darwin"
55+
)
56+
self.assertEqual(
57+
env_variables["projects_to_build"],
58+
"clang;clang-tools-extra;lld;llvm;mlir",
59+
)
60+
self.assertEqual(
61+
env_variables["project_check_targets"],
62+
"check-clang check-clang-tools check-lld check-llvm check-mlir",
63+
)
64+
self.assertEqual(
65+
env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind"
66+
)
67+
self.assertEqual(
68+
env_variables["runtimes_check_targets"],
69+
"check-cxx check-cxxabi check-unwind",
70+
)
71+
72+
def test_clang(self):
73+
env_variables = compute_projects.get_env_variables(
74+
["clang/CMakeLists.txt"], "Linux"
75+
)
76+
self.assertEqual(
77+
env_variables["projects_to_build"],
78+
"clang;clang-tools-extra;compiler-rt;lld;llvm",
79+
)
80+
self.assertEqual(
81+
env_variables["project_check_targets"],
82+
"check-clang check-clang-tools check-compiler-rt",
83+
)
84+
self.assertEqual(
85+
env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind"
86+
)
87+
self.assertEqual(
88+
env_variables["runtimes_check_targets"],
89+
"check-cxx check-cxxabi check-unwind",
90+
)
91+
92+
def test_clang_windows(self):
93+
env_variables = compute_projects.get_env_variables(
94+
["clang/CMakeLists.txt"], "Windows"
95+
)
96+
self.assertEqual(
97+
env_variables["projects_to_build"], "clang;clang-tools-extra;llvm"
98+
)
99+
self.assertEqual(
100+
env_variables["project_check_targets"], "check-clang check-clang-tools"
101+
)
102+
self.assertEqual(
103+
env_variables["runtimes_to_build"], "libcxx;libcxxabi;libunwind"
104+
)
105+
self.assertEqual(
106+
env_variables["runtimes_check_targets"],
107+
"check-cxx check-cxxabi check-unwind",
108+
)
109+
110+
def test_bolt(self):
111+
env_variables = compute_projects.get_env_variables(
112+
["bolt/CMakeLists.txt"], "Linux"
113+
)
114+
self.assertEqual(env_variables["projects_to_build"], "bolt;clang;lld;llvm")
115+
self.assertEqual(env_variables["project_check_targets"], "check-bolt")
116+
self.assertEqual(env_variables["runtimes_to_build"], "")
117+
self.assertEqual(env_variables["runtimes_check_targets"], "")
118+
119+
def test_lldb(self):
120+
env_variables = compute_projects.get_env_variables(
121+
["lldb/CMakeLists.txt"], "Linux"
122+
)
123+
self.assertEqual(env_variables["projects_to_build"], "clang;lldb;llvm")
124+
self.assertEqual(env_variables["project_check_targets"], "check-lldb")
125+
self.assertEqual(env_variables["runtimes_to_build"], "")
126+
self.assertEqual(env_variables["runtimes_check_targets"], "")
127+
128+
def test_mlir(self):
129+
env_variables = compute_projects.get_env_variables(
130+
["mlir/CMakeLists.txt"], "Linux"
131+
)
132+
self.assertEqual(env_variables["projects_to_build"], "clang;flang;llvm;mlir")
133+
self.assertEqual(
134+
env_variables["project_check_targets"], "check-flang check-mlir"
135+
)
136+
self.assertEqual(env_variables["runtimes_to_build"], "")
137+
self.assertEqual(env_variables["runtimes_check_targets"], "")
138+
139+
def test_flang(self):
140+
env_variables = compute_projects.get_env_variables(
141+
["flang/CMakeLists.txt"], "Linux"
142+
)
143+
self.assertEqual(env_variables["projects_to_build"], "clang;flang;llvm")
144+
self.assertEqual(env_variables["project_check_targets"], "check-flang")
145+
self.assertEqual(env_variables["runtimes_to_build"], "")
146+
self.assertEqual(env_variables["runtimes_check_targets"], "")
147+
148+
def test_invalid_subproject(self):
149+
env_variables = compute_projects.get_env_variables(
150+
[".ci/compute_projects.py"], "Linux"
151+
)
152+
self.assertEqual(env_variables["projects_to_build"], "")
153+
self.assertEqual(env_variables["project_check_targets"], "")
154+
self.assertEqual(env_variables["runtimes_to_build"], "")
155+
self.assertEqual(env_variables["runtimes_check_targets"], "")
156+
157+
def test_top_level_file(self):
158+
env_variables = compute_projects.get_env_variables(["README.md"], "Linux")
159+
self.assertEqual(env_variables["projects_to_build"], "")
160+
self.assertEqual(env_variables["project_check_targets"], "")
161+
self.assertEqual(env_variables["runtimes_to_build"], "")
162+
self.assertEqual(env_variables["runtimes_check_targets"], "")
163+
164+
165+
if __name__ == "__main__":
166+
unittest.main()

0 commit comments

Comments
 (0)