Skip to content

Commit fafb75a

Browse files
committed
Merge from 'main' to 'sycl-web' (100 commits)
CONFLICT (content): Merge conflict in clang/include/clang/Basic/CodeGenOptions.h CONFLICT (content): Merge conflict in clang/lib/CodeGen/BackendUtil.cpp
2 parents 0b589b1 + a207e63 commit fafb75a

File tree

729 files changed

+9317
-2339
lines changed

Some content is hidden

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

729 files changed

+9317
-2339
lines changed

.github/workflows/pr-code-format.yml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,33 @@ jobs:
1111
- name: Fetch LLVM sources
1212
uses: actions/checkout@v4
1313
with:
14-
fetch-depth: 2 # Fetches only the last 2 commits
14+
ref: ${{ github.event.pull_request.head.sha }}
15+
16+
- name: Checkout through merge base
17+
uses: rmacklin/fetch-through-merge-base@v0
18+
with:
19+
base_ref: ${{ github.event.pull_request.base.ref }}
20+
head_ref: ${{ github.event.pull_request.head.sha }}
21+
deepen_length: 500
1522

1623
- name: Get changed files
1724
id: changed-files
1825
uses: tj-actions/changed-files@v39
1926
with:
2027
separator: ","
21-
fetch_depth: 2000 # Fetches only the last 2000 commits
28+
skip_initial_fetch: true
29+
30+
# We need to make sure that we aren't executing/using any code from the
31+
# PR for security reasons as we're using pull_request_target. Checkout
32+
# the target branch with the necessary files.
33+
- name: Fetch code formatting utils
34+
uses: actions/checkout@v4
35+
with:
36+
sparse-checkout: |
37+
llvm/utils/git/requirements_formatting.txt
38+
llvm/utils/git/code-format-helper.py
39+
sparse-checkout-cone-mode: false
40+
path: code-format-tools
2241

2342
- name: "Listed files"
2443
run: |
@@ -35,10 +54,10 @@ jobs:
3554
with:
3655
python-version: '3.11'
3756
cache: 'pip'
38-
cache-dependency-path: 'llvm/utils/git/requirements_formatting.txt'
57+
cache-dependency-path: 'code-format-tools/llvm/utils/git/requirements_formatting.txt'
3958

4059
- name: Install python dependencies
41-
run: pip install -r llvm/utils/git/requirements_formatting.txt
60+
run: pip install -r code-format-tools/llvm/utils/git/requirements_formatting.txt
4261

4362
- name: Run code formatter
4463
env:
@@ -47,7 +66,7 @@ jobs:
4766
END_REV: ${{ github.event.pull_request.head.sha }}
4867
CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }}
4968
run: |
50-
python llvm/utils/git/code-format-helper.py \
69+
python ./code-format-tools/llvm/utils/git/code-format-helper.py \
5170
--token ${{ secrets.GITHUB_TOKEN }} \
5271
--issue-number $GITHUB_PR_NUMBER \
5372
--start-rev $START_REV \

bolt/lib/Passes/BinaryPasses.cpp

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -582,65 +582,47 @@ bool CheckLargeFunctions::shouldOptimize(const BinaryFunction &BF) const {
582582
}
583583

