Skip to content

Commit 3d84261

Browse files
authored
Merge branch 'main' into users/kparzysz/block-construct-structure
2 parents 0aae9d5 + 6b92a3b commit 3d84261

File tree

588 files changed

+23354
-17486
lines changed

Some content is hidden

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

588 files changed

+23354
-17486
lines changed

.ci/metrics/metrics_test.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
"""Tests for metrics.py"""
5+
6+
from dataclasses import dataclass
7+
import requests
8+
import unittest
9+
import unittest.mock
10+
11+
import metrics
12+
13+
14+
class TestMetrics(unittest.TestCase):
15+
def test_upload_gauge_metric(self):
16+
"""Test that we can upload a gauge metric correctly.
17+
18+
Also verify that we pass around parameters like API keys and user IDs
19+
correctly to the HTTP POST request.
20+
"""
21+
test_metrics = [metrics.GaugeMetric("gauge_test", 5, 1000)]
22+
return_value = requests.Response()
23+
return_value.status_code = 204
24+
with unittest.mock.patch(
25+
"requests.post", return_value=return_value
26+
) as post_mock:
27+
metrics.upload_metrics(test_metrics, "test_userid", "test_api_key")
28+
self.assertSequenceEqual(post_mock.call_args.args, [metrics.GRAFANA_URL])
29+
self.assertEqual(
30+
post_mock.call_args.kwargs["data"], "gauge_test value=5 1000"
31+
)
32+
self.assertEqual(
33+
post_mock.call_args.kwargs["auth"], ("test_userid", "test_api_key")
34+
)
35+
36+
def test_upload_job_metric(self):
37+
"""Test that we can upload a job metric correctly."""
38+
test_metrics = [
39+
metrics.JobMetrics("test_job", 5, 10, 1, 1000, 7, "test_workflow")
40+
]
41+
return_value = requests.Response()
42+
return_value.status_code = 204
43+
with unittest.mock.patch(
44+
"requests.post", return_value=return_value
45+
) as post_mock:
46+
metrics.upload_metrics(test_metrics, "test_userid", "test_aoi_key")
47+
self.assertEqual(
48+
post_mock.call_args.kwargs["data"],
49+
"test_job queue_time=5,run_time=10,status=1 1000",
50+
)
51+
52+
def test_upload_unknown_metric(self):
53+
"""Test we report an error if we encounter an unknown metric type."""
54+
55+
@dataclass
56+
class FakeMetric:
57+
fake_data: str
58+
59+
test_metrics = [FakeMetric("test")]
60+
61+
with self.assertRaises(ValueError):
62+
metrics.upload_metrics(test_metrics, "test_userid", "test_api_key")
63+
64+
def test_bad_response_code(self):
65+
"""Test that we gracefully handle HTTP response errors."""
66+
test_metrics = [metrics.GaugeMetric("gauge_test", 5, 1000)]
67+
return_value = requests.Response()
68+
return_value.status_code = 403
69+
# Just assert that we continue running here and do not raise anything.
70+
with unittest.mock.patch("requests.post", return_value=return_value) as _:
71+
metrics.upload_metrics(test_metrics, "test_userid", "test_api_key")
72+
73+
74+
if __name__ == "__main__":
75+
unittest.main()

.github/workflows/check-ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ jobs:
3131
- name: Install Python Dependencies
3232
run: |
3333
pip3 install -r .ci/all_requirements.txt
34+
pip3 install -r .ci/metrics/requirements.lock.txt
3435
pip3 install pytest==8.4.1
3536
- name: Run Tests
3637
working-directory: .ci

