Auto merge of #96978 - lqd:win_pgo2, r=Mark-Simulacrum · rust-lang/rust@8a33254 (original) (raw)
`@@ -3,44 +3,82 @@
`
3
3
``
4
4
`set -euxo pipefail
`
5
5
``
``
6
`` +
ci_dir=cd <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>d</mi><mi>i</mi><mi>r</mi><mi>n</mi><mi>a</mi><mi>m</mi><mi>e</mi></mrow><annotation encoding="application/x-tex">(dirname </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">d</span><span class="mord mathnormal">i</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">nam</span><span class="mord mathnormal">e</span></span></span></span>0) && pwd
``
``
7
`+
source "$ci_dir/shared.sh"
`
``
8
+
``
9
`+
The root checkout, where the source is located
`
``
10
`+
CHECKOUT=/checkout
`
``
11
+
``
12
`+
DOWNLOADED_LLVM=/rustroot
`
``
13
+
``
14
`+
The main directory where the build occurs, which can be different between linux and windows
`
``
15
`+
BUILD_ROOT=$CHECKOUT/obj
`
``
16
+
``
17
`+
if isWindows; then
`
``
18
`+
CHECKOUT=$(pwd)
`
``
19
`+
DOWNLOADED_LLVM=$CHECKOUT/citools/clang-rust
`
``
20
`+
BUILD_ROOT=$CHECKOUT
`
``
21
`+
fi
`
``
22
+
``
23
`+
The various build artifacts used in other commands: to launch rustc builds, build the perf
`
``
24
`+
collector, and run benchmarks to gather profiling data
`
``
25
`+
BUILD_ARTIFACTS=$BUILD_ROOT/build/$PGO_HOST
`
``
26
`+
RUSTC_STAGE_0=$BUILD_ARTIFACTS/stage0/bin/rustc
`
``
27
`+
CARGO_STAGE_0=$BUILD_ARTIFACTS/stage0/bin/cargo
`
``
28
`+
RUSTC_STAGE_2=$BUILD_ARTIFACTS/stage2/bin/rustc
`
``
29
+
``
30
`+
Windows needs these to have the .exe extension
`
``
31
`+
if isWindows; then
`
``
32
`+
RUSTC_STAGE_0="${RUSTC_STAGE_0}.exe"
`
``
33
`+
CARGO_STAGE_0="${CARGO_STAGE_0}.exe"
`
``
34
`+
RUSTC_STAGE_2="${RUSTC_STAGE_2}.exe"
`
``
35
`+
fi
`
``
36
+
``
37
`+
Make sure we have a temporary PGO work folder
`
``
38
`+
PGO_TMP=/tmp/tmp-pgo
`
``
39
`+
mkdir -p $PGO_TMP
`
``
40
`+
rm -rf $PGO_TMP/*
`
``
41
+
``
42
`+
RUSTC_PERF=$PGO_TMP/rustc-perf
`
``
43
+
6
44
`# Compile several crates to gather execution PGO profiles.
`
7
45
`# Arg0 => profiles (Debug, Opt)
`
8
46
`# Arg1 => scenarios (Full, IncrFull, All)
`
9
47
`# Arg2 => crates (syn, cargo, ...)
`
10
48
`gather_profiles () {
`
11
``
`-
cd /checkout/obj
`
``
49
`+
cd $BUILD_ROOT
`
12
50
``
13
51
`# Compile libcore, both in opt-level=0 and opt-level=3
`
14
``
`-
RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc \
`
15
``
`-
--edition=2021 --crate-type=lib ../library/core/src/lib.rs
`
16
``
`-
RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc \
`
17
``
`-
--edition=2021 --crate-type=lib -Copt-level=3 ../library/core/src/lib.rs
`
``
52
`+
RUSTC_BOOTSTRAP=1 $RUSTC_STAGE_2 \
`
``
53
`+
--edition=2021 --crate-type=lib $CHECKOUT/library/core/src/lib.rs \
`
``
54
`+
--out-dir $PGO_TMP
`
``
55
`+
RUSTC_BOOTSTRAP=1 $RUSTC_STAGE_2 \
`
``
56
`+
--edition=2021 --crate-type=lib -Copt-level=3 $CHECKOUT/library/core/src/lib.rs \
`
``
57
`+
--out-dir $PGO_TMP
`
18
58
``
19
``
`-
cd rustc-perf
`
``
59
`+
cd $RUSTC_PERF
`
20
60
``
21
61
`# Run rustc-perf benchmarks
`
22
62
`# Benchmark using profile_local with eprintln, which essentially just means
`
23
63
`# don't actually benchmark -- just make sure we run rustc a bunch of times.
`
24
64
` RUST_LOG=collector=debug \
`
25
``
`-
RUSTC=/checkout/obj/build/$PGO_HOST/stage0/bin/rustc \
`
``
65
`+
RUSTC=$RUSTC_STAGE_0 \
`
26
66
` RUSTC_BOOTSTRAP=1 \
`
27
``
`-
/checkout/obj/build/$PGO_HOST/stage0/bin/cargo run -p collector --bin collector -- \
`
28
``
`-
profile_local \
`
29
``
`-
eprintln \
`
30
``
`-
/checkout/obj/build/$PGO_HOST/stage2/bin/rustc \
`
31
``
`-
--id Test \
`
32
``
`-
--profiles $1 \
`
33
``
`-
--cargo /checkout/obj/build/$PGO_HOST/stage0/bin/cargo \
`
34
``
`-
--scenarios $2 \
`
35
``
`-
--include $3
`
36
``
-
37
``
`-
cd /checkout/obj
`
``
67
`+
$CARGO_STAGE_0 run -p collector --bin collector -- \
`
``
68
`+
profile_local \
`
``
69
`+
eprintln \
`
``
70
`+
$RUSTC_STAGE_2 \
`
``
71
`+
--id Test \
`
``
72
`+
--profiles $1 \
`
``
73
`+
--cargo $CARGO_STAGE_0 \
`
``
74
`+
--scenarios $2 \
`
``
75
`+
--include $3
`
``
76
+
``
77
`+
cd $BUILD_ROOT
`
38
78
`}
`
39
79
``
40
``
`-
rm -rf /tmp/rustc-pgo
`
41
``
-
42
80
`# This path has to be absolute
`
43
``
`-
LLVM_PROFILE_DIRECTORY_ROOT=/tmp/llvm-pgo
`
``
81
`+
LLVM_PROFILE_DIRECTORY_ROOT=$PGO_TMP/llvm-pgo
`
44
82
``
45
83
`# We collect LLVM profiling information and rustc profiling information in
`
46
84
`# separate phases. This increases build time -- though not by a huge amount --
`
`@@ -49,69 +87,93 @@ LLVM_PROFILE_DIRECTORY_ROOT=/tmp/llvm-pgo
`
49
87
`# LLVM IR PGO does not respect LLVM_PROFILE_FILE, so we have to set the profiling file
`
50
88
`# path through our custom environment variable. We include the PID in the directory path
`
51
89
`# to avoid updates to profile files being lost because of race conditions.
`
52
``
`-
LLVM_PROFILE_DIR=${LLVM_PROFILE_DIRECTORY_ROOT}/prof-%p python3 ../x.py build \
`
``
90
`+
LLVM_PROFILE_DIR=${LLVM_PROFILE_DIRECTORY_ROOT}/prof-%p python3 $CHECKOUT/x.py build \
`
53
91
` --target=$PGO_HOST \
`
54
92
` --host=$PGO_HOST \
`
55
93
` --stage 2 library/std \
`
56
94
` --llvm-profile-generate
`
57
95
``
58
``
`-
Compile rustc perf
`
59
``
`-
cp -r /tmp/rustc-perf ./
`
60
``
`-
chown -R $(whoami): ./rustc-perf
`
61
``
`-
cd rustc-perf
`
62
``
-
63
``
`-
Build the collector ahead of time, which is needed to make sure the rustc-fake
`
64
``
`-
binary used by the collector is present.
`
65
``
`-
RUSTC=/checkout/obj/build/$PGO_HOST/stage0/bin/rustc \
`
``
96
`+
Compile rustc-perf:
`
``
97
`+
- get the expected commit source code: on linux, the Dockerfile downloads a source archive before
`
``
98
`+
running this script. On Windows, we do that here.
`
``
99
`+
if isLinux; then
`
``
100
`+
cp -r /tmp/rustc-perf $RUSTC_PERF
`
``
101
`+
chown -R (whoami):(whoami): (whoami):RUSTC_PERF
`
``
102
`+
else
`
``
103
`+
rustc-perf version from 2022-05-18
`
``
104
`+
PERF_COMMIT=f66cc8f3e04392b0e2fd811f21fd1ece6ebaded3
`
``
105
`+
retry curl -LS -o $PGO_TMP/perf.zip \
`
``
106
`+
https://github.com/rust-lang/rustc-perf/archive/$PERF_COMMIT.zip && \
`
``
107
`+
cd $PGO_TMP && unzip -q perf.zip && \
`
``
108
`+
mv rustc-perf-$PERF_COMMIT $RUSTC_PERF && \
`
``
109
`+
rm perf.zip
`
``
110
`+
fi
`
``
111
+
``
112
`+
- build rustc-perf's collector ahead of time, which is needed to make sure the rustc-fake binary
`
``
113
`+
used by the collector is present.
`
``
114
`+
cd $RUSTC_PERF
`
``
115
+
``
116
`+
RUSTC=$RUSTC_STAGE_0 \
`
66
117
`RUSTC_BOOTSTRAP=1 \
`
67
``
`-
/checkout/obj/build/$PGO_HOST/stage0/bin/cargo build -p collector
`
``
118
`+
$CARGO_STAGE_0 build -p collector
`
68
119
``
69
120
`` # Here we're profiling LLVM, so we only care about Debug
and Opt
, because we want to stress
``
70
121
`# codegen. We also profile some of the most prolific crates.
`
71
122
`gather_profiles "Debug,Opt" "Full" \
`
72
``
`-
"syn-1.0.89,cargo-0.60.0,serde-1.0.136,ripgrep-13.0.0,regex-1.5.5,clap-3.1.6,hyper-0.14.18"
`
``
123
`+
"syn-1.0.89,cargo-0.60.0,serde-1.0.136,ripgrep-13.0.0,regex-1.5.5,clap-3.1.6,hyper-0.14.18"
`
73
124
``
74
``
`-
LLVM_PROFILE_MERGED_FILE=/tmp/llvm-pgo.profdata
`
``
125
`+
LLVM_PROFILE_MERGED_FILE=$PGO_TMP/llvm-pgo.profdata
`
75
126
``
76
127
`# Merge the profile data we gathered for LLVM
`
77
128
`# Note that this uses the profdata from the clang we used to build LLVM,
`
78
129
`# which likely has a different version than our in-tree clang.
`
79
``
`-
/rustroot/bin/llvm-profdata merge -o LLVMPROFILEMERGEDFILE{LLVM_PROFILE_MERGED_FILE} LLVMPROFILEMERGEDFILE{LLVM_PROFILE_DIRECTORY_ROOT}
`
``
130
`+ DOWNLOADEDLLVM/bin/llvm−profdatamerge−oDOWNLOADED_LLVM/bin/llvm-profdata merge -o DOWNLOADEDLLVM/bin/llvm−profdatamerge−o{LLVM_PROFILE_MERGED_FILE} ${LLVM_PROFILE_DIRECTORY_ROOT}
`
80
131
``
81
132
`echo "LLVM PGO statistics"
`
82
133
`du -sh ${LLVM_PROFILE_MERGED_FILE}
`
83
134
`du -sh ${LLVM_PROFILE_DIRECTORY_ROOT}
`
84
135
`echo "Profile file count"
`
85
136
`find ${LLVM_PROFILE_DIRECTORY_ROOT} -type f | wc -l
`
86
137
``
``
138
`+
We don't need the individual .profraw files now that they have been merged into a final .profdata
`
``
139
`+
rm -r $LLVM_PROFILE_DIRECTORY_ROOT
`
``
140
+
87
141
`# Rustbuild currently doesn't support rebuilding LLVM when PGO options
`
88
142
`# change (or any other llvm-related options); so just clear out the relevant
`
89
143
`# directories ourselves.
`
90
``
`-
rm -r ./build/$PGO_HOST/llvm ./build/$PGO_HOST/lld
`
``
144
`+
rm -r BUILDARTIFACTS/llvmBUILD_ARTIFACTS/llvm BUILDARTIFACTS/llvmBUILD_ARTIFACTS/lld
`
91
145
``
92
146
`# Okay, LLVM profiling is done, switch to rustc PGO.
`
93
147
``
94
148
`# The path has to be absolute
`
95
``
`-
RUSTC_PROFILE_DIRECTORY_ROOT=/tmp/rustc-pgo
`
``
149
`+
RUSTC_PROFILE_DIRECTORY_ROOT=$PGO_TMP/rustc-pgo
`
96
150
``
97
``
`-
python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
`
``
151
`+
python3 CHECKOUT/x.pybuild−−target=CHECKOUT/x.py build --target=CHECKOUT/x.pybuild−−target=PGO_HOST --host=$PGO_HOST \
`
98
152
` --stage 2 library/std \
`
99
153
` --rust-profile-generate=${RUSTC_PROFILE_DIRECTORY_ROOT}
`
100
154
``
101
155
`` # Here we're profiling the rustc
frontend, so we also include Check
.
``
102
156
`# The benchmark set includes various stress tests that put the frontend under pressure.
`
103
``
`-
The profile data is written into a single filepath that is being repeatedly merged when each
`
104
``
`-
rustc invocation ends. Empirically, this can result in some profiling data being lost.
`
105
``
`-
That's why we override the profile path to include the PID. This will produce many more profiling
`
106
``
`-
files, but the resulting profile will produce a slightly faster rustc binary.
`
107
``
`-
LLVM_PROFILE_FILE=${RUSTC_PROFILE_DIRECTORY_ROOT}/default_%m_%p.profraw gather_profiles \
`
108
``
`-
"Check,Debug,Opt" "All" \
`
109
``
`-
"externs,ctfe-stress-5,cargo-0.60.0,token-stream-stress,match-stress,tuple-stress,diesel-1.4.8,bitmaps-3.1.0"
`
110
``
-
111
``
`-
RUSTC_PROFILE_MERGED_FILE=/tmp/rustc-pgo.profdata
`
``
157
`+
if isLinux; then
`
``
158
`+
The profile data is written into a single filepath that is being repeatedly merged when each
`
``
159
`+
rustc invocation ends. Empirically, this can result in some profiling data being lost. That's
`
``
160
`+
why we override the profile path to include the PID. This will produce many more profiling
`
``
161
`+
files, but the resulting profile will produce a slightly faster rustc binary.
`
``
162
`+
LLVM_PROFILE_FILE=${RUSTC_PROFILE_DIRECTORY_ROOT}/default_%m_%p.profraw gather_profiles \
`
``
163
`+
"Check,Debug,Opt" "All" \
`
``
164
`+
"externs,ctfe-stress-5,cargo-0.60.0,token-stream-stress,match-stress,tuple-stress,diesel-1.4.8,bitmaps-3.1.0"
`
``
165
`+
else
`
``
166
`+
On windows, we don't do that yet (because it generates a lot of data, hitting disk space
`
``
167
`+
limits on the builder), and use the default profraw merging behavior.
`
``
168
`+
gather_profiles \
`
``
169
`+
"Check,Debug,Opt" "All" \
`
``
170
`+
"externs,ctfe-stress-5,cargo-0.60.0,token-stream-stress,match-stress,tuple-stress,diesel-1.4.8,bitmaps-3.1.0"
`
``
171
`+
fi
`
``
172
+
``
173
`+
RUSTC_PROFILE_MERGED_FILE=$PGO_TMP/rustc-pgo.profdata
`
112
174
``
113
175
`# Merge the profile data we gathered
`
114
``
`-
./build/$PGO_HOST/llvm/bin/llvm-profdata \
`
``
176
`+
$BUILD_ARTIFACTS/llvm/bin/llvm-profdata \
`
115
177
` merge -o RUSTCPROFILEMERGEDFILE{RUSTC_PROFILE_MERGED_FILE} RUSTCPROFILEMERGEDFILE{RUSTC_PROFILE_DIRECTORY_ROOT}
`
116
178
``
117
179
`echo "Rustc PGO statistics"
`
`@@ -120,10 +182,13 @@ du -sh ${RUSTC_PROFILE_DIRECTORY_ROOT}
`
120
182
`echo "Profile file count"
`
121
183
`find ${RUSTC_PROFILE_DIRECTORY_ROOT} -type f | wc -l
`
122
184
``
``
185
`+
We don't need the individual .profraw files now that they have been merged into a final .profdata
`
``
186
`+
rm -r $RUSTC_PROFILE_DIRECTORY_ROOT
`
``
187
+
123
188
`# Rustbuild currently doesn't support rebuilding LLVM when PGO options
`
124
189
`# change (or any other llvm-related options); so just clear out the relevant
`
125
190
`# directories ourselves.
`
126
``
`-
rm -r ./build/$PGO_HOST/llvm ./build/$PGO_HOST/lld
`
``
191
`+
rm -r BUILDARTIFACTS/llvmBUILD_ARTIFACTS/llvm BUILDARTIFACTS/llvmBUILD_ARTIFACTS/lld
`
127
192
``
128
193
`# This produces the actual final set of artifacts, using both the LLVM and rustc
`
129
194
`# collected profiling data.
`