584584
void LowerAnnotations::runOnFunctions(BinaryContext &BC) {
585-
std::vector<std::pair<MCInst *, uint32_t>> PreservedOffsetAnnotations;
586-
std::vector<std::pair<MCInst *, MCSymbol *>> PreservedLabelAnnotations;
587-
588-
for (auto &It : BC.getBinaryFunctions()) {
589-
BinaryFunction &BF = It.second;
590-
591-
for (FunctionFragment &FF : BF.getLayout().fragments()) {
585+
for (BinaryFunction *BF : BC.getAllBinaryFunctions()) {
586+
for (FunctionFragment &FF : BF->getLayout().fragments()) {
587+
// Reset at the start of the new fragment.
592588
int64_t CurrentGnuArgsSize = 0;
593589

594590
for (BinaryBasicBlock *const BB : FF) {
595-
// First convert GnuArgsSize annotations into CFIs. This may change
596-
// instr pointers, so do it before recording ptrs for preserved
597-
// annotations
598-
if (BF.usesGnuArgsSize()) {
599-
for (auto II = BB->begin(); II != BB->end(); ++II) {
600-
if (!BC.MIB->isInvoke(*II))
601-
continue;
591+
for (auto II = BB->begin(); II != BB->end(); ++II) {
592+
593+
// Convert GnuArgsSize annotations into CFIs.
594+
if (BF->usesGnuArgsSize() && BC.MIB->isInvoke(*II)) {
602595
const int64_t NewGnuArgsSize = BC.MIB->getGnuArgsSize(*II);
603596
assert(NewGnuArgsSize >= 0 &&
604-
"expected non-negative GNU_args_size");
597+
"Expected non-negative GNU_args_size.");
605598
if (NewGnuArgsSize != CurrentGnuArgsSize) {
606-
auto InsertII = BF.addCFIInstruction(
599+
auto InsertII = BF->addCFIInstruction(
607600
BB, II,
608601
MCCFIInstruction::createGnuArgsSize(nullptr, NewGnuArgsSize));
609602
CurrentGnuArgsSize = NewGnuArgsSize;
610603
II = std::next(InsertII);
611604
}
612605
}
613-
}
614606

615-
// Now record preserved annotations separately and then strip
616-
// annotations.
617-
for (auto II = BB->begin(); II != BB->end(); ++II) {
618-
if (BF.requiresAddressTranslation() && BC.MIB->getOffset(*II))
619-
PreservedOffsetAnnotations.emplace_back(&(*II),
620-
*BC.MIB->getOffset(*II));
621-
if (MCSymbol *Label = BC.MIB->getLabel(*II))
622-
PreservedLabelAnnotations.emplace_back(&*II, Label);
607+
// Preserve selected annotations and strip the rest.
608+
std::optional<uint32_t> Offset = BF->requiresAddressTranslation()
609+
? BC.MIB->getOffset(*II)
610+
: std::nullopt;
611+
MCSymbol *Label = BC.MIB->getLabel(*II);
612+
623613
BC.MIB->stripAnnotations(*II);
614+
615+
if (Offset)
616+
BC.MIB->setOffset(*II, *Offset);
617+
if (Label)
618+
BC.MIB->setLabel(*II, Label);
624619
}
625620
}
626621
}
627622
}
628-
for (BinaryFunction *BF : BC.getInjectedBinaryFunctions())
629-
for (BinaryBasicBlock &BB : *BF)
630-
for (MCInst &Instruction : BB) {
631-
if (MCSymbol *Label = BC.MIB->getLabel(Instruction))
632-
PreservedLabelAnnotations.emplace_back(&Instruction, Label);
633-
BC.MIB->stripAnnotations(Instruction);
634-
}
635623

636624
// Release all memory taken by annotations
637625
BC.MIB->freeAnnotations();
638-
639-
// Reinsert preserved annotations we need during code emission.
640-
for (const std::pair<MCInst *, uint32_t> &Item : PreservedOffsetAnnotations)
641-
BC.MIB->setOffset(*Item.first, Item.second);
642-
for (auto [Instr, Label] : PreservedLabelAnnotations)
643-
BC.MIB->setLabel(*Instr, Label);
644626
}
645627

646628
// Check for dirty state in MCSymbol objects that might be a consequence

bolt/utils/nfc-stat-parser.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import csv
4+
import re
5+
import sys
6+
import os
7+
from statistics import geometric_mean
8+
9+
TIMING_LOG_RE = re.compile(r"(.*)/(.*).tmp(.*)")
10+
11+
12+
def main():
13+
parser = argparse.ArgumentParser(
14+
description="BOLT NFC stat parser",
15+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
16+
)
17+
parser.add_argument(
18+
"input", nargs="+", help="timing.log files produced by llvm-bolt-wrapper"
19+
)
20+
parser.add_argument(
21+
"--check_longer_than",
22+
default=0.5,
23+
type=float,
24+
help="Only warn on tests longer than X seconds for at least one side",
25+
)
26+
parser.add_argument(
27+
"--threshold_single",
28+
default=10,
29+
type=float,
30+
help="Threshold for a single test result swing, abs percent",
31+
),
32+
parser.add_argument(
33+
"--threshold_agg",
34+
default=5,
35+
type=float,
36+
help="Threshold for geomean test results swing, abs percent",
37+
),
38+
parser.add_argument("--verbose", "-v", action="store_true")
39+
args = parser.parse_args()
40+
41+
def fmt_delta(value, exc_threshold, above_bound=True):
42+
formatted_value = format(value, "+.2%")
43+
if not above_bound:
44+
formatted_value += "?"
45+
elif exc_threshold and sys.stdout.isatty(): # terminal supports colors
46+
return f"\033[1m{formatted_value}\033[0m"
47+
return formatted_value
48+
49+
# Ratios for geomean computation
50+
time_ratios = []
51+
mem_ratios = []
52+
# Whether any test exceeds the single test threshold (mem or time)
53+
threshold_single = False
54+
# Whether geomean exceeds aggregate test threshold (mem or time)
55+
threshold_agg = False
56+
57+
if args.verbose:
58+
print(f"# Individual test threshold: +-{args.threshold_single}%")
59+
print(f"# Aggregate (geomean) test threshold: +-{args.threshold_agg}%")
60+
print(
61+
f"# Checking time swings for tests with runtime >"
62+
f"{args.check_longer_than}s - otherwise marked as ?"
63+
)
64+
print("Test/binary BOLT_wall_time BOLT_max_rss")
65+
66+
for input_file in args.input:
67+
input_dir = os.path.dirname(input_file)
68+
with open(input_file) as timing_file:
69+
timing_reader = csv.reader(timing_file, delimiter=";")
70+
for row in timing_reader:
71+
test_name = row[0]
72+
m = TIMING_LOG_RE.match(row[0])
73+
if m:
74+
test_name = f"{input_dir}/{m.groups()[1]}/{m.groups()[2]}"
75+
else:
76+
# Prepend input dir to unparsed test name
77+
test_name = input_dir + "#" + test_name
78+
time_a, time_b = float(row[1]), float(row[3])
79+
mem_a, mem_b = int(row[2]), int(row[4])
80+
# Check if time is above bound for at least one side
81+
time_above_bound = any(
82+
[x > args.check_longer_than for x in [time_a, time_b]]
83+
)
84+
# Compute B/A ratios (for % delta and geomean)
85+
time_ratio = time_b / time_a if time_a else float('nan')
86+
mem_ratio = mem_b / mem_a if mem_a else float('nan')
87+
# Keep ratios for geomean
88+
if time_above_bound and time_ratio > 0: # must be >0 for gmean
89+
time_ratios += [time_ratio]
90+
mem_ratios += [mem_ratio]
91+
# Deltas: (B/A)-1 = (B-A)/A
92+
time_delta = time_ratio - 1
93+
mem_delta = mem_ratio - 1
94+
# Check individual test results vs single test threshold
95+
time_exc = (
96+
100.0 * abs(time_delta) > args.threshold_single and time_above_bound
97+
)
98+
mem_exc = 100.0 * abs(mem_delta) > args.threshold_single
99+
if time_exc or mem_exc:
100+
threshold_single = True
101+
# Print deltas with formatting in verbose mode
102+
if args.verbose or time_exc or mem_exc:
103+
print(
104+
test_name,
105+
fmt_delta(time_delta, time_exc, time_above_bound),
106+
fmt_delta(mem_delta, mem_exc),
107+
)
108+
109+
time_gmean_delta = geometric_mean(time_ratios) - 1
110+
mem_gmean_delta = geometric_mean(mem_ratios) - 1
111+
time_agg_threshold = 100.0 * abs(time_gmean_delta) > args.threshold_agg
112+
mem_agg_threshold = 100.0 * abs(mem_gmean_delta) > args.threshold_agg
113+
if time_agg_threshold or mem_agg_threshold:
114+
threshold_agg = True
115+
if time_agg_threshold or mem_agg_threshold or args.verbose:
116+
print(
117+
"Geomean",
118+
fmt_delta(time_gmean_delta, time_agg_threshold),
119+
fmt_delta(mem_gmean_delta, mem_agg_threshold),
120+
)
121+
exit(threshold_single or threshold_agg)
122+
123+
124+
if __name__ == "__main__":
125+
main()

0 commit comments

Comments
 (0)