.github/workflows/premerge.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ jobs:
6262
# why we do not hardcode it.
6363
export SCCACHE_GCS_BUCKET=$CACHE_GCS_BUCKET
6464
export SCCACHE_GCS_RW_MODE=READ_WRITE
65+
66+
# Set the idle timeout to zero to ensure sccache runs for the
67+
# entire duration of the job. Otherwise it might stop if we run
68+
# several test suites in a row and discard statistics that we want
69+
# to save in the end.
70+
export SCCACHE_IDLE_TIMEOUT=0
6571
sccache --start-server
6672
6773
./.ci/monolithic-linux.sh "${projects_to_build}" "${project_check_targets}" "${runtimes_to_build}" "${runtimes_check_targets}" "${runtimes_check_targets_needs_reconfig}" "${enable_cir}"
@@ -110,7 +116,9 @@ jobs:
110116
shell: cmd
111117
run: |
112118
call C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat -arch=amd64 -host_arch=amd64
113-
bash -c "export SCCACHE_GCS_BUCKET=$CACHE_GCS_BUCKET; export SCCACHE_GCS_RW_MODE=READ_WRITE; sccache --start-server; .ci/monolithic-windows.sh \"${{ steps.vars.outputs.windows-projects }}\" \"${{ steps.vars.outputs.windows-check-targets }}\""
119+
# See the comments above in the Linux job for why we define each of
120+
# these environment variables.
121+
bash -c "export SCCACHE_GCS_BUCKET=$CACHE_GCS_BUCKET; export SCCACHE_GCS_RW_MODE=READ_WRITE; export SCCACHE_IDLE_TIMEOUT=0; sccache --start-server; .ci/monolithic-windows.sh \"${{ steps.vars.outputs.windows-projects }}\" \"${{ steps.vars.outputs.windows-check-targets }}\""
114122
- name: Upload Artifacts
115123
if: '!cancelled()'
116124
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0

bolt/lib/Profile/DataAggregator.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -906,11 +906,10 @@ DataAggregator::getFallthroughsInTrace(BinaryFunction &BF, const Trace &Trace,
906906
if (BF.isPseudo())
907907
return Branches;
908908

909-
if (!BF.isSimple())
909+
// Can only record traces in CFG state
910+
if (!BF.hasCFG())
910911
return std::nullopt;
911912

912-
assert(BF.hasCFG() && "can only record traces in CFG state");
913-
914913
const BinaryBasicBlock *FromBB = BF.getBasicBlockContainingOffset(From);
915914
const BinaryBasicBlock *ToBB = BF.getBasicBlockContainingOffset(To);
916915

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 12 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -714,21 +714,6 @@ Error RewriteInstance::run() {
714714

715715
preprocessProfileData();
716716

717-
// Skip disassembling if we have a translation table and we are running an
718-
// aggregation job.
719-
if (opts::AggregateOnly && BAT->enabledFor(InputFile)) {
720-
// YAML profile in BAT mode requires CFG for .bolt.org.text functions
721-
if (!opts::SaveProfile.empty() ||
722-
opts::ProfileFormat == opts::ProfileFormatKind::PF_YAML) {
723-
selectFunctionsToProcess();
724-
disassembleFunctions();
725-
processMetadataPreCFG();
726-
buildFunctionsCFG();
727-
}
728-
processProfileData();
729-
return Error::success();
730-
}
731-
732717
selectFunctionsToProcess();
733718

734719
readDebugInfo();
@@ -4260,31 +4245,25 @@ void RewriteInstance::patchELFPHDRTable() {
42604245
const ELFFile<ELF64LE> &Obj = ELF64LEFile->getELFFile();
42614246
raw_fd_ostream &OS = Out->os();
42624247

4263-
// Write/re-write program headers.
42644248
Phnum = Obj.getHeader().e_phnum;
4265-
if (PHDRTableOffset) {
4266-
// Writing new pheader table and adding one new entry for R+X segment.
4267-
Phnum += 1;
4268-
if (NewWritableSegmentSize) {
4269-
// Adding one more entry for R+W segment.
4270-
Phnum += 1;
4271-
}
4272-
} else {
4249+
4250+
if (BC->NewSegments.empty()) {
4251+
BC->outs() << "BOLT-INFO: not adding new segments\n";
4252+
return;
4253+
}
4254+
4255+
if (opts::UseGnuStack) {
42734256
assert(!PHDRTableAddress && "unexpected address for program header table");
4274-
PHDRTableOffset = Obj.getHeader().e_phoff;
4275-
if (NewWritableSegmentSize) {
4257+
if (BC->NewSegments.size() > 1) {
42764258
BC->errs() << "BOLT-ERROR: unable to add writable segment\n";
42774259
exit(1);
42784260
}
4261+
} else {
4262+
Phnum += BC->NewSegments.size();
42794263
}
42804264

4281-
if (opts::Instrument)
4282-
Phnum += 2;
4283-
4284-
if (BC->NewSegments.empty()) {
4285-
BC->outs() << "BOLT-INFO: not adding new segments\n";
4286-
return;
4287-
}
4265+
if (!PHDRTableOffset)
4266+
PHDRTableOffset = Obj.getHeader().e_phoff;
42884267

42894268
const uint64_t SavedPos = OS.tell();
42904269
OS.seek(PHDRTableOffset);

bolt/test/X86/unclaimed-jt-entries.s

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@
1818

1919
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
2020
# RUN: %clang %cflags -no-pie %t.o -o %t.exe -Wl,-q
21+
22+
## Check that non-simple function profile is emitted in perf2bolt mode
23+
# RUN: link_fdata %s %t.exe %t.pa PREAGG
24+
# RUN: llvm-strip -N L5 -N L5_ret %t.exe
25+
# RUN: perf2bolt %t.exe -p %t.pa --pa -o %t.fdata -strict=0 -print-profile \
26+
# RUN: -print-only=main | FileCheck %s --check-prefix=CHECK-P2B
27+
# CHECK-P2B: PERF2BOLT: traces mismatching disassembled function contents: 0
28+
# CHECK-P2B: Binary Function "main"
29+
# CHECK-P2B: IsSimple : 0
30+
# RUN: FileCheck %s --input-file %t.fdata --check-prefix=CHECK-FDATA
31+
# CHECK-FDATA: 1 main 0 1 main 7 0 1
32+
2133
# RUN: llvm-bolt %t.exe -v=1 -o %t.out 2>&1 | FileCheck %s
2234

2335
# CHECK: BOLT-WARNING: unclaimed data to code reference (possibly an unrecognized jump table entry) to .Ltmp[[#]] in main
@@ -33,8 +45,10 @@
3345
.size main, .Lend-main
3446
main:
3547
jmp *L4-24(,%rdi,8)
36-
.L5:
48+
# PREAGG: T #main# #L5# #L5_ret# 1
49+
L5:
3750
movl $4, %eax
51+
L5_ret:
3852
ret
3953
.L9:
4054
movl $2, %eax
@@ -58,7 +72,7 @@ L4:
5872
.quad .L3
5973
.quad .L6
6074
.quad .L3
61-
.quad .L5
75+
.quad L5
6276
.quad .L3
6377
.quad .L3
6478
.quad .L3

clang-tools-extra/clang-doc/JSONGenerator.cpp

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,27 @@ serializeLocation(const Location &Loc,
8383
return LocationObj;
8484
}
8585

86-
static json::Value serializeComment(const CommentInfo &I) {
86+
static void insertComment(Object &Description, json::Value &Comment,
87+
StringRef Key) {
88+
auto DescriptionIt = Description.find(Key);
89+
90+
if (DescriptionIt == Description.end()) {
91+
auto CommentsArray = json::Array();
92+
CommentsArray.push_back(Comment);
93+
Description[Key] = std::move(CommentsArray);
94+
Description["Has" + Key.str()] = true;
95+
} else {
96+
DescriptionIt->getSecond().getAsArray()->push_back(Comment);
97+
}
98+
}
99+
100+
static json::Value extractTextComments(Object *ParagraphComment) {
101+
if (!ParagraphComment)
102+
return json::Object();
103+
return *ParagraphComment->get("Children");
104+
}
105+
106+
static Object serializeComment(const CommentInfo &I, Object &Description) {
87107
// taken from PR #142273
88108
Object Obj = Object();
89109

@@ -94,7 +114,7 @@ static json::Value serializeComment(const CommentInfo &I) {
94114
auto &CARef = *ChildArr.getAsArray();
95115
CARef.reserve(I.Children.size());
96116
for (const auto &C : I.Children)
97-
CARef.emplace_back(serializeComment(*C));
117+
CARef.emplace_back(serializeComment(*C, Description));
98118

99119
switch (I.Kind) {
100120
case CommentKind::CK_TextComment: {
@@ -103,9 +123,9 @@ static json::Value serializeComment(const CommentInfo &I) {
103123
}
104124

105125
case CommentKind::CK_BlockCommandComment: {
106-
Child.insert({"Command", I.Name});
107-
Child.insert({"Children", ChildArr});
108-
Obj.insert({commentKindToString(I.Kind), ChildVal});
126+
auto TextCommentsArray = extractTextComments(CARef.front().getAsObject());
127+
if (I.Name == "brief")
128+
insertComment(Description, TextCommentsArray, "BriefComments");
109129
return Obj;
110130
}
111131

@@ -137,7 +157,10 @@ static json::Value serializeComment(const CommentInfo &I) {
137157
if (!I.CloseName.empty())
138158
Child.insert({"CloseName", I.CloseName});
139159
Child.insert({"Children", ChildArr});
140-
Obj.insert({commentKindToString(I.Kind), ChildVal});
160+
if (I.CloseName == "endcode")
161+
insertComment(Description, ChildVal, "CodeComments");
162+
else if (I.CloseName == "endverbatim")
163+
insertComment(Description, ChildVal, "VerbatimComments");
141164
return Obj;
142165
}
143166

@@ -179,8 +202,8 @@ static json::Value serializeComment(const CommentInfo &I) {
179202
case CommentKind::CK_FullComment:
180203
case CommentKind::CK_ParagraphComment: {
181204
Child.insert({"Children", ChildArr});
182-
Obj.insert({commentKindToString(I.Kind), ChildVal});
183-
return Obj;
205+
Child["ParagraphComment"] = true;
206+
return Child;
184207
}
185208

186209
case CommentKind::CK_Unknown: {
@@ -210,12 +233,20 @@ serializeCommonAttributes(const Info &I, json::Object &Obj,
210233
}
211234

212235
if (!I.Description.empty()) {
213-
json::Value DescArray = json::Array();
214-
auto &DescArrayRef = *DescArray.getAsArray();
215-
DescArrayRef.reserve(I.Description.size());
216-
for (const auto &Comment : I.Description)
217-
DescArrayRef.push_back(serializeComment(Comment));
218-
Obj["Description"] = DescArray;
236+
Object Description = Object();
237+
// Skip straight to the FullComment's children
238+
auto &Comments = I.Description.at(0).Children;
239+
for (const auto &CommentInfo : Comments) {
240+
json::Value Comment = serializeComment(*CommentInfo, Description);
241+
// if a ParagraphComment is returned, then it is a top-level comment that
242+
// needs to be inserted manually.
243+
if (auto *ParagraphComment = Comment.getAsObject();
244+
ParagraphComment->get("ParagraphComment")) {
245+
auto TextCommentsArray = extractTextComments(ParagraphComment);
246+
insertComment(Description, TextCommentsArray, "ParagraphComments");
247+
}
248+
}
249+
Obj["Description"] = std::move(Description);
219250
}
220251

221252
// Namespaces aren't SymbolInfos, so they dont have a DefLoc

clang-tools-extra/clang-doc/assets/class-template.mustache

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,11 @@
128128
<section class="hero section-container">
129129
<div class="hero__title">
130130
<h1 class="hero__title-large">{{TagType}} {{Name}}</h1>
131-
{{#RecordComments}}
131+
{{#Description}}
132132
<div class="hero__subtitle">
133133
{{>Comments}}
134134
</div>
135-
{{/RecordComments}}
135+
{{/Description}}
136136
</div>
137137
</section>
138138
{{#HasPublicMembers}}

clang-tools-extra/clang-doc/assets/comment-template.mustache

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,20 @@
55
66
This file defines templates for generating comments
77
}}
8-
{{#FullComment}}
9-
{{#Children}}
10-
{{>Comments}}
11-
{{/Children}}
12-
{{/FullComment}}
8+
{{#BriefComments}}
9+
<div>
10+
{{#.}}
11+
<p>{{TextComment}}</p>
12+
{{/.}}
13+
</div>
14+
{{/BriefComments}}
15+
{{#ParagraphComments}}
16+
<div>
17+
{{#.}}
18+
<p>{{TextComment}}</p>
19+
{{/.}}
20+
</div>
21+
{{/ParagraphComments}}
1322
{{#ParagraphComment}}
1423
{{#Children}}
1524
{{>Comments}}

clang-tools-extra/clang-tidy/tool/clang-tidy-diff.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def main():
177177
parser.add_argument(
178178
"-j",
179179
type=int,
180-
default=1,
180+
default=0,
181181
help="number of tidy instances to be run in parallel.",
182182
)
183183
parser.add_argument(
@@ -318,6 +318,7 @@ def main():
318318
if max_task_count == 0:
319319
max_task_count = multiprocessing.cpu_count()
320320
max_task_count = min(len(lines_by_file), max_task_count)
321+
print(f"Running clang-tidy in {max_task_count} threads...")
321322

322323
combine_fixes = False
323324
export_fixes_dir = None

0 commit comments

Comments
 (0)